Compare commits

..

2 Commits

Author SHA1 Message Date
Steven Valdez 98aaf4eda3 Clang formatting.
Change-Id: I31e9fb52fb2f7e800ded73076f3da1b7fac716c5
2019-08-15 15:30:33 -04:00
Steven Valdez b641b6aaab In-Progress ESNI draft 04.
Change-Id: Idaebefde3f23f747d5660b46b0f90b2cbe4e6db9
2019-07-21 11:52:36 -04:00
1250 changed files with 120967 additions and 505592 deletions
-4
View File
@@ -4,8 +4,4 @@ AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
DerivePointerAlignment: false
PointerAlignment: Right
# TODO(davidben): The default for Google style is now Regroup, but the default
# IncludeCategories does not recognize <openssl/header.h>. We should
# reconfigure IncludeCategories to match. For now, keep it at Preserve.
IncludeBlocks: Preserve
-2
View File
@@ -1,6 +1,4 @@
build/
build32/
build64/
ssl/test/runner/runner
*.pyc
*.swp
+20 -54
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3)
cmake_minimum_required(VERSION 3.0)
# Defer enabling C and CXX languages.
project(BoringSSL NONE)
@@ -59,15 +59,9 @@ if(BORINGSSL_ALLOW_CXX_RUNTIME)
add_definitions(-DBORINGSSL_ALLOW_CXX_RUNTIME)
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if(NOT FIPS)
if(CMAKE_BUILD_TYPE_LOWER STREQUAL "relwithassert" OR
NOT CMAKE_BUILD_TYPE_LOWER MATCHES "rel")
add_definitions(-DBORINGSSL_DISPATCH_TEST)
# CMake automatically connects include_directories to the NASM
# command-line, but not add_definitions.
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DBORINGSSL_DISPATCH_TEST")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# Windows release builds don't set NDEBUG in NASM flags automatically.
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DNDEBUG")
endif()
# Add a RelWithAsserts build configuration. It is the same as Release, except it
@@ -110,14 +104,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CLANG 1)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
set(EMSCRIPTEN 1)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CLANG)
# Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration
# primarily on our normal Clang one.
set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -Wvla")
set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings")
if(MSVC)
# clang-cl sets different default warnings than clang. It also treats -Wall
# as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall.
@@ -127,14 +117,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CLANG)
# honor it. Suppress it here to compensate. See https://crbug.com/772117.
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-deprecated-declarations")
else()
if(EMSCRIPTEN)
# emscripten's emcc/clang does not accept the "-ggdb" flag.
set(C_CXX_FLAGS "${C_CXX_FLAGS} -g")
else()
set(C_CXX_FLAGS "${C_CXX_FLAGS} -ggdb")
endif()
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -fvisibility=hidden -fno-common")
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -ggdb -fvisibility=hidden -fno-common")
endif()
if(CLANG)
@@ -248,10 +231,11 @@ if(WIN32)
add_definitions(-DNOMINMAX)
# Allow use of fopen.
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# VS 2017 and higher supports STL-only warning suppressions.
# A bug in CMake < 3.13.0 may cause the space in this value to
# cause issues when building with NASM. In that case, update CMake.
add_definitions("-D_STL_EXTRA_DISABLED_WARNINGS=4774 4987")
# VS 2017 and higher supports STL-only warning suppressions. Manually add to
# C++ only to work around a CMake quoting bug when using NASM with the Visual
# Studio generator. This will be fixed in CMake 3.13.0. See
# https://gitlab.kitware.com/cmake/cmake/merge_requests/2179
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-D_STL_EXTRA_DISABLED_WARNINGS=4774\ 4987>)
endif()
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.99") OR
@@ -387,14 +371,6 @@ if(FIPS)
set(FIPS_DELOCATE "1")
endif()
endif()
if(FIPS_SHARED)
# The Android CMake files set -ffunction-sections and -fdata-sections,
# which is incompatible with FIPS_SHARED.
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -fno-function-sections -fno-data-sections")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fno-function-sections -fno-data-sections")
endif()
endif()
if(OPENSSL_SMALL)
@@ -458,10 +434,6 @@ if(NOT OPENSSL_NO_ASM AND CMAKE_OSX_ARCHITECTURES)
list(GET CMAKE_OSX_ARCHITECTURES 0 CMAKE_SYSTEM_PROCESSOR)
endif()
if(OPENSSL_NO_SSE2_FOR_TESTING)
add_definitions(-DOPENSSL_NO_SSE2_FOR_TESTING)
endif()
if(OPENSSL_NO_ASM)
add_definitions(-DOPENSSL_NO_ASM)
set(ARCH "generic")
@@ -471,7 +443,7 @@ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
set(ARCH "x86_64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
# cmake reports AMD64 on Windows, but we might be building for 32-bit.
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
if(CMAKE_CL_64)
set(ARCH "x86_64")
else()
set(ARCH "x86")
@@ -573,21 +545,10 @@ include_directories(third_party/googletest/include)
# themselves as dependencies next to the target definition.
add_custom_target(all_tests)
# On Windows, CRYPTO_TEST_DATA is too long to fit in command-line limits.
# TODO(davidben): CMake 3.12 has a list(JOIN) command. Use that when we've
# updated the minimum version.
set(EMBED_TEST_DATA_ARGS "")
foreach(arg ${CRYPTO_TEST_DATA})
set(EMBED_TEST_DATA_ARGS "${EMBED_TEST_DATA_ARGS}${arg}\n")
endforeach()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/embed_test_data_args.txt"
"${EMBED_TEST_DATA_ARGS}")
add_custom_command(
OUTPUT crypto_test_data.cc
COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go -file-list
"${CMAKE_CURRENT_BINARY_DIR}/embed_test_data_args.txt" >
"${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc"
COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go ${CRYPTO_TEST_DATA} >
${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc
DEPENDS util/embed_test_data.go ${CRYPTO_TEST_DATA}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
@@ -613,6 +574,11 @@ if(FUZZ)
add_subdirectory(fuzz)
endif()
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.2")
# USES_TERMINAL is only available in CMake 3.2 or later.
set(MAYBE_USES_TERMINAL USES_TERMINAL)
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
set(HANDSHAKER_ARGS "-handshaker-path" $<TARGET_FILE:handshaker>)
endif()
@@ -626,4 +592,4 @@ add_custom_target(
${HANDSHAKER_ARGS} ${RUNNER_ARGS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS all_tests bssl_shim handshaker
USES_TERMINAL)
${MAYBE_USES_TERMINAL})
-1
View File
@@ -26,7 +26,6 @@ The recommended values of `max_len` for each test are:
| Test | `max_len` value |
|---------------|-----------------|
| `bn_div` | 384 |
| `bn_mod_exp` | 4096 |
| `cert` | 10000 |
| `client` | 20000 |
+23
View File
@@ -181,6 +181,29 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The code in third_party/sike also carries the MIT license:
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
Licenses for support code
-------------------------
-8
View File
@@ -21,13 +21,6 @@ these patches in multiple places was growing steadily.
Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's
not part of the NDK) and a number of other apps/programs.
Project links:
* [API documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html)
* [Bug tracker](https://bugs.chromium.org/p/boringssl/issues/list)
* [CI](https://ci.chromium.org/p/boringssl/g/main/console)
* [Code review](https://boringssl-review.googlesource.com)
There are other files in this directory which might be helpful:
* [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
@@ -39,4 +32,3 @@ There are other files in this directory which might be helpful:
* [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
* [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL.
* [BREAKING-CHANGES.md](/BREAKING-CHANGES.md): notes on potentially-breaking changes.
* [SANDBOXING.md](/SANDBOXING.md): notes on using BoringSSL in a sandboxed environment.
-138
View File
@@ -1,138 +0,0 @@
# Using BoringSSL in a Sandbox
Sandboxes are a valuable tool for securing applications, so BoringSSL aims to
support them. However, it is difficult to make concrete API guarantees with
sandboxes. Sandboxes remove low-level OS resources and system calls, which
breaks platform abstractions. A syscall-filtering sandbox may, for instance, be
sensitive to otherwise non-breaking changes to use newer syscalls
in either BoringSSL or the C library.
Some functions in BoringSSL, such as `BIO_new_file`, inherently need OS
resources like the filesystem. We assume that sandboxed consumers either avoid
those functions or make necessary resources available. Other functions like
`RSA_sign` are purely computational, but still have some baseline OS
dependencies.
Sandboxes which drop privileges partway through a process's lifetime are
additionally sensitive to OS resources retained across the transitions. For
instance, if a library function internally opened and retained a handle to the
user's home directory, and then the application called `chroot`, that handle
would be a sandbox escape.
This document attempts to describe these baseline OS dependencies and long-lived
internal resources. These dependencies may change over time, but we aim to
[work with sandboxed consumers](/BREAKING-CHANGES.md) when they do. However,
each sandbox imposes different constraints, so, above all, sandboxed consumers
must have ample test coverage to detect issues as they arise.
## Baseline dependencies
Callers must assume that any BoringSSL function may perform one of the following
operations:
### Memory allocation
Any BoringSSL function may allocate memory via `malloc` and related functions.
### Thread synchronization
Any BoringSSL function may call into the platform's thread synchronization
primitives, including read/write locks and the equivalent of `pthread_once`.
These must succeed, or BoringSSL will abort the process. Callers, however, can
assume that BoringSSL functions will not spawn internal threads, unless
otherwise documented.
Syscall-filtering sandboxes should note that BoringSSL uses `pthread_rwlock_t`
on POSIX systems, which is less common and may not be part of other libraries'
syscall surface. Additionally, thread synchronization primitives usually have an
atomics-based fast path. If a sandbox blocks a necessary pthreads syscall, it
may not show up in testing without lock contention.
### Standard error
Any BoringSSL function may write to `stderr` or file descriptor
`STDERR_FILENO` (2), either via `FILE` APIs or low-level functions like `write`.
Writes to `stderr` may fail, but there must some file at `STDERR_FILENO` which
will tolerate error messages from BoringSSL. (The file descriptor must be
allocated so calls to `open` do not accidentally open something else there.)
Note some C standard library implementations also log to `stderr`, so callers
should ensure this regardless.
### Entropy
Any BoringSSL function may draw entropy from the OS. On Windows, this uses
`RtlGenRandom` and, on POSIX systems, this uses `getrandom`, `getentropy`, or a
`read` from a file descriptor to `/dev/urandom`. These operations must succeed
or BoringSSL will abort the process. BoringSSL only probes for `getrandom`
support once and assumes support is consistent for the lifetime of the address
space (and any copies made via `fork`). If a syscall-filtering sandbox is
enabled partway through this lifetime and changes whether `getrandom` works,
BoringSSL may abort the process. Sandboxes are recommended to allow
`getrandom`.
Note even deterministic algorithms may require OS entropy. For example,
RSASSA-PKCS1-v1_5 is deterministic, but BoringSSL draws entropy to implement
RSA blinding.
Entropy gathering additionally has some initialization dependencies described in
the following section.
## Initialization
BoringSSL has some uncommon OS dependencies which are only used once to
initialize some state. Sandboxes which drop privileges after some setup work may
use `CRYPTO_pre_sandbox_init` to initialize this state ahead of time. Otherwise,
callers must assume any BoringSSL function may depend on these resources, in
addition to the operations above.
### CPU capabilities
On Linux ARM platforms, BoringSSL depends on OS APIs to query CPU capabilities.
32-bit and 64-bit ARM both depend on the `getauxval` function. 32-bit ARM, to
work around bugs in older Android devices, may additionally read `/proc/cpuinfo`
and `/proc/self/auxv`.
If querying CPU capabilities fails, BoringSSL will still function, but may not
perform as well.
### Entropy
On Linux systems without a working `getrandom`, drawing entropy from the OS
additionally requires opening `/dev/urandom`. If this fails, BoringSSL will
abort the process. BoringSSL retains the resulting file descriptor, even across
privilege transitions.
### Fork protection
On Linux, BoringSSL allocates a page and calls `madvise` with `MADV_WIPEONFORK`
to protect single-use state from `fork`. This operation must not crash, but if
it fails, BoringSSL will use alternate fork-safety strategies, potentially at a
performance cost. If it succeeds, BoringSSL assumes `MADV_WIPEONFORK` is
functional and relies on it for fork-safety. Sandboxes must not report success
if they ignore the `MADV_WIPEONFORK` flag. As of writing, QEMU will ignore
`madvise` calls and report success, so BoringSSL detects this by calling
`madvise` with -1. Sandboxes must cleanly report an error instead of crashing.
Once initialized, this mechanism does not require system calls in the steady
state, though note the configured page will be inherited across privilege
transitions.
## C and C++ standard library
BoringSSL depends on the C and C++ standard libraries which, themselves, do not
make any guarantees about sandboxes. If it produces the correct answer and has
no observable invalid side effects, it is possible, though unreasonable, for
`memcmp` to create and close a socket.
BoringSSL assumes that functions in the C and C++ library only have the platform
dependencies which would be "reasonable". For instance, a function in BoringSSL
which aims not to open files will still freely call any libc memory and
string functions.
Note some C functions, such as `strerror`, may read files relating to the user's
locale. BoringSSL may trigger these paths and assumes the sandbox environment
will tolerate this. BoringSSL additionally cannot make guarantees about which
system calls are used by standard library's syscall wrappers. In some cases, the
compiler may add dependencies. (Some C++ language features emit locking code.)
Syscall-filtering sandboxes may need updates as these dependencies change.
+13 -41
View File
@@ -115,14 +115,7 @@ if(${ARCH} STREQUAL "aarch64")
chacha/chacha-armv8.${ASM_EXT}
test/trampoline-armv8.${ASM_EXT}
)
endif()
if(${ARCH} STREQUAL "ppc64le")
set(
CRYPTO_ARCH_SOURCES
test/trampoline-ppc.${ASM_EXT}
third_party/sike/asm/fp-armv8.${ASM_EXT}
)
endif()
@@ -144,6 +137,7 @@ if(${ARCH} STREQUAL "x86_64")
cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT}
hrss/asm/poly_rq_mul.S
test/trampoline-x86_64.${ASM_EXT}
third_party/sike/asm/fp-x86_64.${ASM_EXT}
)
endif()
@@ -153,9 +147,10 @@ perlasm(chacha/chacha-x86.${ASM_EXT} chacha/asm/chacha-x86.pl)
perlasm(chacha/chacha-x86_64.${ASM_EXT} chacha/asm/chacha-x86_64.pl)
perlasm(cipher_extra/aes128gcmsiv-x86_64.${ASM_EXT} cipher_extra/asm/aes128gcmsiv-x86_64.pl)
perlasm(cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT} cipher_extra/asm/chacha20_poly1305_x86_64.pl)
perlasm(third_party/sike/asm/fp-x86_64.${ASM_EXT} ../third_party/sike/asm/fp-x86_64.pl)
perlasm(third_party/sike/asm/fp-armv8.${ASM_EXT} ../third_party/sike/asm/fp-armv8.pl)
perlasm(test/trampoline-armv4.${ASM_EXT} test/asm/trampoline-armv4.pl)
perlasm(test/trampoline-armv8.${ASM_EXT} test/asm/trampoline-armv8.pl)
perlasm(test/trampoline-ppc.${ASM_EXT} test/asm/trampoline-ppc.pl)
perlasm(test/trampoline-x86.${ASM_EXT} test/asm/trampoline-x86.pl)
perlasm(test/trampoline-x86_64.${ASM_EXT} test/asm/trampoline-x86_64.pl)
@@ -184,7 +179,6 @@ add_custom_command(
err/pkcs8.errordata
err/rsa.errordata
err/ssl.errordata
err/trust_token.errordata
err/x509.errordata
err/x509v3.errordata
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/err
@@ -263,7 +257,6 @@ add_library(
cpu-intel.c
cpu-ppc64le.c
crypto.c
curve25519/curve25519.c
curve25519/spake25519.c
dh/dh.c
dh/params.c
@@ -275,8 +268,6 @@ add_library(
ecdh_extra/ecdh_extra.c
ecdsa_extra/ecdsa_asn1.c
ec_extra/ec_asn1.c
ec_extra/ec_derive.c
ec_extra/hash_to_curve.c
err/err.c
err_data.c
engine/engine.c
@@ -291,15 +282,12 @@ add_library(
evp/p_ed25519_asn1.c
evp/p_rsa.c
evp/p_rsa_asn1.c
evp/p_x25519.c
evp/p_x25519_asn1.c
evp/pbkdf.c
evp/print.c
evp/scrypt.c
evp/sign.c
ex_data.c
hkdf/hkdf.c
hpke/hpke.c
hrss/hrss.c
lhash/lhash.c
mem.c
@@ -338,8 +326,6 @@ add_library(
thread_none.c
thread_pthread.c
thread_win.c
trust_token/pmbtoken.c
trust_token/trust_token.c
x509/a_digest.c
x509/a_sign.c
x509/a_strex.c
@@ -422,6 +408,12 @@ add_library(
x509v3/v3_skey.c
x509v3/v3_sxnet.c
x509v3/v3_utl.c
../third_party/fiat/curve25519.c
../third_party/sike/fpx.c
../third_party/sike/isogeny.c
../third_party/sike/curve_params.c
../third_party/sike/sike.c
../third_party/sike/asm/fp_generic.c
$<TARGET_OBJECTS:fipsmodule>
@@ -430,17 +422,13 @@ add_library(
)
if(FIPS_SHARED)
set(EXTRA_INJECT_HASH_ARGS)
if(ANDROID)
set(EXTRA_INJECT_HASH_ARGS "-sha256")
endif()
# Rewrite libcrypto.so to inject the correct module hash value. This assumes
# UNIX-style library naming, but we only support FIPS mode on Linux anyway.
add_custom_command(
TARGET crypto POST_BUILD
COMMAND ${GO_EXECUTABLE} run
${CMAKE_CURRENT_SOURCE_DIR}/../util/fipstools/inject_hash/inject_hash.go
-o libcrypto.so -in-object libcrypto.so ${EXTRA_INJECT_HASH_ARGS}
-o libcrypto.so -in-object libcrypto.so
# The DEPENDS argument to a POST_BUILD rule appears to be ignored. Thus
# go_executable isn't used (as it doesn't get built), but we list this
# dependency anyway in case it starts working in some CMake version.
@@ -457,7 +445,7 @@ endif()
SET_TARGET_PROPERTIES(crypto PROPERTIES LINKER_LANGUAGE C)
if(NOT WIN32 AND NOT ANDROID)
if(NOT MSVC AND NOT ANDROID)
target_link_libraries(crypto pthread)
endif()
@@ -467,20 +455,6 @@ if(USE_CUSTOM_LIBCXX)
target_link_libraries(crypto libcxx)
endif()
# urandom_test is a separate binary because it needs to be able to observe the
# PRNG initialisation, which means that it can't have other tests running before
# it does.
add_executable(
urandom_test
fipsmodule/rand/urandom_test.cc
)
target_link_libraries(urandom_test test_support_lib boringssl_gtest crypto)
add_dependencies(urandom_test global_target)
add_dependencies(all_tests urandom_test)
add_executable(
crypto_test
@@ -517,10 +491,8 @@ add_executable(
fipsmodule/md5/md5_test.cc
fipsmodule/modes/gcm_test.cc
fipsmodule/rand/ctrdrbg_test.cc
fipsmodule/rand/fork_detect_test.cc
fipsmodule/sha/sha_test.cc
hkdf/hkdf_test.cc
hpke/hpke_test.cc
hmac_extra/hmac_test.cc
hrss/hrss_test.cc
impl_dispatch_test.cc
@@ -540,11 +512,11 @@ add_executable(
siphash/siphash_test.cc
test/file_test_gtest.cc
thread_test.cc
trust_token/trust_token_test.cc
x509/x509_test.cc
x509/x509_time_test.cc
x509v3/tab_test.cc
x509v3/v3name_test.cc
../third_party/sike/sike_test.cc
$<TARGET_OBJECTS:crypto_test_data>
$<TARGET_OBJECTS:boringssl_gtest_main>
+1 -286
View File
@@ -341,6 +341,7 @@ TEST(ABITest, ARM) {
}
#endif // OPENSSL_ARM && SUPPORTS_ABI_TEST
#if defined(OPENSSL_AARCH64) && defined(SUPPORTS_ABI_TEST)
extern "C" {
void abi_test_clobber_x0(void);
@@ -520,289 +521,3 @@ TEST(ABITest, AArch64) {
CHECK_ABI_NO_UNWIND(abi_test_clobber_v15_upper);
}
#endif // OPENSSL_AARCH64 && SUPPORTS_ABI_TEST
#if defined(OPENSSL_PPC64LE) && defined(SUPPORTS_ABI_TEST)
extern "C" {
void abi_test_clobber_r0(void);
// r1 is the stack pointer.
void abi_test_clobber_r2(void);
void abi_test_clobber_r3(void);
void abi_test_clobber_r4(void);
void abi_test_clobber_r5(void);
void abi_test_clobber_r6(void);
void abi_test_clobber_r7(void);
void abi_test_clobber_r8(void);
void abi_test_clobber_r9(void);
void abi_test_clobber_r10(void);
void abi_test_clobber_r11(void);
void abi_test_clobber_r12(void);
// r13 is the thread pointer.
void abi_test_clobber_r14(void);
void abi_test_clobber_r15(void);
void abi_test_clobber_r16(void);
void abi_test_clobber_r17(void);
void abi_test_clobber_r18(void);
void abi_test_clobber_r19(void);
void abi_test_clobber_r20(void);
void abi_test_clobber_r21(void);
void abi_test_clobber_r22(void);
void abi_test_clobber_r23(void);
void abi_test_clobber_r24(void);
void abi_test_clobber_r25(void);
void abi_test_clobber_r26(void);
void abi_test_clobber_r27(void);
void abi_test_clobber_r28(void);
void abi_test_clobber_r29(void);
void abi_test_clobber_r30(void);
void abi_test_clobber_r31(void);
void abi_test_clobber_f0(void);
void abi_test_clobber_f1(void);
void abi_test_clobber_f2(void);
void abi_test_clobber_f3(void);
void abi_test_clobber_f4(void);
void abi_test_clobber_f5(void);
void abi_test_clobber_f6(void);
void abi_test_clobber_f7(void);
void abi_test_clobber_f8(void);
void abi_test_clobber_f9(void);
void abi_test_clobber_f10(void);
void abi_test_clobber_f11(void);
void abi_test_clobber_f12(void);
void abi_test_clobber_f13(void);
void abi_test_clobber_f14(void);
void abi_test_clobber_f15(void);
void abi_test_clobber_f16(void);
void abi_test_clobber_f17(void);
void abi_test_clobber_f18(void);
void abi_test_clobber_f19(void);
void abi_test_clobber_f20(void);
void abi_test_clobber_f21(void);
void abi_test_clobber_f22(void);
void abi_test_clobber_f23(void);
void abi_test_clobber_f24(void);
void abi_test_clobber_f25(void);
void abi_test_clobber_f26(void);
void abi_test_clobber_f27(void);
void abi_test_clobber_f28(void);
void abi_test_clobber_f29(void);
void abi_test_clobber_f30(void);
void abi_test_clobber_f31(void);
void abi_test_clobber_v0(void);
void abi_test_clobber_v1(void);
void abi_test_clobber_v2(void);
void abi_test_clobber_v3(void);
void abi_test_clobber_v4(void);
void abi_test_clobber_v5(void);
void abi_test_clobber_v6(void);
void abi_test_clobber_v7(void);
void abi_test_clobber_v8(void);
void abi_test_clobber_v9(void);
void abi_test_clobber_v10(void);
void abi_test_clobber_v11(void);
void abi_test_clobber_v12(void);
void abi_test_clobber_v13(void);
void abi_test_clobber_v14(void);
void abi_test_clobber_v15(void);
void abi_test_clobber_v16(void);
void abi_test_clobber_v17(void);
void abi_test_clobber_v18(void);
void abi_test_clobber_v19(void);
void abi_test_clobber_v20(void);
void abi_test_clobber_v21(void);
void abi_test_clobber_v22(void);
void abi_test_clobber_v23(void);
void abi_test_clobber_v24(void);
void abi_test_clobber_v25(void);
void abi_test_clobber_v26(void);
void abi_test_clobber_v27(void);
void abi_test_clobber_v28(void);
void abi_test_clobber_v29(void);
void abi_test_clobber_v30(void);
void abi_test_clobber_v31(void);
void abi_test_clobber_cr0(void);
void abi_test_clobber_cr1(void);
void abi_test_clobber_cr2(void);
void abi_test_clobber_cr3(void);
void abi_test_clobber_cr4(void);
void abi_test_clobber_cr5(void);
void abi_test_clobber_cr6(void);
void abi_test_clobber_cr7(void);
void abi_test_clobber_ctr(void);
void abi_test_clobber_lr(void);
} // extern "C"
TEST(ABITest, PPC64LE) {
// abi_test_trampoline hides unsaved registers from the caller, so we can
// safely call the abi_test_clobber_* functions below.
abi_test::internal::CallerState state;
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
CHECK_ABI_NO_UNWIND(abi_test_trampoline,
reinterpret_cast<crypto_word_t>(abi_test_clobber_r14),
&state, nullptr, 0, 0 /* no breakpoint */);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r0);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r2);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r3);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r4);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r5);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r6);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r7);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r8);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r9);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r10);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r11);
CHECK_ABI_NO_UNWIND(abi_test_clobber_r12);
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r14),
"r14 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r15),
"r15 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r16),
"r16 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r17),
"r17 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r18),
"r18 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r19),
"r19 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r20),
"r20 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r21),
"r21 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r22),
"r22 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r23),
"r23 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r24),
"r24 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r25),
"r25 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r26),
"r26 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r27),
"r27 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r28),
"r28 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r29),
"r29 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r30),
"r30 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r31),
"r31 was not restored after return");
CHECK_ABI_NO_UNWIND(abi_test_clobber_f0);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f1);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f2);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f3);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f4);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f5);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f6);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f7);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f8);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f9);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f10);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f11);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f12);
CHECK_ABI_NO_UNWIND(abi_test_clobber_f13);
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f14),
"f14 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f15),
"f15 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f16),
"f16 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f17),
"f17 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f18),
"f18 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f19),
"f19 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f20),
"f20 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f21),
"f21 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f22),
"f22 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f23),
"f23 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f24),
"f24 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f25),
"f25 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f26),
"f26 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f27),
"f27 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f28),
"f28 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f29),
"f29 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f30),
"f30 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f31),
"f31 was not restored after return");
CHECK_ABI_NO_UNWIND(abi_test_clobber_v0);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v1);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v2);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v3);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v4);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v5);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v6);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v7);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v8);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v9);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v10);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v11);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v12);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v13);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v14);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v15);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v16);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v17);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v18);
CHECK_ABI_NO_UNWIND(abi_test_clobber_v19);
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v20),
"v20 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v21),
"v21 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v22),
"v22 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v23),
"v23 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v24),
"v24 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v25),
"v25 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v26),
"v26 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v27),
"v27 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v28),
"v28 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v29),
"v29 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v30),
"v30 was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v31),
"v31 was not restored after return");
CHECK_ABI_NO_UNWIND(abi_test_clobber_cr0);
CHECK_ABI_NO_UNWIND(abi_test_clobber_cr1);
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr2),
"cr was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr3),
"cr was not restored after return");
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr4),
"cr was not restored after return");
CHECK_ABI_NO_UNWIND(abi_test_clobber_cr5);
CHECK_ABI_NO_UNWIND(abi_test_clobber_cr6);
CHECK_ABI_NO_UNWIND(abi_test_clobber_cr7);
CHECK_ABI_NO_UNWIND(abi_test_clobber_ctr);
CHECK_ABI_NO_UNWIND(abi_test_clobber_lr);
}
#endif // OPENSSL_PPC64LE && SUPPORTS_ABI_TEST
+3 -3
View File
@@ -70,7 +70,7 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
return M_ASN1_BIT_STRING_set(x, d, len);
}
int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp)
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
int ret, j, bits, len;
unsigned char *p, *d;
@@ -233,7 +233,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
return (1);
}
int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w, v;
@@ -250,7 +250,7 @@ int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
unsigned char *flags, int flags_len)
{
int i, ok;
+3 -3
View File
@@ -108,7 +108,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
return (1);
}
long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
{
int neg = 0, i;
@@ -147,7 +147,7 @@ long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
return r;
}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
{
ASN1_ENUMERATED *ret;
int len, j;
@@ -183,7 +183,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
return (NULL);
}
BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
{
BIGNUM *ret;
+1 -1
View File
@@ -115,7 +115,7 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
* followed by optional zeros isn't padded.
*/
int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp)
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
int pad = 0, ret, i, neg;
unsigned char *p, *n, pb = 0;
+3 -3
View File
@@ -66,7 +66,7 @@
#include "../internal.h"
int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p, *allocated = NULL;
int objsize;
@@ -98,12 +98,12 @@ int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
return objsize;
}
int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
{
char buf[80], *p = buf;
int i;
+6 -5
View File
@@ -60,6 +60,7 @@
#include <time.h>
#include <openssl/asn1t.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -100,7 +101,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
}
int ASN1_TIME_check(const ASN1_TIME *t)
int ASN1_TIME_check(ASN1_TIME *t)
{
if (t->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_check(t);
@@ -110,7 +111,7 @@ int ASN1_TIME_check(const ASN1_TIME *t)
}
/* Convert an ASN1_TIME structure to GeneralizedTime */
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *ret = NULL;
@@ -142,11 +143,11 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
str = (char *)ret->data;
/* Work out the century and prepend */
if (t->data[0] >= '5')
OPENSSL_strlcpy(str, "19", newlen);
BUF_strlcpy(str, "19", newlen);
else
OPENSSL_strlcpy(str, "20", newlen);
BUF_strlcpy(str, "20", newlen);
OPENSSL_strlcat(str, (char *)t->data, newlen);
BUF_strlcat(str, (char *)t->data, newlen);
done:
if (out != NULL && *out == NULL)
+1 -1
View File
@@ -61,7 +61,7 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
int ASN1_TYPE_get(const ASN1_TYPE *a)
int ASN1_TYPE_get(ASN1_TYPE *a)
{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return (a->type);
+1 -1
View File
@@ -430,7 +430,7 @@ void ASN1_STRING_length_set(ASN1_STRING *x, int len)
return;
}
int ASN1_STRING_type(const ASN1_STRING *x)
int ASN1_STRING_type(ASN1_STRING *x)
{
return M_ASN1_STRING_type(x);
}
+1 -1
View File
@@ -174,7 +174,7 @@ TEST(ASN1Test, SerializeObject) {
static const uint8_t kDER[] = {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01};
const ASN1_OBJECT *obj = OBJ_nid2obj(NID_rsaEncryption);
TestSerialize(obj, i2d_ASN1_OBJECT, kDER);
TestSerialize(const_cast<ASN1_OBJECT *>(obj), i2d_ASN1_OBJECT, kDER);
}
TEST(ASN1Test, SerializeBoolean) {
+1 -1
View File
@@ -93,7 +93,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
/* Extract an ASN1 object from an ASN1_STRING */
void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
{
const unsigned char *p;
void *ret;
+1 -1
View File
@@ -60,7 +60,7 @@
/* Based on a_int.c: equivalent ENUMERATED functions */
int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
+1 -1
View File
@@ -58,7 +58,7 @@
#include <openssl/bio.h>
int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
+1 -1
View File
@@ -58,7 +58,7 @@
#include <openssl/bio.h>
int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
+1 -1
View File
@@ -192,7 +192,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
/* Use indefinite length constructed if requested */
if (aclass & ASN1_TFLG_NDEF)
ndef = 2;
OPENSSL_FALLTHROUGH;
/* fall through */
case ASN1_ITYPE_SEQUENCE:
i = asn1_enc_restore(&seqcontlen, out, pval, it);
+1 -1
View File
@@ -105,7 +105,7 @@ static const Base64TestVector kTestVectors[] = {
class Base64Test : public testing::TestWithParam<Base64TestVector> {};
INSTANTIATE_TEST_SUITE_P(All, Base64Test, testing::ValuesIn(kTestVectors));
INSTANTIATE_TEST_SUITE_P(, Base64Test, testing::ValuesIn(kTestVectors));
// RemoveNewlines returns a copy of |in| with all '\n' characters removed.
static std::string RemoveNewlines(const char *in) {
+2 -2
View File
@@ -220,7 +220,7 @@ TEST_P(BIOASN1Test, ReadASN1) {
}
}
INSTANTIATE_TEST_SUITE_P(All, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
INSTANTIATE_TEST_SUITE_P(, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
// Run through the tests twice, swapping |bio1| and |bio2|, for symmetry.
class BIOPairTest : public testing::TestWithParam<bool> {};
@@ -322,4 +322,4 @@ TEST_P(BIOPairTest, TestPair) {
EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
}
INSTANTIATE_TEST_SUITE_P(All, BIOPairTest, testing::Values(false, true));
INSTANTIATE_TEST_SUITE_P(, BIOPairTest, testing::Values(false, true));
+4 -3
View File
@@ -74,6 +74,7 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -148,7 +149,7 @@ static int split_host_and_port(char **out_host, char **out_port, const char *nam
}
}
*out_host = OPENSSL_strndup(host, host_len);
*out_host = BUF_strndup(host, host_len);
if (*out_host == NULL) {
return 0;
}
@@ -428,13 +429,13 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
bio->init = 1;
if (num == 0) {
OPENSSL_free(data->param_hostname);
data->param_hostname = OPENSSL_strdup(ptr);
data->param_hostname = BUF_strdup(ptr);
if (data->param_hostname == NULL) {
ret = 0;
}
} else if (num == 1) {
OPENSSL_free(data->param_port);
data->param_port = OPENSSL_strdup(ptr);
data->param_port = BUF_strdup(ptr);
if (data->param_port == NULL) {
ret = 0;
}
+1
View File
@@ -70,6 +70,7 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
+6 -5
View File
@@ -79,6 +79,7 @@
#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -207,16 +208,16 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
b->shutdown = (int)num & BIO_CLOSE;
if (num & BIO_FP_APPEND) {
if (num & BIO_FP_READ) {
OPENSSL_strlcpy(p, "a+", sizeof(p));
BUF_strlcpy(p, "a+", sizeof(p));
} else {
OPENSSL_strlcpy(p, "a", sizeof(p));
BUF_strlcpy(p, "a", sizeof(p));
}
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) {
OPENSSL_strlcpy(p, "r+", sizeof(p));
BUF_strlcpy(p, "r+", sizeof(p));
} else if (num & BIO_FP_WRITE) {
OPENSSL_strlcpy(p, "w", sizeof(p));
BUF_strlcpy(p, "w", sizeof(p));
} else if (num & BIO_FP_READ) {
OPENSSL_strlcpy(p, "r", sizeof(p));
BUF_strlcpy(p, "r", sizeof(p));
} else {
OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
ret = 0;
+1
View File
@@ -55,6 +55,7 @@
#include <assert.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
+69 -10
View File
@@ -132,10 +132,6 @@ size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) {
}
int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
// Work around a C language bug. See https://crbug.com/1019588.
if (len == 0) {
return 1;
}
size_t new_len = buf->length + len;
if (new_len < len) {
OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW);
@@ -149,24 +145,87 @@ int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
return 1;
}
char *BUF_strdup(const char *str) { return OPENSSL_strdup(str); }
char *BUF_strdup(const char *str) {
if (str == NULL) {
return NULL;
}
return BUF_strndup(str, strlen(str));
}
size_t BUF_strnlen(const char *str, size_t max_len) {
return OPENSSL_strnlen(str, max_len);
size_t i;
for (i = 0; i < max_len; i++) {
if (str[i] == 0) {
break;
}
}
return i;
}
char *BUF_strndup(const char *str, size_t size) {
return OPENSSL_strndup(str, size);
char *ret;
size_t alloc_size;
if (str == NULL) {
return NULL;
}
size = BUF_strnlen(str, size);
alloc_size = size + 1;
if (alloc_size < size) {
// overflow
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret = OPENSSL_malloc(alloc_size);
if (ret == NULL) {
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
OPENSSL_memcpy(ret, str, size);
ret[size] = '\0';
return ret;
}
size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size) {
return OPENSSL_strlcpy(dst, src, dst_size);
size_t l = 0;
for (; dst_size > 1 && *src; dst_size--) {
*dst++ = *src++;
l++;
}
if (dst_size) {
*dst = 0;
}
return l + strlen(src);
}
size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) {
return OPENSSL_strlcat(dst, src, dst_size);
size_t l = 0;
for (; dst_size > 0 && *dst; dst_size--, dst++) {
l++;
}
return l + BUF_strlcpy(dst, src, dst_size);
}
void *BUF_memdup(const void *data, size_t size) {
return OPENSSL_memdup(data, size);
if (size == 0) {
return NULL;
}
void *ret = OPENSSL_malloc(size);
if (ret == NULL) {
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
OPENSSL_memcpy(ret, data, size);
return ret;
}
+1 -87
View File
@@ -67,14 +67,6 @@ TEST(CBSTest, GetUint) {
EXPECT_EQ(0x13u, u8);
EXPECT_FALSE(CBS_get_u8(&data, &u8));
EXPECT_FALSE(CBS_get_last_u8(&data, &u8));
CBS_init(&data, kData, sizeof(kData));
ASSERT_TRUE(CBS_get_u16le(&data, &u16));
EXPECT_EQ(0x0201u, u16);
ASSERT_TRUE(CBS_get_u32le(&data, &u32));
EXPECT_EQ(0x06050403u, u32);
ASSERT_TRUE(CBS_get_u64le(&data, &u64));
EXPECT_EQ(0x0e0d0c0b0a090807u, u64);
}
TEST(CBSTest, GetPrefixed) {
@@ -324,9 +316,7 @@ TEST(CBBTest, InitUninitialized) {
TEST(CBBTest, Basic) {
static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7,
8, 9, 0xa, 0xb, 0xc, 0xd, 0xe,
0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 3, 2,
10, 9, 8, 7, 0x12, 0x11, 0x10,
0xf, 0xe, 0xd, 0xc, 0xb};
0xf, 0x10, 0x11, 0x12, 0x13, 0x14};
uint8_t *buf;
size_t buf_len;
@@ -341,9 +331,6 @@ TEST(CBBTest, Basic) {
ASSERT_TRUE(CBB_add_u32(cbb.get(), 0x708090a));
ASSERT_TRUE(CBB_add_u64(cbb.get(), 0xb0c0d0e0f101112));
ASSERT_TRUE(CBB_add_bytes(cbb.get(), (const uint8_t *)"\x13\x14", 2));
ASSERT_TRUE(CBB_add_u16le(cbb.get(), 0x203));
ASSERT_TRUE(CBB_add_u32le(cbb.get(), 0x708090a));
ASSERT_TRUE(CBB_add_u64le(cbb.get(), 0xb0c0d0e0f101112));
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
bssl::UniquePtr<uint8_t> scoper(buf);
@@ -767,79 +754,6 @@ TEST(CBSTest, ASN1Uint64) {
}
}
struct ASN1Int64Test {
int64_t value;
const char *encoding;
size_t encoding_len;
};
static const ASN1Int64Test kASN1Int64Tests[] = {
{0, "\x02\x01\x00", 3},
{1, "\x02\x01\x01", 3},
{-1, "\x02\x01\xff", 3},
{127, "\x02\x01\x7f", 3},
{-127, "\x02\x01\x81", 3},
{128, "\x02\x02\x00\x80", 4},
{-128, "\x02\x01\x80", 3},
{129, "\x02\x02\x00\x81", 4},
{-129, "\x02\x02\xff\x7f", 4},
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
{INT64_C(0x0102030405060708), "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08",
10},
{INT64_MIN, "\x02\x08\x80\x00\x00\x00\x00\x00\x00\x00", 10},
{INT64_MAX, "\x02\x08\x7f\xff\xff\xff\xff\xff\xff\xff", 10},
};
struct ASN1InvalidInt64Test {
const char *encoding;
size_t encoding_len;
};
static const ASN1InvalidInt64Test kASN1InvalidInt64Tests[] = {
// Bad tag.
{"\x03\x01\x00", 3},
// Empty contents.
{"\x02\x00", 2},
// Overflow.
{"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
// Leading zeros.
{"\x02\x02\x00\x01", 4},
// Leading 0xff.
{"\x02\x02\xff\xff", 4},
};
TEST(CBSTest, ASN1Int64) {
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Int64Tests); i++) {
SCOPED_TRACE(i);
const ASN1Int64Test *test = &kASN1Int64Tests[i];
CBS cbs;
int64_t value;
uint8_t *out;
size_t len;
CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
ASSERT_TRUE(CBS_get_asn1_int64(&cbs, &value));
EXPECT_EQ(0u, CBS_len(&cbs));
EXPECT_EQ(test->value, value);
bssl::ScopedCBB cbb;
ASSERT_TRUE(CBB_init(cbb.get(), 0));
ASSERT_TRUE(CBB_add_asn1_int64(cbb.get(), test->value));
ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len));
bssl::UniquePtr<uint8_t> scoper(out);
EXPECT_EQ(Bytes(test->encoding, test->encoding_len), Bytes(out, len));
}
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1InvalidInt64Tests); i++) {
const ASN1InvalidInt64Test *test = &kASN1InvalidInt64Tests[i];
CBS cbs;
int64_t value;
CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
EXPECT_FALSE(CBS_get_asn1_int64(&cbs, &value));
}
}
TEST(CBBTest, Zero) {
CBB cbb;
CBB_zero(&cbb);
+2 -41
View File
@@ -18,6 +18,7 @@
#include <limits.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/mem.h>
#include "../internal.h"
@@ -447,10 +448,6 @@ int CBB_add_u16(CBB *cbb, uint16_t value) {
return cbb_buffer_add_u(cbb->base, value, 2);
}
int CBB_add_u16le(CBB *cbb, uint16_t value) {
return CBB_add_u16(cbb, CRYPTO_bswap2(value));
}
int CBB_add_u24(CBB *cbb, uint32_t value) {
if (!CBB_flush(cbb)) {
return 0;
@@ -467,10 +464,6 @@ int CBB_add_u32(CBB *cbb, uint32_t value) {
return cbb_buffer_add_u(cbb->base, value, 4);
}
int CBB_add_u32le(CBB *cbb, uint32_t value) {
return CBB_add_u32(cbb, CRYPTO_bswap4(value));
}
int CBB_add_u64(CBB *cbb, uint64_t value) {
if (!CBB_flush(cbb)) {
return 0;
@@ -478,10 +471,6 @@ int CBB_add_u64(CBB *cbb, uint64_t value) {
return cbb_buffer_add_u(cbb->base, value, 8);
}
int CBB_add_u64le(CBB *cbb, uint64_t value) {
return CBB_add_u64(cbb, CRYPTO_bswap8(value));
}
void CBB_discard_child(CBB *cbb) {
if (cbb->child == NULL) {
return;
@@ -528,34 +517,6 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
return CBB_flush(cbb);
}
int CBB_add_asn1_int64(CBB *cbb, int64_t value) {
if (value >= 0) {
return CBB_add_asn1_uint64(cbb, value);
}
union {
int64_t i;
uint8_t bytes[sizeof(int64_t)];
} u;
u.i = value;
int start = 7;
// Skip leading sign-extension bytes unless they are necessary.
while (start > 0 && (u.bytes[start] == 0xff && (u.bytes[start - 1] & 0x80))) {
start--;
}
CBB child;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
return 0;
}
for (int i = start; i >= 0; i--) {
if (!CBB_add_u8(&child, u.bytes[i])) {
return 0;
}
}
return CBB_flush(cbb);
}
int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) {
CBB child;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) ||
@@ -688,7 +649,7 @@ int CBB_flush_asn1_set_of(CBB *cbb) {
// remain valid as we rewrite |cbb|.
int ret = 0;
size_t buf_len = CBB_len(cbb);
uint8_t *buf = OPENSSL_memdup(CBB_data(cbb), buf_len);
uint8_t *buf = BUF_memdup(CBB_data(cbb), buf_len);
CBS *children = OPENSSL_malloc(num_children * sizeof(CBS));
if (buf == NULL || children == NULL) {
goto err;
+3 -60
View File
@@ -12,6 +12,7 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/buf.h>
#include <openssl/mem.h>
#include <openssl/bytestring.h>
@@ -60,7 +61,7 @@ int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
if (cbs->len == 0) {
return 1;
}
*out_ptr = OPENSSL_memdup(cbs->data, cbs->len);
*out_ptr = BUF_memdup(cbs->data, cbs->len);
if (*out_ptr == NULL) {
return 0;
}
@@ -72,7 +73,7 @@ int CBS_strdup(const CBS *cbs, char **out_ptr) {
if (*out_ptr != NULL) {
OPENSSL_free(*out_ptr);
}
*out_ptr = OPENSSL_strndup((const char*)cbs->data, cbs->len);
*out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
return (*out_ptr != NULL);
}
@@ -120,14 +121,6 @@ int CBS_get_u16(CBS *cbs, uint16_t *out) {
return 1;
}
int CBS_get_u16le(CBS *cbs, uint16_t *out) {
if (!CBS_get_u16(cbs, out)) {
return 0;
}
*out = CRYPTO_bswap2(*out);
return 1;
}
int CBS_get_u24(CBS *cbs, uint32_t *out) {
uint64_t v;
if (!cbs_get_u(cbs, &v, 3)) {
@@ -146,26 +139,10 @@ int CBS_get_u32(CBS *cbs, uint32_t *out) {
return 1;
}
int CBS_get_u32le(CBS *cbs, uint32_t *out) {
if (!CBS_get_u32(cbs, out)) {
return 0;
}
*out = CRYPTO_bswap4(*out);
return 1;
}
int CBS_get_u64(CBS *cbs, uint64_t *out) {
return cbs_get_u(cbs, out, 8);
}
int CBS_get_u64le(CBS *cbs, uint64_t *out) {
if (!cbs_get_u(cbs, out, 8)) {
return 0;
}
*out = CRYPTO_bswap8(*out);
return 1;
}
int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
if (cbs->len == 0) {
return 0;
@@ -461,40 +438,6 @@ int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
return 1;
}
int CBS_get_asn1_int64(CBS *cbs, int64_t *out) {
CBS bytes;
if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
return 0;
}
const uint8_t *data = CBS_data(&bytes);
const size_t len = CBS_len(&bytes);
if (len == 0 || len > sizeof(int64_t)) {
// An INTEGER is encoded with at least one octet.
return 0;
}
if (len > 1) {
if (data[0] == 0 && (data[1] & 0x80) == 0) {
return 0; // Extra leading zeros.
}
if (data[0] == 0xff && (data[1] & 0x80) != 0) {
return 0; // Extra leading 0xff.
}
}
union {
int64_t i;
uint8_t bytes[sizeof(int64_t)];
} u;
const int is_negative = (data[0] & 0x80);
memset(u.bytes, is_negative ? 0xff : 0, sizeof(u.bytes)); // Sign-extend.
for (size_t i = 0; i < len; i++) {
u.bytes[i] = data[len - i - 1];
}
*out = u.i;
return 1;
}
int CBS_get_asn1_bool(CBS *cbs, int *out) {
CBS bytes;
if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) ||
+2 -4
View File
@@ -44,11 +44,9 @@ if ($flavour && $flavour ne "void") {
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open OUT,">$output";
*STDOUT=*OUT;
open STDOUT,">$output";
}
sub AUTOLOAD() # thunk [simplified] x86-style perlasm
+8 -5
View File
@@ -131,6 +131,12 @@ $code.=<<___;
.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
.Lone:
.long 1,0,0,0
.LOPENSSL_armcap_P:
#ifdef __ILP32__
.long OPENSSL_armcap_P-.
#else
.quad OPENSSL_armcap_P-.
#endif
.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.text
@@ -140,14 +146,11 @@ $code.=<<___;
.align 5
ChaCha20_ctr32:
cbz $len,.Labort
#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10
adrp @x[0],:pg_hi21_nc:OPENSSL_armcap_P
#else
adrp @x[0],:pg_hi21:OPENSSL_armcap_P
#endif
cmp $len,#192
b.lo .Lshort
ldr w17,[@x[0],:lo12:OPENSSL_armcap_P]
add @x[0],@x[0],:lo12:OPENSSL_armcap_P
ldr w17,[@x[0]]
tst w17,#ARMV7_NEON
b.ne ChaCha20_neon
+13 -109
View File
@@ -25,7 +25,6 @@
#include "../fipsmodule/cipher/internal.h"
#include "../internal.h"
#include "../test/abi_test.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"
@@ -54,8 +53,6 @@ static const struct KnownAEAD kAEADs[] = {
true, 0},
{"AES_128_GCM_NIST", EVP_aead_aes_128_gcm, "nist_cavp/aes_128_gcm.txt",
false, true, true, 0},
{"AES_192_GCM", EVP_aead_aes_192_gcm, "aes_192_gcm_tests.txt", false, true,
true, 0},
{"AES_256_GCM", EVP_aead_aes_256_gcm, "aes_256_gcm_tests.txt", false, true,
true, 0},
{"AES_256_GCM_NIST", EVP_aead_aes_256_gcm, "nist_cavp/aes_256_gcm.txt",
@@ -104,7 +101,7 @@ class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
const EVP_AEAD *aead() { return GetParam().func(); }
};
INSTANTIATE_TEST_SUITE_P(All, PerAEADTest, testing::ValuesIn(kAEADs),
INSTANTIATE_TEST_SUITE_P(, PerAEADTest, testing::ValuesIn(kAEADs),
[](const testing::TestParamInfo<KnownAEAD> &params)
-> std::string { return params.param.name; });
@@ -543,10 +540,10 @@ TEST_P(PerAEADTest, AliasedBuffers) {
}
TEST_P(PerAEADTest, UnalignedInput) {
alignas(16) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH + 1];
alignas(16) uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH + 1];
alignas(16) uint8_t plaintext[32 + 1];
alignas(16) uint8_t ad[32 + 1];
alignas(64) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH + 1];
alignas(64) uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH + 1];
alignas(64) uint8_t plaintext[32 + 1];
alignas(64) uint8_t ad[32 + 1];
OPENSSL_memset(key, 'K', sizeof(key));
OPENSSL_memset(nonce, 'N', sizeof(nonce));
OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
@@ -564,7 +561,7 @@ TEST_P(PerAEADTest, UnalignedInput) {
ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
evp_aead_seal));
alignas(16) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD];
alignas(64) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD];
size_t ciphertext_len;
ASSERT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), ciphertext + 1, &ciphertext_len,
sizeof(ciphertext) - 1, nonce + 1, nonce_len,
@@ -572,7 +569,7 @@ TEST_P(PerAEADTest, UnalignedInput) {
ad_len));
// It must successfully decrypt.
alignas(16) uint8_t out[sizeof(ciphertext)];
alignas(64) uint8_t out[sizeof(ciphertext)];
ctx.Reset();
ASSERT_TRUE(EVP_AEAD_CTX_init_with_direction(
ctx.get(), aead(), key + 1, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
@@ -586,7 +583,7 @@ TEST_P(PerAEADTest, UnalignedInput) {
}
TEST_P(PerAEADTest, Overflow) {
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
alignas(64) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
OPENSSL_memset(key, 'K', sizeof(key));
bssl::ScopedEVP_AEAD_CTX ctx;
@@ -665,91 +662,6 @@ TEST_P(PerAEADTest, InvalidNonceLength) {
}
}
#if defined(SUPPORTS_ABI_TEST)
// CHECK_ABI can't pass enums, i.e. |evp_aead_seal| and |evp_aead_open|. Thus
// these two wrappers.
static int aead_ctx_init_for_seal(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len) {
return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, 0,
evp_aead_seal);
}
static int aead_ctx_init_for_open(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len) {
return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, 0,
evp_aead_open);
}
// CHECK_ABI can pass, at most, eight arguments. Thus these wrappers that
// figure out the output length from the input length, and take the nonce length
// from the configuration of the AEAD.
static int aead_ctx_seal(EVP_AEAD_CTX *ctx, uint8_t *out_ciphertext,
size_t *out_ciphertext_len, const uint8_t *nonce,
const uint8_t *plaintext, size_t plaintext_len,
const uint8_t *ad, size_t ad_len) {
const size_t nonce_len = EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(ctx));
return EVP_AEAD_CTX_seal(ctx, out_ciphertext, out_ciphertext_len,
plaintext_len + EVP_AEAD_MAX_OVERHEAD, nonce,
nonce_len, plaintext, plaintext_len, ad, ad_len);
}
static int aead_ctx_open(EVP_AEAD_CTX *ctx, uint8_t *out_plaintext,
size_t *out_plaintext_len, const uint8_t *nonce,
const uint8_t *ciphertext, size_t ciphertext_len,
const uint8_t *ad, size_t ad_len) {
const size_t nonce_len = EVP_AEAD_nonce_length(EVP_AEAD_CTX_aead(ctx));
return EVP_AEAD_CTX_open(ctx, out_plaintext, out_plaintext_len,
ciphertext_len, nonce, nonce_len, ciphertext,
ciphertext_len, ad, ad_len);
}
TEST_P(PerAEADTest, ABI) {
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
OPENSSL_memset(key, 'K', sizeof(key));
const size_t key_len = EVP_AEAD_key_length(aead());
ASSERT_LE(key_len, sizeof(key));
bssl::ScopedEVP_AEAD_CTX ctx_seal;
ASSERT_TRUE(
CHECK_ABI(aead_ctx_init_for_seal, ctx_seal.get(), aead(), key, key_len));
bssl::ScopedEVP_AEAD_CTX ctx_open;
ASSERT_TRUE(
CHECK_ABI(aead_ctx_init_for_open, ctx_open.get(), aead(), key, key_len));
alignas(2) uint8_t plaintext[512];
OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
alignas(2) uint8_t ad_buf[512];
OPENSSL_memset(ad_buf, 'A', sizeof(ad_buf));
const uint8_t *const ad = ad_buf + 1;
ASSERT_LE(GetParam().ad_len, sizeof(ad_buf) - 1);
const size_t ad_len =
GetParam().ad_len != 0 ? GetParam().ad_len : sizeof(ad_buf) - 1;
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
const size_t nonce_len = EVP_AEAD_nonce_length(aead());
ASSERT_LE(nonce_len, sizeof(nonce));
alignas(2) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD + 1];
size_t ciphertext_len;
// Knock plaintext, ciphertext, and AD off alignment and give odd lengths for
// plaintext and AD. This hopefully triggers any edge-cases in the assembly.
ASSERT_TRUE(CHECK_ABI(aead_ctx_seal, ctx_seal.get(), ciphertext + 1,
&ciphertext_len, nonce, plaintext + 1,
sizeof(plaintext) - 1, ad, ad_len));
alignas(2) uint8_t plaintext2[sizeof(ciphertext) + 1];
size_t plaintext2_len;
ASSERT_TRUE(CHECK_ABI(aead_ctx_open, ctx_open.get(), plaintext2 + 1,
&plaintext2_len, nonce, ciphertext + 1, ciphertext_len,
ad, ad_len));
EXPECT_EQ(Bytes(plaintext + 1, sizeof(plaintext) - 1),
Bytes(plaintext2 + 1, plaintext2_len));
}
#endif // SUPPORTS_ABI_TEST
TEST(AEADTest, AESCCMLargeAD) {
static const std::vector<uint8_t> kKey(16, 'A');
static const std::vector<uint8_t> kNonce(13, 'N');
@@ -814,8 +726,8 @@ static void RunWycheproofTestCase(FileTest *t, const EVP_AEAD *aead) {
size_t out_len;
// Wycheproof tags small AES-GCM IVs as "acceptable" and otherwise does not
// use it in AEADs. Any AES-GCM IV that isn't 96 bits is absurd, but our API
// supports those, so we treat SmallIv tests as valid.
if (result.IsValid({"SmallIv"})) {
// supports those, so we treat "acceptable" as "valid" here.
if (result != WycheproofResult::kInvalid) {
// Decryption should succeed.
ASSERT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
iv.data(), iv.size(), ct_and_tag.data(),
@@ -889,8 +801,9 @@ TEST(AEADTest, WycheproofAESGCM) {
aead = EVP_aead_aes_128_gcm();
break;
case 192:
aead = EVP_aead_aes_192_gcm();
break;
// Skip AES-192-GCM tests.
t->SkipCurrent();
return;
case 256:
aead = EVP_aead_aes_256_gcm();
break;
@@ -909,12 +822,3 @@ TEST(AEADTest, WycheproofChaCha20Poly1305) {
RunWycheproofTestCase(t, EVP_aead_chacha20_poly1305());
});
}
TEST(AEADTest, WycheproofXChaCha20Poly1305) {
FileTestGTest(
"third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("keySize");
RunWycheproofTestCase(t, EVP_aead_xchacha20_poly1305());
});
}
@@ -1273,7 +1273,7 @@ do_length_block:\n";
pop %rbp
.cfi_adjust_cfa_offset -8
ret
.cfi_adjust_cfa_offset (8 * 7) + 288 + 32
.cfi_adjust_cfa_offset (8 * 6) + 288 + 32
################################################################################
seal_sse_128:
movdqu .chacha20_consts(%rip), $A0\nmovdqa $A0, $A1\nmovdqa $A0, $A2
@@ -2478,7 +2478,6 @@ if (!$win64) {
print $code;
} else {
print <<___;
.text
.globl dummy_chacha20_poly1305_asm
.type dummy_chacha20_poly1305_asm,\@abi-omnipotent
dummy_chacha20_poly1305_asm:
+68 -167
View File
@@ -61,10 +61,8 @@
#include <gtest/gtest.h>
#include <openssl/aes.h>
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/nid.h>
#include <openssl/span.h>
#include "../test/file_test.h"
@@ -120,8 +118,7 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
}
static bool DoCipher(EVP_CIPHER_CTX *ctx, std::vector<uint8_t> *out,
bssl::Span<const uint8_t> in, size_t chunk,
bool in_place) {
bssl::Span<const uint8_t> in, size_t chunk) {
size_t max_out = in.size();
if ((EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_NO_PADDING) == 0 &&
EVP_CIPHER_CTX_encrypting(ctx)) {
@@ -129,10 +126,6 @@ static bool DoCipher(EVP_CIPHER_CTX *ctx, std::vector<uint8_t> *out,
max_out += block_size - (max_out % block_size);
}
out->resize(max_out);
if (in_place) {
std::copy(in.begin(), in.end(), out->begin());
in = bssl::MakeConstSpan(out->data(), in.size());
}
size_t total = 0;
int len;
@@ -157,7 +150,7 @@ static bool DoCipher(EVP_CIPHER_CTX *ctx, std::vector<uint8_t> *out,
}
static void TestOperation(FileTest *t, const EVP_CIPHER *cipher, bool encrypt,
bool copy, bool in_place, size_t chunk_size,
bool copy, size_t chunk_size,
const std::vector<uint8_t> &key,
const std::vector<uint8_t> &iv,
const std::vector<uint8_t> &plaintext,
@@ -214,7 +207,7 @@ static void TestOperation(FileTest *t, const EVP_CIPHER *cipher, bool encrypt,
}
ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx, 0));
std::vector<uint8_t> result;
ASSERT_TRUE(DoCipher(ctx, &result, *in, chunk_size, in_place));
ASSERT_TRUE(DoCipher(ctx, &result, *in, chunk_size));
EXPECT_EQ(Bytes(*out), Bytes(result));
if (encrypt && is_aead) {
uint8_t rtag[16];
@@ -223,91 +216,6 @@ static void TestOperation(FileTest *t, const EVP_CIPHER *cipher, bool encrypt,
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag.size(), rtag));
EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size()));
}
// Additionally test low-level AES mode APIs. Skip runs where |copy| because
// it does not apply.
if (!copy) {
int nid = EVP_CIPHER_nid(cipher);
bool is_ctr = nid == NID_aes_128_ctr || nid == NID_aes_192_ctr ||
nid == NID_aes_256_ctr;
bool is_cbc = nid == NID_aes_128_cbc || nid == NID_aes_192_cbc ||
nid == NID_aes_256_cbc;
bool is_ofb = nid == NID_aes_128_ofb128 || nid == NID_aes_192_ofb128 ||
nid == NID_aes_256_ofb128;
if (is_ctr || is_cbc || is_ofb) {
AES_KEY aes;
if (encrypt || !is_cbc) {
ASSERT_EQ(0, AES_set_encrypt_key(key.data(), key.size() * 8, &aes));
} else {
ASSERT_EQ(0, AES_set_decrypt_key(key.data(), key.size() * 8, &aes));
}
// The low-level APIs all work in-place.
bssl::Span<const uint8_t> input = *in;
result.clear();
if (in_place) {
result = *in;
input = result;
} else {
result.resize(out->size());
}
bssl::Span<uint8_t> output = bssl::MakeSpan(result);
ASSERT_EQ(input.size(), output.size());
// The low-level APIs all use block-size IVs.
ASSERT_EQ(iv.size(), size_t{AES_BLOCK_SIZE});
uint8_t ivec[AES_BLOCK_SIZE];
OPENSSL_memcpy(ivec, iv.data(), iv.size());
if (is_ctr) {
unsigned num = 0;
uint8_t ecount_buf[AES_BLOCK_SIZE];
if (chunk_size == 0) {
AES_ctr128_encrypt(input.data(), output.data(), input.size(), &aes,
ivec, ecount_buf, &num);
} else {
do {
size_t todo = std::min(input.size(), chunk_size);
AES_ctr128_encrypt(input.data(), output.data(), todo, &aes, ivec,
ecount_buf, &num);
input = input.subspan(todo);
output = output.subspan(todo);
} while (!input.empty());
}
EXPECT_EQ(Bytes(*out), Bytes(result));
} else if (is_cbc && chunk_size % AES_BLOCK_SIZE == 0) {
// Note |AES_cbc_encrypt| requires block-aligned chunks.
if (chunk_size == 0) {
AES_cbc_encrypt(input.data(), output.data(), input.size(), &aes, ivec,
encrypt);
} else {
do {
size_t todo = std::min(input.size(), chunk_size);
AES_cbc_encrypt(input.data(), output.data(), todo, &aes, ivec,
encrypt);
input = input.subspan(todo);
output = output.subspan(todo);
} while (!input.empty());
}
EXPECT_EQ(Bytes(*out), Bytes(result));
} else if (is_ofb) {
int num = 0;
if (chunk_size == 0) {
AES_ofb128_encrypt(input.data(), output.data(), input.size(), &aes,
ivec, &num);
} else {
do {
size_t todo = std::min(input.size(), chunk_size);
AES_ofb128_encrypt(input.data(), output.data(), todo, &aes, ivec,
&num);
input = input.subspan(todo);
output = output.subspan(todo);
} while (!input.empty());
}
EXPECT_EQ(Bytes(*out), Bytes(result));
}
}
}
}
static void TestCipher(FileTest *t) {
@@ -349,24 +257,21 @@ static void TestCipher(FileTest *t) {
for (size_t chunk_size : chunk_sizes) {
SCOPED_TRACE(chunk_size);
for (bool copy : {false, true}) {
SCOPED_TRACE(copy);
for (bool in_place : {false, true}) {
SCOPED_TRACE(in_place);
// By default, both directions are run, unless overridden by the
// operation.
if (operation != kDecrypt) {
SCOPED_TRACE("encrypt");
TestOperation(t, cipher, true /* encrypt */, copy, in_place,
chunk_size, key, iv, plaintext, ciphertext, aad, tag);
}
// By default, both directions are run, unless overridden by the operation.
if (operation != kDecrypt) {
SCOPED_TRACE("encrypt");
TestOperation(t, cipher, true /* encrypt */, false /* no copy */,
chunk_size, key, iv, plaintext, ciphertext, aad, tag);
TestOperation(t, cipher, true /* encrypt */, true /* copy */, chunk_size,
key, iv, plaintext, ciphertext, aad, tag);
}
if (operation != kEncrypt) {
SCOPED_TRACE("decrypt");
TestOperation(t, cipher, false /* decrypt */, copy, in_place,
chunk_size, key, iv, plaintext, ciphertext, aad, tag);
}
}
if (operation != kEncrypt) {
SCOPED_TRACE("decrypt");
TestOperation(t, cipher, false /* decrypt */, false /* no copy */,
chunk_size, key, iv, plaintext, ciphertext, aad, tag);
TestOperation(t, cipher, false /* decrypt */, true /* copy */, chunk_size,
key, iv, plaintext, ciphertext, aad, tag);
}
}
}
@@ -414,63 +319,59 @@ TEST(CipherTest, CAVP_TDES_ECB) {
}
TEST(CipherTest, WycheproofAESCBC) {
FileTestGTest(
"third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("type");
t->IgnoreInstruction("ivSize");
FileTestGTest("third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("type");
t->IgnoreInstruction("ivSize");
std::string key_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
const EVP_CIPHER *cipher;
switch (atoi(key_size.c_str())) {
case 128:
cipher = EVP_aes_128_cbc();
break;
case 192:
cipher = EVP_aes_192_cbc();
break;
case 256:
cipher = EVP_aes_256_cbc();
break;
default:
FAIL() << "Unsupported key size: " << key_size;
}
std::string key_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
const EVP_CIPHER *cipher;
switch (atoi(key_size.c_str())) {
case 128:
cipher = EVP_aes_128_cbc();
break;
case 192:
cipher = EVP_aes_192_cbc();
break;
case 256:
cipher = EVP_aes_256_cbc();
break;
default:
FAIL() << "Unsupported key size: " << key_size;
}
std::vector<uint8_t> key, iv, msg, ct;
ASSERT_TRUE(t->GetBytes(&key, "key"));
ASSERT_TRUE(t->GetBytes(&iv, "iv"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
ASSERT_TRUE(t->GetBytes(&ct, "ct"));
ASSERT_EQ(EVP_CIPHER_key_length(cipher), key.size());
ASSERT_EQ(EVP_CIPHER_iv_length(cipher), iv.size());
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
std::vector<uint8_t> key, iv, msg, ct;
ASSERT_TRUE(t->GetBytes(&key, "key"));
ASSERT_TRUE(t->GetBytes(&iv, "iv"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
ASSERT_TRUE(t->GetBytes(&ct, "ct"));
ASSERT_EQ(EVP_CIPHER_key_length(cipher), key.size());
ASSERT_EQ(EVP_CIPHER_iv_length(cipher), iv.size());
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
bssl::ScopedEVP_CIPHER_CTX ctx;
std::vector<uint8_t> out;
const std::vector<size_t> chunk_sizes = {
0, 1, 2, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 512};
for (size_t chunk : chunk_sizes) {
SCOPED_TRACE(chunk);
for (bool in_place : {false, true}) {
SCOPED_TRACE(in_place);
if (result.IsValid()) {
ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr,
key.data(), iv.data()));
ASSERT_TRUE(DoCipher(ctx.get(), &out, ct, chunk, in_place));
EXPECT_EQ(Bytes(msg), Bytes(out));
bssl::ScopedEVP_CIPHER_CTX ctx;
std::vector<uint8_t> out;
const std::vector<size_t> chunk_sizes = {0, 1, 2, 5, 7, 8, 9, 15, 16,
17, 31, 32, 33, 63, 64, 65, 512};
for (size_t chunk : chunk_sizes) {
SCOPED_TRACE(chunk);
if (result == WycheproofResult::kValid) {
ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, key.data(),
iv.data()));
ASSERT_TRUE(DoCipher(ctx.get(), &out, ct, chunk));
EXPECT_EQ(Bytes(msg), Bytes(out));
ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), cipher, nullptr,
key.data(), iv.data()));
ASSERT_TRUE(DoCipher(ctx.get(), &out, msg, chunk, in_place));
EXPECT_EQ(Bytes(ct), Bytes(out));
} else {
ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr,
key.data(), iv.data()));
EXPECT_FALSE(DoCipher(ctx.get(), &out, ct, chunk, in_place));
}
}
}
});
ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), cipher, nullptr, key.data(),
iv.data()));
ASSERT_TRUE(DoCipher(ctx.get(), &out, msg, chunk));
EXPECT_EQ(Bytes(ct), Bytes(out));
} else {
ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, key.data(),
iv.data()));
EXPECT_FALSE(DoCipher(ctx.get(), &out, ct, chunk));
}
}
});
}
+1 -1
View File
@@ -86,7 +86,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
EVP_MD_CTX_init(&c);
for (;;) {
if (!EVP_DigestInit_ex(&c, md, NULL)) {
goto err;
return 0;
}
if (addmd++) {
if (!EVP_DigestUpdate(&c, md_buf, mds)) {
+12 -254
View File
@@ -1,56 +1,21 @@
/* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
/* Copyright (c) 2018, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/aead.h>
#include <assert.h>
#include <openssl/cpu.h>
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -58,213 +23,6 @@
#include "../fipsmodule/cipher/internal.h"
struct ccm128_context {
block128_f block;
ctr128_f ctr;
unsigned M, L;
};
struct ccm128_state {
union {
uint64_t u[2];
uint8_t c[16];
} nonce, cmac;
};
static int CRYPTO_ccm128_init(struct ccm128_context *ctx, const AES_KEY *key,
block128_f block, ctr128_f ctr, unsigned M,
unsigned L) {
if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) {
return 0;
}
ctx->block = block;
ctx->ctr = ctr;
ctx->M = M;
ctx->L = L;
return 1;
}
static size_t CRYPTO_ccm128_max_input(const struct ccm128_context *ctx) {
return ctx->L >= sizeof(size_t) ? (size_t)-1
: (((size_t)1) << (ctx->L * 8)) - 1;
}
static int ccm128_init_state(const struct ccm128_context *ctx,
struct ccm128_state *state, const AES_KEY *key,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *aad, size_t aad_len,
size_t plaintext_len) {
const block128_f block = ctx->block;
const unsigned M = ctx->M;
const unsigned L = ctx->L;
// |L| determines the expected |nonce_len| and the limit for |plaintext_len|.
if (plaintext_len > CRYPTO_ccm128_max_input(ctx) ||
nonce_len != 15 - L) {
return 0;
}
// Assemble the first block for computing the MAC.
OPENSSL_memset(state, 0, sizeof(*state));
state->nonce.c[0] = (uint8_t)((L - 1) | ((M - 2) / 2) << 3);
if (aad_len != 0) {
state->nonce.c[0] |= 0x40; // Set AAD Flag
}
OPENSSL_memcpy(&state->nonce.c[1], nonce, nonce_len);
for (unsigned i = 0; i < L; i++) {
state->nonce.c[15 - i] = (uint8_t)(plaintext_len >> (8 * i));
}
(*block)(state->nonce.c, state->cmac.c, key);
size_t blocks = 1;
if (aad_len != 0) {
unsigned i;
// Cast to u64 to avoid the compiler complaining about invalid shifts.
uint64_t aad_len_u64 = aad_len;
if (aad_len_u64 < 0x10000 - 0x100) {
state->cmac.c[0] ^= (uint8_t)(aad_len_u64 >> 8);
state->cmac.c[1] ^= (uint8_t)aad_len_u64;
i = 2;
} else if (aad_len_u64 <= 0xffffffff) {
state->cmac.c[0] ^= 0xff;
state->cmac.c[1] ^= 0xfe;
state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 24);
state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 16);
state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 8);
state->cmac.c[5] ^= (uint8_t)aad_len_u64;
i = 6;
} else {
state->cmac.c[0] ^= 0xff;
state->cmac.c[1] ^= 0xff;
state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 56);
state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 48);
state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 40);
state->cmac.c[5] ^= (uint8_t)(aad_len_u64 >> 32);
state->cmac.c[6] ^= (uint8_t)(aad_len_u64 >> 24);
state->cmac.c[7] ^= (uint8_t)(aad_len_u64 >> 16);
state->cmac.c[8] ^= (uint8_t)(aad_len_u64 >> 8);
state->cmac.c[9] ^= (uint8_t)aad_len_u64;
i = 10;
}
do {
for (; i < 16 && aad_len != 0; i++) {
state->cmac.c[i] ^= *aad;
aad++;
aad_len--;
}
(*block)(state->cmac.c, state->cmac.c, key);
blocks++;
i = 0;
} while (aad_len != 0);
}
// Per RFC 3610, section 2.6, the total number of block cipher operations done
// must not exceed 2^61. There are two block cipher operations remaining per
// message block, plus one block at the end to encrypt the MAC.
size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1;
if (plaintext_len + 15 < plaintext_len ||
remaining_blocks + blocks < blocks ||
(uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) {
return 0;
}
// Assemble the first block for encrypting and decrypting. The bottom |L|
// bytes are replaced with a counter and all bit the encoding of |L| is
// cleared in the first byte.
state->nonce.c[0] &= 7;
return 1;
}
static int ccm128_encrypt(const struct ccm128_context *ctx,
struct ccm128_state *state, const AES_KEY *key,
uint8_t *out, const uint8_t *in, size_t len) {
// The counter for encryption begins at one.
for (unsigned i = 0; i < ctx->L; i++) {
state->nonce.c[15 - i] = 0;
}
state->nonce.c[15] = 1;
uint8_t partial_buf[16];
unsigned num = 0;
if (ctx->ctr != NULL) {
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf,
&num, ctx->ctr);
} else {
CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num,
ctx->block);
}
return 1;
}
static int ccm128_compute_mac(const struct ccm128_context *ctx,
struct ccm128_state *state, const AES_KEY *key,
uint8_t *out_tag, size_t tag_len,
const uint8_t *in, size_t len) {
block128_f block = ctx->block;
if (tag_len != ctx->M) {
return 0;
}
// Incorporate |in| into the MAC.
union {
uint64_t u[2];
uint8_t c[16];
} tmp;
while (len >= 16) {
OPENSSL_memcpy(tmp.c, in, 16);
state->cmac.u[0] ^= tmp.u[0];
state->cmac.u[1] ^= tmp.u[1];
(*block)(state->cmac.c, state->cmac.c, key);
in += 16;
len -= 16;
}
if (len > 0) {
for (size_t i = 0; i < len; i++) {
state->cmac.c[i] ^= in[i];
}
(*block)(state->cmac.c, state->cmac.c, key);
}
// Encrypt the MAC with counter zero.
for (unsigned i = 0; i < ctx->L; i++) {
state->nonce.c[15 - i] = 0;
}
(*block)(state->nonce.c, tmp.c, key);
state->cmac.u[0] ^= tmp.u[0];
state->cmac.u[1] ^= tmp.u[1];
OPENSSL_memcpy(out_tag, state->cmac.c, tag_len);
return 1;
}
static int CRYPTO_ccm128_encrypt(const struct ccm128_context *ctx,
const AES_KEY *key, uint8_t *out,
uint8_t *out_tag, size_t tag_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t len,
const uint8_t *aad, size_t aad_len) {
struct ccm128_state state;
return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
len) &&
ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) &&
ccm128_encrypt(ctx, &state, key, out, in, len);
}
static int CRYPTO_ccm128_decrypt(const struct ccm128_context *ctx,
const AES_KEY *key, uint8_t *out,
uint8_t *out_tag, size_t tag_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t len,
const uint8_t *aad, size_t aad_len) {
struct ccm128_state state;
return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len,
len) &&
ccm128_encrypt(ctx, &state, key, out, in, len) &&
ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len);
}
#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16
struct aead_aes_ccm_ctx {
@@ -272,7 +30,7 @@ struct aead_aes_ccm_ctx {
double align;
AES_KEY ks;
} ks;
struct ccm128_context ccm;
CCM128_CONTEXT ccm;
};
OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
-8
View File
@@ -723,14 +723,6 @@ static void gcm_siv_keys(
}
OPENSSL_memcpy(out_keys->auth_key, key_material, 16);
// Note the |ctr128_f| function uses a big-endian couner, while AES-GCM-SIV
// uses a little-endian counter. We ignore the return value and only use
// |block128_f|. This has a significant performance cost for the fallback
// bitsliced AES implementations (bsaes and aes_nohw).
//
// We currently do not consider AES-GCM-SIV to be performance-sensitive on
// client hardware. If this changes, we can write little-endian |ctr128_f|
// functions.
aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block,
key_material + 16, gcm_siv_ctx->is_256 ? 32 : 16);
}
@@ -1,43 +0,0 @@
# Test vectors from NIST: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
KEY: 000000000000000000000000000000000000000000000000
NONCE: 000000000000000000000000
AD:
TAG: cd33b28ac773f74ba00ed1f312572435
IN:
CT:
KEY: 000000000000000000000000000000000000000000000000
NONCE: 000000000000000000000000
AD:
TAG: 2ff58d80033927ab8ef4d4587514f0fb
IN: 00000000000000000000000000000000
CT: 98e7247c07f0fe411c267e4384b0f600
KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c
NONCE: cafebabefacedbaddecaf888
AD:
TAG: 9924a7c8587336bfb118024db8674a14
IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
CT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256
KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c
NONCE: cafebabefacedbaddecaf888
AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
TAG: 2519498e80f1478f37ba55bd6d27618c
IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
CT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710
KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c
NONCE: cafebabefacedbad
AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
TAG: 65dcc57fcf623a24094fcca40d3533f8
IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
CT: 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7
KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c
NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
TAG: dcf566ff291c25bbb8568fc3d376a6d9
IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
CT: d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b
-1
View File
@@ -133,7 +133,6 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in,
assert(orig_len >= in_len);
assert(in_len >= md_size);
assert(md_size <= EVP_MAX_MD_SIZE);
assert(md_size > 0);
// scan_start contains the number of bytes that we can ignore because
// the MAC's position can only vary by 255 bytes.
+2 -2
View File
@@ -148,7 +148,7 @@ TEST(CMACTest, Wycheproof) {
// Some test vectors intentionally give the wrong key size. Our API
// requires the caller pick the sized CBC primitive, so these tests
// aren't useful for us.
EXPECT_FALSE(result.IsValid());
EXPECT_EQ(WycheproofResult::kInvalid, result);
return;
}
@@ -164,7 +164,7 @@ TEST(CMACTest, Wycheproof) {
// Truncate the tag, if requested.
out_len = std::min(out_len, tag_len);
if (result.IsValid()) {
if (result == WycheproofResult::kValid) {
EXPECT_EQ(Bytes(tag), Bytes(out, out_len));
// Test the streaming API as well.
+6 -7
View File
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <openssl/arm_arch.h>
#include <openssl/buf.h>
#include <openssl/mem.h>
#include "cpu-arm-linux.h"
@@ -146,13 +147,11 @@ extern uint32_t OPENSSL_armcap_P;
static int g_has_broken_neon, g_needs_hwcap2_workaround;
void OPENSSL_cpuid_setup(void) {
// We ignore the return value of |read_file| and proceed with an empty
// /proc/cpuinfo on error. If |getauxval| works, we will still detect
// capabilities. There may be a false positive due to
// |crypto_cpuinfo_has_broken_neon|, but this is now rare.
char *cpuinfo_data = NULL;
size_t cpuinfo_len = 0;
read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo");
char *cpuinfo_data;
size_t cpuinfo_len;
if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) {
return;
}
STRING_PIECE cpuinfo;
cpuinfo.data = cpuinfo_data;
cpuinfo.len = cpuinfo_len;
-7
View File
@@ -220,13 +220,6 @@ TEST(ARMLinuxTest, CPUInfo) {
0,
false,
},
// If opening /proc/cpuinfo fails, we process the empty string.
{
"",
0,
0,
false,
},
};
for (const auto &t : kTests) {
+5 -28
View File
@@ -123,28 +123,15 @@ static uint64_t OPENSSL_xgetbv(uint32_t xcr) {
// and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this.
static void handle_cpu_env(uint32_t *out, const char *in) {
const int invert = in[0] == '~';
const int or = in[0] == '|';
const int skip_first_byte = invert || or;
const int hex = in[skip_first_byte] == '0' && in[skip_first_byte+1] == 'x';
int sscanf_result;
uint64_t v;
if (hex) {
sscanf_result = sscanf(in + invert + 2, "%" PRIx64, &v);
} else {
sscanf_result = sscanf(in + invert, "%" PRIu64, &v);
}
if (!sscanf_result) {
if (!sscanf(in + invert, "%" PRIu64, &v)) {
return;
}
if (invert) {
out[0] &= ~v;
out[1] &= ~(v >> 32);
} else if (or) {
out[0] |= v;
out[1] |= (v >> 32);
} else {
out[0] = v;
out[1] = v >> 32;
@@ -177,23 +164,17 @@ void OPENSSL_cpuid_setup(void) {
if (is_amd) {
// See https://www.amd.com/system/files/TechDocs/25481.pdf, page 10.
const uint32_t base_family = (eax >> 8) & 15;
const uint32_t base_model = (eax >> 4) & 15;
uint32_t family = base_family;
uint32_t model = base_model;
if (base_family == 0xf) {
const uint32_t ext_family = (eax >> 20) & 255;
family += ext_family;
const uint32_t ext_model = (eax >> 16) & 15;
model |= ext_model << 4;
}
if (family < 0x17 || (family == 0x17 && 0x70 <= model && model <= 0x7f)) {
if (family < 0x17) {
// Disable RDRAND on AMD families before 0x17 (Zen) due to reported
// failures after suspend.
// https://bugzilla.redhat.com/show_bug.cgi?id=1150286
// Also disable for family 0x17, models 0x700x7f, due to possible RDRAND
// failures there too.
ecx &= ~(1u << 30);
}
}
@@ -269,14 +250,10 @@ void OPENSSL_cpuid_setup(void) {
// OPENSSL_ia32cap can contain zero, one or two values, separated with a ':'.
// Each value is a 64-bit, unsigned value which may start with "0x" to
// indicate a hex value. Prior to the 64-bit value, a '~' or '|' may be given.
// indicate a hex value. Prior to the 64-bit value, a '~' may be given.
//
// If the '~' prefix is present:
// the value is inverted and ANDed with the probed CPUID result
// If the '|' prefix is present:
// the value is ORed with the probed CPUID result
// Otherwise:
// the value is taken as the result of the CPUID
// If '~' isn't present, then the value is taken as the result of the CPUID.
// Otherwise the value is inverted and ANDed with the probed CPUID result.
//
// The first value determines OPENSSL_ia32cap_P[0] and [1]. The second [2]
// and [3].
+1 -12
View File
@@ -16,8 +16,6 @@
#include <openssl/cpu.h>
#include "fipsmodule/rand/fork_detect.h"
#include "fipsmodule/rand/internal.h"
#include "internal.h"
@@ -62,7 +60,7 @@
// that tests the capability values will still skip the constructor but, so
// far, the init constructor function only sets the capability variables.
#if defined(BORINGSSL_DISPATCH_TEST)
#if !defined(NDEBUG) && !defined(BORINGSSL_FIPS)
// This value must be explicitly initialised to zero in order to work around a
// bug in libtool or the linker on OS X.
//
@@ -176,15 +174,6 @@ int CRYPTO_has_asm(void) {
#endif
}
void CRYPTO_pre_sandbox_init(void) {
// Read from /proc/cpuinfo if needed.
CRYPTO_library_init();
// Open /dev/urandom if needed.
CRYPTO_init_sysrand();
// Set up MADV_WIPEONFORK state if needed.
CRYPTO_get_fork_generation();
}
const char *SSLeay_version(int which) { return OpenSSL_version(which); }
const char *OpenSSL_version(int which) {
-4
View File
@@ -2130,7 +2130,3 @@ vpop {q4,q5,q6,q7}
bx lr
#endif /* !OPENSSL_NO_ASM && __arm__ && !__APPLE__ */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
+1 -1
View File
@@ -23,7 +23,7 @@
#include <openssl/sha.h>
#include "../internal.h"
#include "./internal.h"
#include "../../third_party/fiat/internal.h"
// The following precomputation tables are for the following
+1 -1
View File
@@ -23,7 +23,7 @@
#include <gtest/gtest.h>
#include "../internal.h"
#include "./internal.h"
#include "../../third_party/fiat/internal.h"
// TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down.
+6 -5
View File
@@ -23,7 +23,6 @@
#include "../internal.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"
TEST(X25519Test, TestVector) {
@@ -133,8 +132,11 @@ TEST(X25519Test, Wycheproof) {
t->IgnoreInstruction("curve");
t->IgnoreAttribute("curve");
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
// Our implementation tolerates the Wycheproof "acceptable"
// inputs. Wycheproof's valid vs. acceptable criteria does not match our
// X25519 return value, so we test only the overall output.
t->IgnoreAttribute("result");
std::vector<uint8_t> priv, pub, shared;
ASSERT_TRUE(t->GetBytes(&priv, "private"));
ASSERT_TRUE(t->GetBytes(&pub, "public"));
@@ -142,8 +144,7 @@ TEST(X25519Test, Wycheproof) {
ASSERT_EQ(32u, priv.size());
ASSERT_EQ(32u, pub.size());
uint8_t secret[32];
int ret = X25519(secret, priv.data(), pub.data());
EXPECT_EQ(ret, result.IsValid({"NonCanonicalPublic", "Twist"}) ? 1 : 0);
X25519(secret, priv.data(), pub.data());
EXPECT_EQ(Bytes(secret), Bytes(shared));
});
}
+3 -3
View File
@@ -151,7 +151,7 @@ int DH_check(const DH *dh, int *out_flags) {
*out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
}
}
r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, ctx, NULL);
r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
if (r < 0) {
goto err;
}
@@ -188,7 +188,7 @@ int DH_check(const DH *dh, int *out_flags) {
*out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
}
r = BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, ctx, NULL);
r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
if (r < 0) {
goto err;
}
@@ -198,7 +198,7 @@ int DH_check(const DH *dh, int *out_flags) {
if (!BN_rshift1(t1, dh->p)) {
goto err;
}
r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx, NULL);
r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
if (r < 0) {
goto err;
}
+2 -16
View File
@@ -59,6 +59,7 @@
#include <string.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/ex_data.h>
#include <openssl/mem.h>
@@ -113,16 +114,6 @@ void DH_free(DH *dh) {
OPENSSL_free(dh);
}
const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; }
const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; }
const BIGNUM *DH_get0_p(const DH *dh) { return dh->p; }
const BIGNUM *DH_get0_q(const DH *dh) { return dh->q; }
const BIGNUM *DH_get0_g(const DH *dh) { return dh->g; }
void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key,
const BIGNUM **out_priv_key) {
if (out_pub_key != NULL) {
@@ -184,11 +175,6 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
return 1;
}
int DH_set_length(DH *dh, unsigned priv_length) {
dh->priv_length = priv_length;
return 1;
}
int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) {
// We generate DH parameters as follows
// find a prime q which is prime_bits/2 bits long.
@@ -490,7 +476,7 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942) {
to->seedlen = 0;
if (from->seed) {
to->seed = OPENSSL_memdup(from->seed, from->seedlen);
to->seed = BUF_memdup(from->seed, from->seedlen);
if (!to->seed) {
return 0;
}
+69 -64
View File
@@ -53,7 +53,6 @@ static const MD sha224 = { "SHA224", &EVP_sha224, &SHA224 };
static const MD sha256 = { "SHA256", &EVP_sha256, &SHA256 };
static const MD sha384 = { "SHA384", &EVP_sha384, &SHA384 };
static const MD sha512 = { "SHA512", &EVP_sha512, &SHA512 };
static const MD sha512_256 = { "SHA512-256", &EVP_sha512_256, &SHA512_256 };
static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr };
struct DigestTestVector {
@@ -70,88 +69,94 @@ struct DigestTestVector {
static const DigestTestVector kTestVectors[] = {
// MD4 tests, from RFC 1320. (crypto/md4 does not provide a
// one-shot MD4 function.)
{md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0"},
{md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24"},
{md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d"},
{md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b"},
{md4, "abcdefghijklmnopqrstuvwxyz", 1, "d79e1c308aa5bbcdeea8ed63df412da9"},
{md4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"043f8582f241db351ce627e153e7f0e4"},
{md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536"},
{ md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0" },
{ md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24" },
{ md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d" },
{ md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b" },
{ md4, "abcdefghijklmnopqrstuvwxyz", 1,
"d79e1c308aa5bbcdeea8ed63df412da9" },
{ md4,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"043f8582f241db351ce627e153e7f0e4" },
{ md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536" },
// MD5 tests, from RFC 1321.
{md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e"},
{md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661"},
{md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72"},
{md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0"},
{md5, "abcdefghijklmnopqrstuvwxyz", 1, "c3fcd3d76192e4007dfb496cca67e13b"},
{md5, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"d174ab98d277d9f5a5611c2c9f419d9f"},
{md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a"},
{ md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e" },
{ md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661" },
{ md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72" },
{ md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" },
{ md5, "abcdefghijklmnopqrstuvwxyz", 1,
"c3fcd3d76192e4007dfb496cca67e13b" },
{ md5,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a" },
// SHA-1 tests, from RFC 3174.
{sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d"},
{sha1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"84983e441c3bd26ebaae4aa1f95129e5e54670f1"},
{sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"},
{sha1, "0123456701234567012345670123456701234567012345670123456701234567",
10, "dea356a2cddd90c7a7ecedc5ebb563934f460452"},
{ sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d" },
{ sha1,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
{ sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f" },
{ sha1,
"0123456701234567012345670123456701234567012345670123456701234567", 10,
"dea356a2cddd90c7a7ecedc5ebb563934f460452" },
// SHA-224 tests, from RFC 3874.
{sha224, "abc", 1,
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"},
{sha224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"},
{sha224, "a", 1000000,
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"},
{ sha224, "abc", 1,
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" },
{ sha224,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" },
{ sha224,
"a", 1000000,
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" },
// SHA-256 tests, from NIST.
{sha256, "abc", 1,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"},
{sha256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"},
{ sha256, "abc", 1,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
{ sha256,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
// SHA-384 tests, from NIST.
{sha384, "abc", 1,
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7"},
{sha384,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1,
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039"},
{ sha384, "abc", 1,
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7" },
{ sha384,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039" },
// SHA-512 tests, from NIST.
{sha512, "abc", 1,
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"},
{sha512,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"},
// SHA-512-256 tests, from
// https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha512_256.pdf
{sha512_256, "abc", 1,
"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"},
{sha512_256,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopj"
"klmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
1, "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"},
{ sha512, "abc", 1,
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
{ sha512,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
// MD5-SHA1 tests.
{md5_sha1, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d"},
{ md5_sha1, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
};
static void CompareDigest(const DigestTestVector *test,
const uint8_t *digest,
size_t digest_len) {
EXPECT_EQ(test->expected_hex,
EncodeHex(bssl::MakeConstSpan(digest, digest_len)));
static const char kHexTable[] = "0123456789abcdef";
char digest_hex[2*EVP_MAX_MD_SIZE + 1];
for (size_t i = 0; i < digest_len; i++) {
digest_hex[2*i] = kHexTable[digest[i] >> 4];
digest_hex[2*i + 1] = kHexTable[digest[i] & 0xf];
}
digest_hex[2*digest_len] = '\0';
EXPECT_STREQ(test->expected_hex, digest_hex);
}
static void TestDigest(const DigestTestVector *test) {
+3 -13
View File
@@ -79,7 +79,7 @@
#define OPENSSL_DSA_MAX_MODULUS_BITS 10000
// Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
// Miller-Rabin.
// Rabin-Miller
#define DSS_prime_checks 50
static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
@@ -131,16 +131,6 @@ int DSA_up_ref(DSA *dsa) {
return 1;
}
const BIGNUM *DSA_get0_pub_key(const DSA *dsa) { return dsa->pub_key; }
const BIGNUM *DSA_get0_priv_key(const DSA *dsa) { return dsa->priv_key; }
const BIGNUM *DSA_get0_p(const DSA *dsa) { return dsa->p; }
const BIGNUM *DSA_get0_q(const DSA *dsa) { return dsa->q; }
const BIGNUM *DSA_get0_g(const DSA *dsa) { return dsa->g; }
void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key,
const BIGNUM **out_priv_key) {
if (out_pub_key != NULL) {
@@ -266,7 +256,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
// Find q.
for (;;) {
// step 1
if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, m++)) {
if (!BN_GENCB_call(cb, 0, m++)) {
goto err;
}
@@ -329,7 +319,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
n = (bits - 1) / 160;
for (;;) {
if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) {
if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
goto err;
}
+6 -18
View File
@@ -264,8 +264,7 @@ static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
CBS *out_base_y, CBS *out_order) {
// See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an
// ECParameters while RFC 5480 calls it a SpecifiedECDomain.
CBS params, field_id, field_type, curve, base, cofactor;
int has_cofactor;
CBS params, field_id, field_type, curve, base;
uint64_t version;
if (!CBS_get_asn1(in, &params, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1_uint64(&params, &version) ||
@@ -273,8 +272,7 @@ static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
!CBS_get_asn1(&params, &field_id, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
CBS_len(&field_type) != sizeof(kPrimeField) ||
OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) !=
0 ||
OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 ||
!CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) ||
!is_unsigned_integer(out_prime) ||
CBS_len(&field_id) != 0 ||
@@ -282,26 +280,16 @@ static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
!CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) ||
// |curve| has an optional BIT STRING seed which we ignore.
!CBS_get_optional_asn1(&curve, NULL, NULL, CBS_ASN1_BITSTRING) ||
CBS_len(&curve) != 0 ||
!CBS_get_asn1(&params, &base, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&params, out_order, CBS_ASN1_INTEGER) ||
!is_unsigned_integer(out_order) ||
!CBS_get_optional_asn1(&params, &cofactor, &has_cofactor,
CBS_ASN1_INTEGER) ||
CBS_len(&params) != 0) {
!is_unsigned_integer(out_order)) {
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
return 0;
}
if (has_cofactor) {
// We only support prime-order curves so the cofactor must be one.
if (CBS_len(&cofactor) != 1 ||
CBS_data(&cofactor)[0] != 1) {
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return 0;
}
}
// |params| has an optional cofactor which we ignore. With the optional seed
// in |curve|, a group already has arbitrarily many encodings. Parse enough to
// uniquely determine the curve.
// Require that the base point use uncompressed form.
uint8_t form;
-95
View File
@@ -1,95 +0,0 @@
/* Copyright (c) 2019, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/ec_key.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/digest.h>
#include <openssl/hkdf.h>
#include <openssl/mem.h>
#include "../fipsmodule/ec/internal.h"
EC_KEY *EC_KEY_derive_from_secret(const EC_GROUP *group, const uint8_t *secret,
size_t secret_len) {
#define EC_KEY_DERIVE_MAX_NAME_LEN 16
const char *name = EC_curve_nid2nist(EC_GROUP_get_curve_name(group));
if (name == NULL || strlen(name) > EC_KEY_DERIVE_MAX_NAME_LEN) {
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return NULL;
}
// Assemble a label string to provide some key separation in case |secret| is
// misused, but ultimately it's on the caller to ensure |secret| is suitably
// separated.
static const char kLabel[] = "derive EC key ";
char info[sizeof(kLabel) + EC_KEY_DERIVE_MAX_NAME_LEN];
OPENSSL_strlcpy(info, kLabel, sizeof(info));
OPENSSL_strlcat(info, name, sizeof(info));
// Generate 128 bits beyond the group order so the bias is at most 2^-128.
#define EC_KEY_DERIVE_EXTRA_BITS 128
#define EC_KEY_DERIVE_EXTRA_BYTES (EC_KEY_DERIVE_EXTRA_BITS / 8)
if (EC_GROUP_order_bits(group) <= EC_KEY_DERIVE_EXTRA_BITS + 8) {
// The reduction strategy below requires the group order be large enough.
// (The actual bound is a bit tighter, but our curves are much larger than
// 128-bit.)
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
return NULL;
}
uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES];
size_t derived_len = BN_num_bytes(&group->order) + EC_KEY_DERIVE_EXTRA_BYTES;
assert(derived_len <= sizeof(derived));
if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len,
/*salt=*/NULL, /*salt_len=*/0, (const uint8_t *)info,
strlen(info))) {
return NULL;
}
EC_KEY *key = EC_KEY_new();
BN_CTX *ctx = BN_CTX_new();
BIGNUM *priv = BN_bin2bn(derived, derived_len, NULL);
EC_POINT *pub = EC_POINT_new(group);
if (key == NULL || ctx == NULL || priv == NULL || pub == NULL ||
// Reduce |priv| with Montgomery reduction. First, convert "from"
// Montgomery form to compute |priv| * R^-1 mod |order|. This requires
// |priv| be under order * R, which is true if the group order is large
// enough. 2^(num_bytes(order)) < 2^8 * order, so:
//
// priv < 2^8 * order * 2^128 < order * order < order * R
!BN_from_montgomery(priv, priv, group->order_mont, ctx) ||
// Multiply by R^2 and do another Montgomery reduction to compute
// priv * R^-1 * R^2 * R^-1 = priv mod order.
!BN_to_montgomery(priv, priv, group->order_mont, ctx) ||
!EC_POINT_mul(group, pub, priv, NULL, NULL, ctx) ||
!EC_KEY_set_group(key, group) || !EC_KEY_set_public_key(key, pub) ||
!EC_KEY_set_private_key(key, priv)) {
EC_KEY_free(key);
key = NULL;
goto err;
}
err:
OPENSSL_cleanse(derived, sizeof(derived));
BN_CTX_free(ctx);
BN_free(priv);
EC_POINT_free(pub);
return key;
}
-385
View File
@@ -1,385 +0,0 @@
/* Copyright (c) 2020, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/ec.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/nid.h>
#include <openssl/type_check.h>
#include <assert.h>
#include "internal.h"
#include "../fipsmodule/bn/internal.h"
#include "../fipsmodule/ec/internal.h"
#include "../internal.h"
// This file implements hash-to-curve, as described in
// draft-irtf-cfrg-hash-to-curve-07.
//
// This hash-to-curve implementation is written generically with the
// expectation that we will eventually wish to support other curves. If it
// becomes a performance bottleneck, some possible optimizations by
// specializing it to the curve:
//
// - Rather than using a generic |felem_exp|, specialize the exponentation to
// c2 with a faster addition chain.
//
// - |felem_mul| and |felem_sqr| are indirect calls to generic Montgomery
// code. Given the few curves, we could specialize
// |map_to_curve_simple_swu|. But doing this reasonably without duplicating
// code in C is difficult. (C++ templates would be useful here.)
//
// - P-521's Z and c2 have small power-of-two absolute values. We could save
// two multiplications in SSWU. (Other curves have reasonable values of Z
// and inconvenient c2.) This is unlikely to be worthwhile without C++
// templates to make specializing more convenient.
// expand_message_xmd implements the operation described in section 5.3.1 of
// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on
// allocation failure or if |out_len| was too large.
static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len,
const uint8_t *msg, size_t msg_len,
const uint8_t *dst, size_t dst_len) {
int ret = 0;
const size_t block_size = EVP_MD_block_size(md);
const size_t md_size = EVP_MD_size(md);
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
// Long DSTs are hashed down to size. See section 5.3.3.
OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, "hashed DST still too large");
uint8_t dst_buf[EVP_MAX_MD_SIZE];
if (dst_len >= 256) {
static const char kPrefix[] = "H2C-OVERSIZE-DST-";
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
!EVP_DigestUpdate(&ctx, kPrefix, sizeof(kPrefix) - 1) ||
!EVP_DigestUpdate(&ctx, dst, dst_len) ||
!EVP_DigestFinal_ex(&ctx, dst_buf, NULL)) {
goto err;
}
dst = dst_buf;
dst_len = md_size;
}
uint8_t dst_len_u8 = (uint8_t)dst_len;
// Compute b_0.
static const uint8_t kZeros[EVP_MAX_MD_BLOCK_SIZE] = {0};
// If |out_len| exceeds 16 bits then |i| will wrap below causing an error to
// be returned. This depends on the static assert above.
uint8_t l_i_b_str_zero[3] = {out_len >> 8, out_len, 0};
uint8_t b_0[EVP_MAX_MD_SIZE];
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
!EVP_DigestUpdate(&ctx, kZeros, block_size) ||
!EVP_DigestUpdate(&ctx, msg, msg_len) ||
!EVP_DigestUpdate(&ctx, l_i_b_str_zero, sizeof(l_i_b_str_zero)) ||
!EVP_DigestUpdate(&ctx, dst, dst_len) ||
!EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
!EVP_DigestFinal_ex(&ctx, b_0, NULL)) {
goto err;
}
uint8_t b_i[EVP_MAX_MD_SIZE];
uint8_t i = 1;
while (out_len > 0) {
if (i == 0) {
// Input was too large.
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
if (i > 1) {
for (size_t j = 0; j < md_size; j++) {
b_i[j] ^= b_0[j];
}
} else {
OPENSSL_memcpy(b_i, b_0, md_size);
}
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
!EVP_DigestUpdate(&ctx, b_i, md_size) ||
!EVP_DigestUpdate(&ctx, &i, 1) ||
!EVP_DigestUpdate(&ctx, dst, dst_len) ||
!EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
!EVP_DigestFinal_ex(&ctx, b_i, NULL)) {
goto err;
}
size_t todo = out_len >= md_size ? md_size : out_len;
OPENSSL_memcpy(out, b_i, todo);
out += todo;
out_len -= todo;
i++;
}
ret = 1;
err:
EVP_MD_CTX_cleanup(&ctx);
return ret;
}
// num_bytes_to_derive determines the number of bytes to derive when hashing to
// a number modulo |modulus|. See the hash_to_field operation defined in
// section 5.2 of draft-irtf-cfrg-hash-to-curve-07.
static int num_bytes_to_derive(size_t *out, const BIGNUM *modulus, unsigned k) {
size_t bits = BN_num_bits(modulus);
size_t L = (bits + k + 7) / 8;
// We require 2^(8*L) < 2^(2*bits - 2) <= n^2 so to fit in bounds for
// |felem_reduce| and |ec_scalar_reduce|. All defined hash-to-curve suites
// define |k| to be well under this bound. (|k| is usually around half of
// |p_bits|.)
if (L * 8 >= 2 * bits - 2 ||
L > 2 * EC_MAX_BYTES) {
assert(0);
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
return 0;
}
*out = L;
return 1;
}
// big_endian_to_words decodes |in| as a big-endian integer and writes the
// result to |out|. |num_words| must be large enough to contain the output.
static void big_endian_to_words(BN_ULONG *out, size_t num_words,
const uint8_t *in, size_t len) {
assert(len <= num_words * sizeof(BN_ULONG));
// Ensure any excess bytes are zeroed.
OPENSSL_memset(out, 0, num_words * sizeof(BN_ULONG));
uint8_t *out_u8 = (uint8_t *)out;
for (size_t i = 0; i < len; i++) {
out_u8[len - 1 - i] = in[i];
}
}
// hash_to_field implements the operation described in section 5.2
// of draft-irtf-cfrg-hash-to-curve-07, with count = 2. |k| is the security
// factor.
static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md,
EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst,
size_t dst_len, unsigned k, const uint8_t *msg,
size_t msg_len) {
size_t L;
uint8_t buf[4 * EC_MAX_BYTES];
if (!num_bytes_to_derive(&L, &group->field, k) ||
!expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) {
return 0;
}
BN_ULONG words[2 * EC_MAX_WORDS];
size_t num_words = 2 * group->field.width;
big_endian_to_words(words, num_words, buf, L);
group->meth->felem_reduce(group, out1, words, num_words);
big_endian_to_words(words, num_words, buf + L, L);
group->meth->felem_reduce(group, out2, words, num_words);
return 1;
}
// hash_to_scalar behaves like |hash_to_field2| but returns a value modulo the
// group order rather than a field element. |k| is the security factor.
static int hash_to_scalar(const EC_GROUP *group, const EVP_MD *md,
EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
unsigned k, const uint8_t *msg, size_t msg_len) {
size_t L;
uint8_t buf[EC_MAX_BYTES * 2];
if (!num_bytes_to_derive(&L, &group->order, k) ||
!expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) {
return 0;
}
BN_ULONG words[2 * EC_MAX_WORDS];
size_t num_words = 2 * group->order.width;
big_endian_to_words(words, num_words, buf, L);
ec_scalar_reduce(group, out, words, num_words);
return 1;
}
static inline void mul_A(const EC_GROUP *group, EC_FELEM *out,
const EC_FELEM *in) {
assert(group->a_is_minus3);
EC_FELEM tmp;
ec_felem_add(group, &tmp, in, in); // tmp = 2*in
ec_felem_add(group, &tmp, &tmp, &tmp); // tmp = 4*in
ec_felem_sub(group, out, in, &tmp); // out = -3*in
}
static inline void mul_minus_A(const EC_GROUP *group, EC_FELEM *out,
const EC_FELEM *in) {
assert(group->a_is_minus3);
EC_FELEM tmp;
ec_felem_add(group, &tmp, in, in); // tmp = 2*in
ec_felem_add(group, out, &tmp, in); // out = 3*in
}
// sgn0_le implements the operation described in section 4.1.2 of
// draft-irtf-cfrg-hash-to-curve-07.
static BN_ULONG sgn0_le(const EC_GROUP *group, const EC_FELEM *a) {
uint8_t buf[EC_MAX_BYTES];
size_t len;
ec_felem_to_bytes(group, buf, &len, a);
return buf[len - 1] & 1;
}
// map_to_curve_simple_swu implements the operation described in section 6.6.2
// of draft-irtf-cfrg-hash-to-curve-07, using the optimization in appendix
// D.2.1. It returns one on success and zero on error.
static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z,
const BN_ULONG *c1, size_t num_c1,
const EC_FELEM *c2, EC_RAW_POINT *out,
const EC_FELEM *u) {
void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
const EC_FELEM *b) = group->meth->felem_mul;
void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
group->meth->felem_sqr;
// This function requires the prime be 3 mod 4, and that A = -3.
if (group->field.width == 0 || (group->field.d[0] & 3) != 3 ||
!group->a_is_minus3) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
return 0;
}
EC_FELEM tv1, tv2, tv3, tv4, xd, x1n, x2n, tmp, gxd, gx1, y1, y2;
felem_sqr(group, &tv1, u); // tv1 = u^2
felem_mul(group, &tv3, Z, &tv1); // tv3 = Z * tv1
felem_sqr(group, &tv2, &tv3); // tv2 = tv3^2
ec_felem_add(group, &xd, &tv2, &tv3); // xd = tv2 + tv3
ec_felem_add(group, &x1n, &xd, &group->one); // x1n = xd + 1
felem_mul(group, &x1n, &x1n, &group->b); // x1n = x1n * B
mul_minus_A(group, &xd, &xd); // xd = -A * xd
BN_ULONG e1 = ec_felem_non_zero_mask(group, &xd); // e1 = xd == 0 [flipped]
mul_A(group, &tmp, Z);
ec_felem_select(group, &xd, e1, &xd, &tmp); // xd = CMOV(xd, Z * A, e1)
felem_sqr(group, &tv2, &xd); // tv2 = xd^2
felem_mul(group, &gxd, &tv2, &xd); // gxd = tv2 * xd = xd^3
mul_A(group, &tv2, &tv2); // tv2 = A * tv2
felem_sqr(group, &gx1, &x1n); // gx1 = x1n^2
ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2
felem_mul(group, &gx1, &gx1, &x1n); // gx1 = gx1 * x1n
felem_mul(group, &tv2, &group->b, &gxd); // tv2 = B * gxd
ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2
felem_sqr(group, &tv4, &gxd); // tv4 = gxd^2
felem_mul(group, &tv2, &gx1, &gxd); // tv2 = gx1 * gxd
felem_mul(group, &tv4, &tv4, &tv2); // tv4 = tv4 * tv2
group->meth->felem_exp(group, &y1, &tv4, c1, num_c1); // y1 = tv4^c1
felem_mul(group, &y1, &y1, &tv2); // y1 = y1 * tv2
felem_mul(group, &x2n, &tv3, &x1n); // x2n = tv3 * x1n
felem_mul(group, &y2, &y1, c2); // y2 = y1 * c2
felem_mul(group, &y2, &y2, &tv1); // y2 = y2 * tv1
felem_mul(group, &y2, &y2, u); // y2 = y2 * u
felem_sqr(group, &tv2, &y1); // tv2 = y1^2
felem_mul(group, &tv2, &tv2, &gxd); // tv2 = tv2 * gxd
ec_felem_sub(group, &tv3, &tv2, &gx1);
BN_ULONG e2 =
ec_felem_non_zero_mask(group, &tv3); // e2 = tv2 == gx1 [flipped]
ec_felem_select(group, &x1n, e2, &x2n, &x1n); // xn = CMOV(x2n, x1n, e2)
ec_felem_select(group, &y1, e2, &y2, &y1); // y = CMOV(y2, y1, e2)
BN_ULONG sgn0_u = sgn0_le(group, u);
BN_ULONG sgn0_y = sgn0_le(group, &y1);
BN_ULONG e3 = sgn0_u ^ sgn0_y;
e3 = ((BN_ULONG)0) - e3; // e3 = sgn0(u) == sgn0(y) [flipped]
ec_felem_neg(group, &y2, &y1);
ec_felem_select(group, &y1, e3, &y2, &y1); // y = CMOV(-y, y, e3)
// Appendix D.1 describes how to convert (x1n, xd, y1, 1) to Jacobian
// coordinates. Note yd = 1. Also note that gxd computed above is xd^3.
felem_mul(group, &out->X, &x1n, &xd); // X = xn * xd
felem_mul(group, &out->Y, &y1, &gxd); // Y = yn * gxd = yn * xd^3
out->Z = xd; // Z = xd
return 1;
}
static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
const EC_FELEM *Z, const EC_FELEM *c2, unsigned k,
EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len,
const uint8_t *msg, size_t msg_len) {
EC_FELEM u0, u1;
if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) {
return 0;
}
// Compute |c1| = (p - 3) / 4.
BN_ULONG c1[EC_MAX_WORDS];
size_t num_c1 = group->field.width;
if (!bn_copy_words(c1, num_c1, &group->field)) {
return 0;
}
bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1);
EC_RAW_POINT Q0, Q1;
if (!map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0) ||
!map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1)) {
return 0;
}
group->meth->add(group, out, &Q0, &Q1); // R = Q0 + Q1
// All our curves have cofactor one, so |clear_cofactor| is a no-op.
return 1;
}
static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) {
uint8_t bytes[EC_MAX_BYTES] = {0};
size_t len = BN_num_bytes(&group->field);
bytes[len - 1] = a;
return ec_felem_from_bytes(group, out, bytes, len);
}
int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
size_t dst_len, const uint8_t *msg, size_t msg_len) {
// See section 8.3 of draft-irtf-cfrg-hash-to-curve-07.
if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
return 0;
}
// kSqrt1728 was computed as follows in python3:
//
// p = 2**384 - 2**128 - 2**96 + 2**32 - 1
// z3 = 12**3
// c2 = pow(z3, (p+1)//4, p)
// assert z3 == pow(c2, 2, p)
// ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big')
static const uint8_t kSqrt1728[] = {
0x01, 0x98, 0x77, 0xcc, 0x10, 0x41, 0xb7, 0x55, 0x57, 0x43, 0xc0, 0xae,
0x2e, 0x3a, 0x3e, 0x61, 0xfb, 0x2a, 0xaa, 0x2e, 0x0e, 0x87, 0xea, 0x55,
0x7a, 0x56, 0x3d, 0x8b, 0x59, 0x8a, 0x09, 0x40, 0xd0, 0xa6, 0x97, 0xa9,
0xe0, 0xb9, 0xe9, 0x2c, 0xfa, 0xa3, 0x14, 0xf5, 0x83, 0xc9, 0xd0, 0x66
};
// Z = -12, c2 = sqrt(1728)
EC_FELEM Z, c2;
if (!felem_from_u8(group, &Z, 12) ||
!ec_felem_from_bytes(group, &c2, kSqrt1728, sizeof(kSqrt1728))) {
return 0;
}
ec_felem_neg(group, &Z, &Z);
return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst,
dst_len, msg, msg_len);
}
int ec_hash_to_scalar_p384_xmd_sha512_draft07(
const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
const uint8_t *msg, size_t msg_len) {
if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
return 0;
}
return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/192, msg,
msg_len);
}
-56
View File
@@ -1,56 +0,0 @@
/* Copyright (c) 2020, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_EC_EXTRA_INTERNAL_H
#define OPENSSL_HEADER_EC_EXTRA_INTERNAL_H
#include <openssl/ec.h>
#include "../fipsmodule/ec/internal.h"
#if defined(__cplusplus)
extern "C" {
#endif
// Hash-to-curve.
//
// The following functions implement primitives from
// draft-irtf-cfrg-hash-to-curve. The |dst| parameter in each function is the
// domain separation tag and must be unique for each protocol and between the
// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec
// for additional guidance on this parameter.
// ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 hashes |msg| to a point on
// |group| and writes the result to |out|, implementing the
// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07. It
// returns one on success and zero on error.
OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
size_t dst_len, const uint8_t *msg, size_t msg_len);
// ec_hash_to_scalar_p384_xmd_sha512_draft07 hashes |msg| to a scalar on |group|
// and writes the result to |out|, using the hash_to_field operation from the
// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07, but
// generating a value modulo the group order rather than a field element.
OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07(
const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
const uint8_t *msg, size_t msg_len);
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_EC_EXTRA_INTERNAL_H
+2 -2
View File
@@ -96,8 +96,8 @@ int ECDH_compute_key(void *out, size_t out_len, const EC_POINT *pub_key,
uint8_t buf[EC_MAX_BYTES];
size_t buf_len;
if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) ||
!ec_get_x_coordinate_as_bytes(group, buf, &buf_len, sizeof(buf),
&shared_point)) {
!ec_point_get_affine_coordinate_bytes(group, buf, NULL, &buf_len,
sizeof(buf), &shared_point)) {
OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
return -1;
}
+13 -7
View File
@@ -140,16 +140,22 @@ static void RunWycheproofTest(FileTest *t) {
ASSERT_TRUE(GetWycheproofResult(t, &result));
std::vector<uint8_t> shared;
ASSERT_TRUE(t->GetBytes(&shared, "shared"));
// BoringSSL supports compressed coordinates.
bool is_valid = result.IsValid({"CompressedPoint"});
// Wycheproof stores the peer key in an SPKI to mimic a Java API mistake.
// This is non-standard and error-prone.
CBS cbs;
CBS_init(&cbs, peer_spki.data(), peer_spki.size());
bssl::UniquePtr<EVP_PKEY> peer_evp(EVP_parse_public_key(&cbs));
if (!peer_evp || CBS_len(&cbs) != 0) {
EXPECT_FALSE(is_valid);
if (!peer_evp) {
// Note some of Wycheproof's "acceptable" entries are unsupported by
// BoringSSL because they test explicit curves (forbidden by RFC 5480),
// while others are supported because they used compressed coordinates. If
// the peer key fails to parse, we consider it to match "acceptable", but if
// the resulting shared secret matches below, it too matches "acceptable".
//
// TODO(davidben): Use the flags field to disambiguate these. Possibly
// first get the Wycheproof folks to use flags more consistently.
EXPECT_NE(WycheproofResult::kValid, result);
return;
}
EC_KEY *peer_ec = EVP_PKEY_get0_EC_KEY(peer_evp.get());
@@ -164,11 +170,11 @@ static void RunWycheproofTest(FileTest *t) {
int ret =
ECDH_compute_key(actual.data(), actual.size(),
EC_KEY_get0_public_key(peer_ec), key.get(), nullptr);
if (is_valid) {
if (result == WycheproofResult::kInvalid) {
EXPECT_EQ(-1, ret);
} else {
EXPECT_EQ(static_cast<int>(actual.size()), ret);
EXPECT_EQ(Bytes(shared), Bytes(actual.data(), static_cast<size_t>(ret)));
} else {
EXPECT_EQ(-1, ret);
}
}
+38 -39
View File
@@ -382,16 +382,18 @@ char *ERR_error_string(uint32_t packed_error, char *ret) {
OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN);
#endif
return ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
return ret;
}
char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
char lib_buf[64], reason_buf[64];
const char *lib_str, *reason_str;
unsigned lib, reason;
if (len == 0) {
return NULL;
return;
}
lib = ERR_GET_LIB(packed_error);
@@ -423,7 +425,7 @@ char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
if (len <= num_colons) {
// In this situation it's not possible to ensure that the correct number
// of colons are included in the output.
return buf;
return;
}
for (i = 0; i < num_colons; i++) {
@@ -442,8 +444,6 @@ char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
s = colon + 1;
}
}
return buf;
}
// err_string_cmp is a compare function for searching error values with
@@ -495,39 +495,38 @@ static const char *err_string_lookup(uint32_t lib, uint32_t key,
static const char *const kLibraryNames[ERR_NUM_LIBS] = {
"invalid library (0)",
"unknown library", // ERR_LIB_NONE
"system library", // ERR_LIB_SYS
"bignum routines", // ERR_LIB_BN
"RSA routines", // ERR_LIB_RSA
"Diffie-Hellman routines", // ERR_LIB_DH
"public key routines", // ERR_LIB_EVP
"memory buffer routines", // ERR_LIB_BUF
"object identifier routines", // ERR_LIB_OBJ
"PEM routines", // ERR_LIB_PEM
"DSA routines", // ERR_LIB_DSA
"X.509 certificate routines", // ERR_LIB_X509
"ASN.1 encoding routines", // ERR_LIB_ASN1
"configuration file routines", // ERR_LIB_CONF
"common libcrypto routines", // ERR_LIB_CRYPTO
"elliptic curve routines", // ERR_LIB_EC
"SSL routines", // ERR_LIB_SSL
"BIO routines", // ERR_LIB_BIO
"PKCS7 routines", // ERR_LIB_PKCS7
"PKCS8 routines", // ERR_LIB_PKCS8
"X509 V3 routines", // ERR_LIB_X509V3
"random number generator", // ERR_LIB_RAND
"ENGINE routines", // ERR_LIB_ENGINE
"OCSP routines", // ERR_LIB_OCSP
"UI routines", // ERR_LIB_UI
"COMP routines", // ERR_LIB_COMP
"ECDSA routines", // ERR_LIB_ECDSA
"ECDH routines", // ERR_LIB_ECDH
"HMAC routines", // ERR_LIB_HMAC
"Digest functions", // ERR_LIB_DIGEST
"Cipher functions", // ERR_LIB_CIPHER
"HKDF functions", // ERR_LIB_HKDF
"Trust Token functions", // ERR_LIB_TRUST_TOKEN
"User defined functions", // ERR_LIB_USER
"unknown library", // ERR_LIB_NONE
"system library", // ERR_LIB_SYS
"bignum routines", // ERR_LIB_BN
"RSA routines", // ERR_LIB_RSA
"Diffie-Hellman routines", // ERR_LIB_DH
"public key routines", // ERR_LIB_EVP
"memory buffer routines", // ERR_LIB_BUF
"object identifier routines", // ERR_LIB_OBJ
"PEM routines", // ERR_LIB_PEM
"DSA routines", // ERR_LIB_DSA
"X.509 certificate routines", // ERR_LIB_X509
"ASN.1 encoding routines", // ERR_LIB_ASN1
"configuration file routines", // ERR_LIB_CONF
"common libcrypto routines", // ERR_LIB_CRYPTO
"elliptic curve routines", // ERR_LIB_EC
"SSL routines", // ERR_LIB_SSL
"BIO routines", // ERR_LIB_BIO
"PKCS7 routines", // ERR_LIB_PKCS7
"PKCS8 routines", // ERR_LIB_PKCS8
"X509 V3 routines", // ERR_LIB_X509V3
"random number generator", // ERR_LIB_RAND
"ENGINE routines", // ERR_LIB_ENGINE
"OCSP routines", // ERR_LIB_OCSP
"UI routines", // ERR_LIB_UI
"COMP routines", // ERR_LIB_COMP
"ECDSA routines", // ERR_LIB_ECDSA
"ECDH routines", // ERR_LIB_ECDH
"HMAC routines", // ERR_LIB_HMAC
"Digest functions", // ERR_LIB_DIGEST
"Cipher functions", // ERR_LIB_CIPHER
"HKDF functions", // ERR_LIB_HKDF
"User defined functions", // ERR_LIB_USER
};
const char *ERR_lib_error_string(uint32_t packed_error) {
-1
View File
@@ -63,7 +63,6 @@ var libraryNames = []string{
"DIGEST",
"CIPHER",
"HKDF",
"TRUST_TOKEN",
"USER",
}
-48
View File
@@ -235,51 +235,3 @@ TEST(ErrTest, PreservesErrno) {
EXPECT_EQ(EINVAL, errno);
}
#endif
TEST(ErrTest, String) {
char buf[128];
const uint32_t err = ERR_PACK(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
EXPECT_STREQ(
"error:0e000044:common libcrypto routines:OPENSSL_internal:internal "
"error",
ERR_error_string_n(err, buf, sizeof(buf)));
// The buffer is exactly the right size.
EXPECT_STREQ(
"error:0e000044:common libcrypto routines:OPENSSL_internal:internal "
"error",
ERR_error_string_n(err, buf, 73));
// If the buffer is too short, the string is truncated.
EXPECT_STREQ(
"error:0e000044:common libcrypto routines:OPENSSL_internal:internal "
"erro",
ERR_error_string_n(err, buf, 72));
EXPECT_STREQ("error:0e000044:common libcrypto routines:OPENSSL_internal:",
ERR_error_string_n(err, buf, 59));
// Truncated log lines always have the right number of colons.
EXPECT_STREQ("error:0e000044:common libcrypto routines:OPENSSL_interna:",
ERR_error_string_n(err, buf, 58));
EXPECT_STREQ("error:0e000044:common libcrypto routines:OPENSSL_intern:",
ERR_error_string_n(err, buf, 57));
EXPECT_STREQ("error:0e000044:common libcryp::",
ERR_error_string_n(err, buf, 32));
EXPECT_STREQ("error:0e0000:::",
ERR_error_string_n(err, buf, 16));
EXPECT_STREQ("err::::",
ERR_error_string_n(err, buf, 8));
EXPECT_STREQ("::::",
ERR_error_string_n(err, buf, 5));
// If the buffer is too short for even four colons, |ERR_error_string_n| does
// not bother trying to preserve the format.
EXPECT_STREQ("err", ERR_error_string_n(err, buf, 4));
EXPECT_STREQ("er", ERR_error_string_n(err, buf, 3));
EXPECT_STREQ("e", ERR_error_string_n(err, buf, 2));
EXPECT_STREQ("", ERR_error_string_n(err, buf, 1));
// A buffer length of zero should not touch the buffer.
ERR_error_string_n(err, nullptr, 0);
}
-2
View File
@@ -15,14 +15,12 @@ EVP,113,INVALID_MGF1_MD
EVP,114,INVALID_OPERATION
EVP,115,INVALID_PADDING_MODE
EVP,133,INVALID_PARAMETERS
EVP,134,INVALID_PEER_KEY
EVP,116,INVALID_PSS_SALTLEN
EVP,131,INVALID_SIGNATURE
EVP,117,KEYS_NOT_SET
EVP,132,MEMORY_LIMIT_EXCEEDED
EVP,118,MISSING_PARAMETERS
EVP,130,NOT_A_PRIVATE_KEY
EVP,135,NOT_XOF_OR_INVALID_LENGTH
EVP,119,NO_DEFAULT_DIGEST
EVP,120,NO_KEY_SET
EVP,121,NO_MDC2_SUPPORT
+8 -14
View File
@@ -23,6 +23,7 @@ SSL,118,BAD_WRITE_RETRY
SSL,119,BIO_NOT_SET
SSL,261,BLOCK_CIPHER_PAD_IS_WRONG
SSL,120,BN_LIB
SSL,255,BUFFERED_MESSAGES_ON_CIPHER_CHANGE
SSL,121,BUFFER_TOO_SMALL
SSL,275,CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD
SSL,272,CANNOT_PARSE_LEAF_CERT
@@ -36,7 +37,6 @@ SSL,292,CERT_DECOMPRESSION_FAILED
SSL,127,CERT_LENGTH_MISMATCH
SSL,128,CHANNEL_ID_NOT_P256
SSL,129,CHANNEL_ID_SIGNATURE_INVALID
SSL,304,CIPHER_MISMATCH_ON_EARLY_DATA
SSL,130,CIPHER_OR_HASH_UNAVAILABLE
SSL,131,CLIENTHELLO_PARSE_FAILED
SSL,132,CLIENTHELLO_TLSEXT
@@ -64,7 +64,6 @@ SSL,147,ERROR_ADDING_EXTENSION
SSL,148,ERROR_IN_RECEIVED_CIPHER_LIST
SSL,149,ERROR_PARSING_EXTENSION
SSL,150,EXCESSIVE_MESSAGE_SIZE
SSL,255,EXCESS_HANDSHAKE_DATA
SSL,151,EXTRA_DATA_IN_MESSAGE
SSL,152,FRAGMENT_MISMATCH
SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
@@ -73,7 +72,6 @@ SSL,284,HANDSHAKE_NOT_COMPLETE
SSL,155,HTTPS_PROXY_REQUEST
SSL,156,HTTP_REQUEST
SSL,157,INAPPROPRIATE_FALLBACK
SSL,303,INCONSISTENT_CLIENT_HELLO
SSL,259,INVALID_ALPN_PROTOCOL
SSL,158,INVALID_COMMAND
SSL,256,INVALID_COMPRESSION_LIST
@@ -86,7 +84,6 @@ SSL,160,INVALID_SSL_SESSION
SSL,161,INVALID_TICKET_KEYS_LENGTH
SSL,302,KEY_USAGE_BIT_INCORRECT
SSL,162,LENGTH_MISMATCH
SSL,307,MISSING_ALPN
SSL,164,MISSING_EXTENSION
SSL,258,MISSING_KEY_SHARE
SSL,165,MISSING_RSA_CERTIFICATE
@@ -134,7 +131,6 @@ SSL,195,PSK_IDENTITY_NOT_FOUND
SSL,196,PSK_NO_CLIENT_CB
SSL,197,PSK_NO_SERVER_CB
SSL,298,QUIC_INTERNAL_ERROR
SSL,305,QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED
SSL,198,READ_TIMEOUT_EXPIRED
SSL,199,RECORD_LENGTH_MISMATCH
SSL,200,RECORD_TOO_LARGE
@@ -175,10 +171,6 @@ SSL,290,SSL_SESSION_ID_TOO_LONG
SSL,276,TICKET_ENCRYPTION_FAILED
SSL,297,TLS13_DOWNGRADE
SSL,1049,TLSV1_ALERT_ACCESS_DENIED
SSL,1114,TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE
SSL,1113,TLSV1_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE
SSL,1116,TLSV1_ALERT_CERTIFICATE_REQUIRED
SSL,1111,TLSV1_ALERT_CERTIFICATE_UNOBTAINABLE
SSL,1050,TLSV1_ALERT_DECODE_ERROR
SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
SSL,1051,TLSV1_ALERT_DECRYPT_ERROR
@@ -186,15 +178,18 @@ SSL,1060,TLSV1_ALERT_EXPORT_RESTRICTION
SSL,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
SSL,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
SSL,1080,TLSV1_ALERT_INTERNAL_ERROR
SSL,1120,TLSV1_ALERT_NO_APPLICATION_PROTOCOL
SSL,1100,TLSV1_ALERT_NO_RENEGOTIATION
SSL,1070,TLSV1_ALERT_PROTOCOL_VERSION
SSL,1022,TLSV1_ALERT_RECORD_OVERFLOW
SSL,1048,TLSV1_ALERT_UNKNOWN_CA
SSL,1115,TLSV1_ALERT_UNKNOWN_PSK_IDENTITY
SSL,1112,TLSV1_ALERT_UNRECOGNIZED_NAME
SSL,1110,TLSV1_ALERT_UNSUPPORTED_EXTENSION
SSL,1090,TLSV1_ALERT_USER_CANCELLED
SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
SSL,1116,TLSV1_CERTIFICATE_REQUIRED
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
SSL,1115,TLSV1_UNKNOWN_PSK_IDENTITY
SSL,1112,TLSV1_UNRECOGNIZED_NAME
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
SSL,219,TOO_MANY_EMPTY_FRAGMENTS
@@ -204,7 +199,6 @@ SSL,300,TOO_MUCH_READ_EARLY_DATA
SSL,270,TOO_MUCH_SKIPPED_EARLY_DATA
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
SSL,293,UNCOMPRESSED_CERT_TOO_LARGE
SSL,306,UNEXPECTED_COMPATIBILITY_MODE
SSL,222,UNEXPECTED_EXTENSION
SSL,279,UNEXPECTED_EXTENSION_ON_EARLY_DATA
SSL,223,UNEXPECTED_MESSAGE
-15
View File
@@ -1,15 +0,0 @@
TRUST_TOKEN,111,BAD_VALIDITY_CHECK
TRUST_TOKEN,101,BUFFER_TOO_SMALL
TRUST_TOKEN,103,DECODE_ERROR
TRUST_TOKEN,105,DECODE_FAILURE
TRUST_TOKEN,109,INVALID_KEY_ID
TRUST_TOKEN,106,INVALID_METADATA
TRUST_TOKEN,113,INVALID_METADATA_KEY
TRUST_TOKEN,114,INVALID_PROOF
TRUST_TOKEN,110,INVALID_TOKEN
TRUST_TOKEN,100,KEYGEN_FAILURE
TRUST_TOKEN,108,NO_KEYS_CONFIGURED
TRUST_TOKEN,112,NO_SRR_KEY_CONFIGURED
TRUST_TOKEN,102,OVER_BATCHSIZE
TRUST_TOKEN,104,SRR_SIGNATURE_ERROR
TRUST_TOKEN,107,TOO_MANY_KEYS
-3
View File
@@ -6,16 +6,13 @@ X509,104,CANT_CHECK_DH_KEY
X509,105,CERT_ALREADY_IN_HASH_TABLE
X509,106,CRL_ALREADY_DELTA
X509,107,CRL_VERIFY_FAILURE
X509,138,DELTA_CRL_WITHOUT_CRL_NUMBER
X509,108,IDP_MISMATCH
X509,109,INVALID_BIT_STRING_BITS_LEFT
X509,110,INVALID_DIRECTORY
X509,139,INVALID_FIELD_FOR_VERSION
X509,111,INVALID_FIELD_NAME
X509,136,INVALID_PARAMETER
X509,112,INVALID_PSS_PARAMETERS
X509,113,INVALID_TRUST
X509,140,INVALID_VERSION
X509,114,ISSUER_MISMATCH
X509,115,KEY_TYPE_MISMATCH
X509,116,KEY_VALUES_MISMATCH
-14
View File
@@ -71,11 +71,6 @@
#include "../internal.h"
// Node depends on |EVP_R_NOT_XOF_OR_INVALID_LENGTH|.
//
// TODO(davidben): Fix Node to not touch the error queue itself and remove this.
OPENSSL_DECLARE_ERROR_REASON(EVP, NOT_XOF_OR_INVALID_LENGTH)
EVP_PKEY *EVP_PKEY_new(void) {
EVP_PKEY *ret;
@@ -205,8 +200,6 @@ static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
return &dsa_asn1_meth;
case EVP_PKEY_ED25519:
return &ed25519_asn1_meth;
case EVP_PKEY_X25519:
return &x25519_asn1_meth;
default:
return NULL;
}
@@ -434,10 +427,3 @@ void OpenSSL_add_all_ciphers(void) {}
void OpenSSL_add_all_digests(void) {}
void EVP_cleanup(void) {}
int EVP_PKEY_base_id(const EVP_PKEY *pkey) {
// OpenSSL has two notions of key type because it supports multiple OIDs for
// the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling
// of DSA. We do not support these, so the base ID is simply the ID.
return EVP_PKEY_id(pkey);
}
-144
View File
@@ -65,7 +65,6 @@
#include <openssl/rsa.h>
#include "internal.h"
#include "../bytestring/internal.h"
#include "../internal.h"
@@ -74,7 +73,6 @@ static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
&ec_asn1_meth,
&dsa_asn1_meth,
&ed25519_asn1_meth,
&x25519_asn1_meth,
};
static int parse_key_type(CBS *cbs, int *out_type) {
@@ -387,145 +385,3 @@ err:
EVP_PKEY_free(ret);
return NULL;
}
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) {
if (len < 0) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
EVP_PKEY *ret = EVP_parse_public_key(&cbs);
if (ret == NULL) {
return NULL;
}
if (out != NULL) {
EVP_PKEY_free(*out);
*out = ret;
}
*inp = CBS_data(&cbs);
return ret;
}
int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) {
CBB cbb;
if (!CBB_init(&cbb, 128) ||
!EVP_marshal_public_key(&cbb, pkey)) {
CBB_cleanup(&cbb);
return -1;
}
return CBB_finish_i2d(&cbb, outp);
}
RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) {
if (len < 0) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
if (pkey == NULL) {
return NULL;
}
RSA *rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (rsa == NULL) {
return NULL;
}
if (out != NULL) {
RSA_free(*out);
*out = rsa;
}
*inp = CBS_data(&cbs);
return rsa;
}
int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) {
int ret = -1;
EVP_PKEY *pkey = EVP_PKEY_new();
if (pkey == NULL ||
!EVP_PKEY_set1_RSA(pkey, (RSA *)rsa)) {
goto err;
}
ret = i2d_PUBKEY(pkey, outp);
err:
EVP_PKEY_free(pkey);
return ret;
}
DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) {
if (len < 0) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
if (pkey == NULL) {
return NULL;
}
DSA *dsa = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
if (dsa == NULL) {
return NULL;
}
if (out != NULL) {
DSA_free(*out);
*out = dsa;
}
*inp = CBS_data(&cbs);
return dsa;
}
int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) {
int ret = -1;
EVP_PKEY *pkey = EVP_PKEY_new();
if (pkey == NULL ||
!EVP_PKEY_set1_DSA(pkey, (DSA *)dsa)) {
goto err;
}
ret = i2d_PUBKEY(pkey, outp);
err:
EVP_PKEY_free(pkey);
return ret;
}
EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) {
if (len < 0) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
if (pkey == NULL) {
return NULL;
}
EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (ec_key == NULL) {
return NULL;
}
if (out != NULL) {
EC_KEY_free(*out);
*out = ec_key;
}
*inp = CBS_data(&cbs);
return ec_key;
}
int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) {
int ret = -1;
EVP_PKEY *pkey = EVP_PKEY_new();
if (pkey == NULL ||
!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY *)ec_key)) {
goto err;
}
ret = i2d_PUBKEY(pkey, outp);
err:
EVP_PKEY_free(pkey);
return ret;
}
+6 -5
View File
@@ -67,14 +67,15 @@
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
&ec_pkey_meth,
&ed25519_pkey_meth,
&x25519_pkey_meth,
&rsa_pkey_meth,
&ec_pkey_meth,
&ed25519_pkey_meth,
};
static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) {
for (size_t i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) {
unsigned i;
for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) {
if (evp_methods[i]->pkey_id == type) {
return evp_methods[i];
}
+81 -317
View File
@@ -70,6 +70,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#include <gtest/gtest.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
@@ -118,9 +119,6 @@ static int GetKeyType(FileTest *t, const std::string &name) {
if (name == "Ed25519") {
return EVP_PKEY_ED25519;
}
if (name == "X25519") {
return EVP_PKEY_X25519;
}
ADD_FAILURE() << "Unknown key type: " << name;
return EVP_PKEY_NONE;
}
@@ -247,7 +245,7 @@ static bool ImportKey(FileTest *t, KeyMap *key_map,
// SetupContext configures |ctx| based on attributes in |t|, with the exception
// of the signing digest which must be configured externally.
static bool SetupContext(FileTest *t, KeyMap *key_map, EVP_PKEY_CTX *ctx) {
static bool SetupContext(FileTest *t, EVP_PKEY_CTX *ctx) {
if (t->HasAttribute("RSAPadding")) {
int padding;
if (!GetRSAPadding(t, &padding, t->GetAttributeOrDie("RSAPadding")) ||
@@ -279,82 +277,14 @@ static bool SetupContext(FileTest *t, KeyMap *key_map, EVP_PKEY_CTX *ctx) {
}
// For historical reasons, |EVP_PKEY_CTX_set0_rsa_oaep_label| expects to be
// take ownership of the input.
bssl::UniquePtr<uint8_t> buf(reinterpret_cast<uint8_t *>(
OPENSSL_memdup(label.data(), label.size())));
bssl::UniquePtr<uint8_t> buf(
reinterpret_cast<uint8_t *>(BUF_memdup(label.data(), label.size())));
if (!buf ||
!EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, buf.get(), label.size())) {
return false;
}
buf.release();
}
if (t->HasAttribute("DerivePeer")) {
std::string derive_peer = t->GetAttributeOrDie("DerivePeer");
if (key_map->count(derive_peer) == 0) {
ADD_FAILURE() << "Could not find key " << derive_peer;
return false;
}
EVP_PKEY *derive_peer_key = (*key_map)[derive_peer].get();
if (!EVP_PKEY_derive_set_peer(ctx, derive_peer_key)) {
return false;
}
}
return true;
}
static bool TestDerive(FileTest *t, KeyMap *key_map, EVP_PKEY *key) {
bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
if (!ctx ||
!EVP_PKEY_derive_init(ctx.get()) ||
!SetupContext(t, key_map, ctx.get())) {
return false;
}
bssl::UniquePtr<EVP_PKEY_CTX> copy(EVP_PKEY_CTX_dup(ctx.get()));
if (!copy) {
return false;
}
for (EVP_PKEY_CTX *pctx : {ctx.get(), copy.get()}) {
size_t len;
std::vector<uint8_t> actual, output;
if (!EVP_PKEY_derive(pctx, nullptr, &len)) {
return false;
}
actual.resize(len);
if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
return false;
}
actual.resize(len);
// Defer looking up the attribute so Error works properly.
if (!t->GetBytes(&output, "Output")) {
return false;
}
EXPECT_EQ(Bytes(output), Bytes(actual));
// Test when the buffer is too large.
actual.resize(len + 1);
len = actual.size();
if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
return false;
}
actual.resize(len);
EXPECT_EQ(Bytes(output), Bytes(actual));
// Test when the buffer is too small.
actual.resize(len - 1);
len = actual.size();
if (t->HasAttribute("SmallBufferTruncates")) {
if (!EVP_PKEY_derive(pctx, actual.data(), &len)) {
return false;
}
actual.resize(len);
EXPECT_EQ(Bytes(output.data(), len), Bytes(actual));
} else {
EXPECT_FALSE(EVP_PKEY_derive(pctx, actual.data(), &len));
ERR_clear_error();
}
}
return true;
}
@@ -368,14 +298,6 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
return ImportKey(t, key_map, EVP_parse_public_key, EVP_marshal_public_key);
}
// Load the key.
const std::string &key_name = t->GetParameter();
if (key_map->count(key_name) == 0) {
ADD_FAILURE() << "Could not find key " << key_name;
return false;
}
EVP_PKEY *key = (*key_map)[key_name].get();
int (*key_op_init)(EVP_PKEY_CTX *ctx) = nullptr;
int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
const uint8_t *in, size_t in_len) = nullptr;
@@ -399,13 +321,19 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
} else if (t->GetType() == "Encrypt") {
key_op_init = EVP_PKEY_encrypt_init;
key_op = EVP_PKEY_encrypt;
} else if (t->GetType() == "Derive") {
return TestDerive(t, key_map, key);
} else {
ADD_FAILURE() << "Unknown test " << t->GetType();
return false;
}
// Load the key.
const std::string &key_name = t->GetParameter();
if (key_map->count(key_name) == 0) {
ADD_FAILURE() << "Could not find key " << key_name;
return false;
}
EVP_PKEY *key = (*key_map)[key_name].get();
const EVP_MD *digest = nullptr;
if (t->HasAttribute("Digest")) {
digest = GetDigest(t, t->GetAttributeOrDie("Digest"));
@@ -427,7 +355,7 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
bssl::ScopedEVP_MD_CTX ctx, copy;
EVP_PKEY_CTX *pctx;
if (!md_op_init(ctx.get(), &pctx, digest, nullptr, key) ||
!SetupContext(t, key_map, pctx) ||
!SetupContext(t, pctx) ||
!EVP_MD_CTX_copy_ex(copy.get(), ctx.get())) {
return false;
}
@@ -474,7 +402,7 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
!key_op_init(ctx.get()) ||
(digest != nullptr &&
!EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
!SetupContext(t, key_map, ctx.get())) {
!SetupContext(t, ctx.get())) {
return false;
}
@@ -508,7 +436,7 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
!EVP_PKEY_decrypt_init(decrypt_ctx.get()) ||
(digest != nullptr &&
!EVP_PKEY_CTX_set_signature_md(decrypt_ctx.get(), digest)) ||
!SetupContext(t, key_map, decrypt_ctx.get()) ||
!SetupContext(t, decrypt_ctx.get()) ||
!EVP_PKEY_decrypt(decrypt_ctx.get(), nullptr, &plaintext_len,
actual.data(), actual.size())) {
return false;
@@ -528,7 +456,7 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
!EVP_PKEY_verify_init(verify_ctx.get()) ||
(digest != nullptr &&
!EVP_PKEY_CTX_set_signature_md(verify_ctx.get(), digest)) ||
!SetupContext(t, key_map, verify_ctx.get())) {
!SetupContext(t, verify_ctx.get())) {
return false;
}
if (t->HasAttribute("VerifyPSSSaltLength")) {
@@ -567,10 +495,40 @@ TEST(EVPTest, TestVectors) {
});
}
static void RunWycheproofVerifyTest(const char *path) {
static void RunWycheproofTest(const char *path) {
SCOPED_TRACE(path);
FileTestGTest(path, [](FileTest *t) {
t->IgnoreAllUnusedInstructions();
t->IgnoreInstruction("key.type");
// Extra ECDSA fields.
t->IgnoreInstruction("key.curve");
t->IgnoreInstruction("key.keySize");
t->IgnoreInstruction("key.wx");
t->IgnoreInstruction("key.wy");
t->IgnoreInstruction("key.uncompressed");
// Extra RSA fields.
t->IgnoreInstruction("e");
t->IgnoreInstruction("keyAsn");
t->IgnoreInstruction("keysize");
t->IgnoreInstruction("n");
t->IgnoreAttribute("padding");
t->IgnoreInstruction("keyJwk.alg");
t->IgnoreInstruction("keyJwk.e");
t->IgnoreInstruction("keyJwk.kid");
t->IgnoreInstruction("keyJwk.kty");
t->IgnoreInstruction("keyJwk.n");
// Extra EdDSA fields.
t->IgnoreInstruction("key.pk");
t->IgnoreInstruction("key.sk");
t->IgnoreInstruction("jwk.crv");
t->IgnoreInstruction("jwk.d");
t->IgnoreInstruction("jwk.kid");
t->IgnoreInstruction("jwk.kty");
t->IgnoreInstruction("jwk.x");
// Extra DSA fields.
t->IgnoreInstruction("key.g");
t->IgnoreInstruction("key.p");
t->IgnoreInstruction("key.q");
t->IgnoreInstruction("key.y");
std::vector<uint8_t> der;
ASSERT_TRUE(t->GetInstructionBytes(&der, "keyDer"));
@@ -615,7 +573,13 @@ static void RunWycheproofVerifyTest(const char *path) {
bool sig_ok = DSA_check_signature(&valid, digest, digest_len, sig.data(),
sig.size(), dsa) &&
valid;
EXPECT_EQ(sig_ok, result.IsValid());
if (result == WycheproofResult::kValid) {
EXPECT_TRUE(sig_ok);
} else if (result == WycheproofResult::kInvalid) {
EXPECT_FALSE(sig_ok);
} else {
// this is a legacy signature, which may or may not be accepted.
}
} else {
bssl::ScopedEVP_MD_CTX ctx;
EVP_PKEY_CTX *pctx;
@@ -628,275 +592,75 @@ static void RunWycheproofVerifyTest(const char *path) {
}
int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
msg.size());
// BoringSSL does not enforce policies on weak keys and leaves it to the
// caller.
EXPECT_EQ(ret,
result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"})
? 1
: 0);
if (result == WycheproofResult::kValid) {
EXPECT_EQ(1, ret);
} else if (result == WycheproofResult::kInvalid) {
EXPECT_EQ(0, ret);
} else {
// this is a legacy signature, which may or may not be accepted.
EXPECT_TRUE(ret == 1 || ret == 0);
}
}
});
}
TEST(EVPTest, WycheproofDSA) {
RunWycheproofVerifyTest("third_party/wycheproof_testvectors/dsa_test.txt");
RunWycheproofTest("third_party/wycheproof_testvectors/dsa_test.txt");
}
TEST(EVPTest, WycheproofECDSAP224) {
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt");
}
TEST(EVPTest, WycheproofECDSAP256) {
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt");
}
TEST(EVPTest, WycheproofECDSAP384) {
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt");
}
TEST(EVPTest, WycheproofECDSAP521) {
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt");
}
TEST(EVPTest, WycheproofEdDSA) {
RunWycheproofVerifyTest("third_party/wycheproof_testvectors/eddsa_test.txt");
RunWycheproofTest("third_party/wycheproof_testvectors/eddsa_test.txt");
}
TEST(EVPTest, WycheproofRSAPKCS1) {
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt");
// TODO(davidben): Is this file redundant with the tests above?
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/rsa_signature_test.txt");
}
TEST(EVPTest, WycheproofRSAPKCS1Sign) {
FileTestGTest(
"third_party/wycheproof_testvectors/rsa_sig_gen_misc_test.txt",
[](FileTest *t) {
t->IgnoreAllUnusedInstructions();
std::vector<uint8_t> pkcs8;
ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
CBS cbs;
CBS_init(&cbs, pkcs8.data(), pkcs8.size());
bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
ASSERT_TRUE(key);
const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
ASSERT_TRUE(md);
std::vector<uint8_t> msg, sig;
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
ASSERT_TRUE(t->GetBytes(&sig, "sig"));
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
bssl::ScopedEVP_MD_CTX ctx;
EVP_PKEY_CTX *pctx;
ASSERT_TRUE(
EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr, key.get()));
std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
size_t len = out.size();
int ret =
EVP_DigestSign(ctx.get(), out.data(), &len, msg.data(), msg.size());
// BoringSSL does not enforce policies on weak keys and leaves it to the
// caller.
bool is_valid =
result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"});
EXPECT_EQ(ret, is_valid ? 1 : 0);
if (is_valid) {
out.resize(len);
EXPECT_EQ(Bytes(sig), Bytes(out));
}
});
}
TEST(EVPTest, WycheproofRSAPSS) {
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/"
"rsa_pss_2048_sha256_mgf1_32_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/"
"rsa_pss_3072_sha256_mgf1_32_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/"
"rsa_pss_4096_sha256_mgf1_32_test.txt");
RunWycheproofVerifyTest(
RunWycheproofTest(
"third_party/wycheproof_testvectors/"
"rsa_pss_4096_sha512_mgf1_32_test.txt");
RunWycheproofVerifyTest(
"third_party/wycheproof_testvectors/rsa_pss_misc_test.txt");
}
static void RunWycheproofDecryptTest(
const char *path,
std::function<void(FileTest *, EVP_PKEY_CTX *)> setup_cb) {
FileTestGTest(path, [&](FileTest *t) {
t->IgnoreAllUnusedInstructions();
std::vector<uint8_t> pkcs8;
ASSERT_TRUE(t->GetInstructionBytes(&pkcs8, "privateKeyPkcs8"));
CBS cbs;
CBS_init(&cbs, pkcs8.data(), pkcs8.size());
bssl::UniquePtr<EVP_PKEY> key(EVP_parse_private_key(&cbs));
ASSERT_TRUE(key);
std::vector<uint8_t> ct, msg;
ASSERT_TRUE(t->GetBytes(&ct, "ct"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key.get(), nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(EVP_PKEY_decrypt_init(ctx.get()));
ASSERT_NO_FATAL_FAILURE(setup_cb(t, ctx.get()));
std::vector<uint8_t> out(EVP_PKEY_size(key.get()));
size_t len = out.size();
int ret =
EVP_PKEY_decrypt(ctx.get(), out.data(), &len, ct.data(), ct.size());
// BoringSSL does not enforce policies on weak keys and leaves it to the
// caller.
bool is_valid = result.IsValid({"SmallModulus"});
EXPECT_EQ(ret, is_valid ? 1 : 0);
if (is_valid) {
out.resize(len);
EXPECT_EQ(Bytes(msg), Bytes(out));
}
});
}
static void RunWycheproofOAEPTest(const char *path) {
RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
ASSERT_TRUE(md);
const EVP_MD *mgf1_md = GetWycheproofDigest(t, "mgfSha", true);
ASSERT_TRUE(mgf1_md);
std::vector<uint8_t> label;
ASSERT_TRUE(t->GetBytes(&label, "label"));
ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING));
ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md));
ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md));
bssl::UniquePtr<uint8_t> label_copy(
static_cast<uint8_t *>(OPENSSL_memdup(label.data(), label.size())));
ASSERT_TRUE(label_copy || label.empty());
ASSERT_TRUE(
EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, label_copy.get(), label.size()));
// |EVP_PKEY_CTX_set0_rsa_oaep_label| takes ownership on success.
label_copy.release();
});
}
TEST(EVPTest, WycheproofRSAOAEP2048) {
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha1_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha224_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha224_mgf1sha224_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha256_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha256_mgf1sha256_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha384_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha384_mgf1sha384_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha512_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_2048_sha512_mgf1sha512_test.txt");
}
TEST(EVPTest, WycheproofRSAOAEP3072) {
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_3072_sha256_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_3072_sha256_mgf1sha256_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_3072_sha512_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_3072_sha512_mgf1sha512_test.txt");
}
TEST(EVPTest, WycheproofRSAOAEP4096) {
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_4096_sha256_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_4096_sha256_mgf1sha256_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_4096_sha512_mgf1sha1_test.txt");
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/"
"rsa_oaep_4096_sha512_mgf1sha512_test.txt");
}
TEST(EVPTest, WycheproofRSAOAEPMisc) {
RunWycheproofOAEPTest(
"third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt");
}
static void RunWycheproofPKCS1DecryptTest(const char *path) {
RunWycheproofDecryptTest(path, [](FileTest *t, EVP_PKEY_CTX *ctx) {
// No setup needed. PKCS#1 is, sadly, the default.
});
}
TEST(EVPTest, WycheproofRSAPKCS1Decrypt) {
RunWycheproofPKCS1DecryptTest(
"third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt");
RunWycheproofPKCS1DecryptTest(
"third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt");
RunWycheproofPKCS1DecryptTest(
"third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt");
RunWycheproofTest("third_party/wycheproof_testvectors/rsa_pss_misc_test.txt");
}
-65
View File
@@ -73,32 +73,6 @@ PrivateKey = P-256-BadInnerParameters
Input = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Error = GROUP_MISMATCH
# The same key, but with the curve spelled explicitly.
PrivateKey = P-256-ExplicitParameters
Type = EC
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Output = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
ExpectNoRawPrivate
ExpectNoRawPublic
# The same as above, but with the optional cofactor omitted.
PrivateKey = P-256-ExplicitParameters-NoCofactor
Type = EC
Input = 3082015e0201003081e906072a8648ce3d02013081dd020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Output = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
ExpectNoRawPrivate
ExpectNoRawPublic
# The same as above, but the cofactor is zero instead of one.
PrivateKey = P-256-ExplicitParameters-CofactorZero
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020100046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Error = UNKNOWN_GROUP
# The same as above, but the cofactor is two instead of one.
PrivateKey = P-256-ExplicitParameters-CofactorTwo
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020102046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Error = UNKNOWN_GROUP
# The public half of the same key encoded as a PublicKey.
PublicKey = P-256-SPKI
Type = EC
@@ -1633,42 +1607,3 @@ Verify = Ed25519
Input = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
Output = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
Error = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
# Derive tests.
PrivateKey = ECDH-P256-Private
Type = EC
Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534
PublicKey = ECDH-P256-Peer
Type = EC
Input = 3059301306072a8648ce3d020106082a8648ce3d03010703420004700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac
Derive = ECDH-P256-Private
DerivePeer = ECDH-P256-Peer
Output = 46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b
SmallBufferTruncates
PrivateKey = X25519-Private
Type = X25519
Input = 302e020100300506032b656e04220420a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
ExpectRawPrivate = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
PublicKey = X25519-Peer
Type = X25519
Input = 302a300506032b656e032100e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c
ExpectRawPublic = e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c
PublicKey = X25519-SmallOrderPeer
Type = X25519
ExpectRawPublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800
Input = 302a300506032b656e032100e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800
Derive = X25519-Private
DerivePeer = X25519-Peer
Output = c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552
Derive = X25519-Private
DerivePeer = X25519-SmallOrderPeer
Error = INVALID_PEER_KEY
-8
View File
@@ -244,22 +244,14 @@ typedef struct {
char has_private;
} ED25519_KEY;
typedef struct {
uint8_t pub[32];
uint8_t priv[32];
char has_private;
} X25519_KEY;
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth;
extern const EVP_PKEY_METHOD rsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
extern const EVP_PKEY_METHOD ed25519_pkey_meth;
extern const EVP_PKEY_METHOD x25519_pkey_meth;
#if defined(__cplusplus)
+1
View File
@@ -58,6 +58,7 @@
#include <string.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/digest.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
+1 -1
View File
@@ -196,7 +196,7 @@ static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) {
static int ed25519_size(const EVP_PKEY *pkey) { return 64; }
static int ed25519_bits(const EVP_PKEY *pkey) { return 253; }
static int ed25519_bits(const EVP_PKEY *pkey) { return 256; }
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
EVP_PKEY_ED25519,
+2 -14
View File
@@ -59,6 +59,7 @@
#include <string.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
@@ -134,7 +135,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
dctx->saltlen = sctx->saltlen;
if (sctx->oaep_label) {
OPENSSL_free(dctx->oaep_label);
dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
if (!dctx->oaep_label) {
return 0;
}
@@ -568,19 +569,6 @@ int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) {
0, out_padding);
}
int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
return 0;
}
int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int salt_len) {
return 0;
}
int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx,
const EVP_MD *md) {
return 0;
}
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) {
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
-110
View File
@@ -1,110 +0,0 @@
/* Copyright (c) 2019, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/evp.h>
#include <openssl/curve25519.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "internal.h"
// X25519 has no parameters to copy.
static int pkey_x25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; }
static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY));
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!EVP_PKEY_set_type(pkey, EVP_PKEY_X25519)) {
OPENSSL_free(key);
return 0;
}
X25519_keypair(key->pub, key->priv);
key->has_private = 1;
OPENSSL_free(pkey->pkey.ptr);
pkey->pkey.ptr = key;
return 1;
}
static int pkey_x25519_derive(EVP_PKEY_CTX *ctx, uint8_t *out,
size_t *out_len) {
if (ctx->pkey == NULL || ctx->peerkey == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
return 0;
}
const X25519_KEY *our_key = ctx->pkey->pkey.ptr;
const X25519_KEY *peer_key = ctx->peerkey->pkey.ptr;
if (our_key == NULL || peer_key == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
return 0;
}
if (!our_key->has_private) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY);
return 0;
}
if (out != NULL) {
if (*out_len < 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
if (!X25519(out, our_key->priv, peer_key->pub)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
return 0;
}
}
*out_len = 32;
return 1;
}
static int pkey_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
switch (type) {
case EVP_PKEY_CTRL_PEER_KEY:
// |EVP_PKEY_derive_set_peer| requires the key implement this command,
// even if it is a no-op.
return 1;
default:
OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}
const EVP_PKEY_METHOD x25519_pkey_meth = {
EVP_PKEY_X25519,
NULL /* init */,
pkey_x25519_copy,
NULL /* cleanup */,
pkey_x25519_keygen,
NULL /* sign */,
NULL /* sign_message */,
NULL /* verify */,
NULL /* verify_message */,
NULL /* verify_recover */,
NULL /* encrypt */,
NULL /* decrypt */,
pkey_x25519_derive,
NULL /* paramgen */,
pkey_x25519_ctrl,
};
-248
View File
@@ -1,248 +0,0 @@
/* Copyright (c) 2019, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/evp.h>
#include <openssl/bytestring.h>
#include <openssl/curve25519.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "internal.h"
#include "../internal.h"
static void x25519_free(EVP_PKEY *pkey) {
OPENSSL_free(pkey->pkey.ptr);
pkey->pkey.ptr = NULL;
}
static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) {
if (len != 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY));
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
OPENSSL_memcpy(key->priv, in, 32);
X25519_public_from_private(key->pub, key->priv);
key->has_private = 1;
x25519_free(pkey);
pkey->pkey.ptr = key;
return 1;
}
static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) {
if (len != 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY));
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
OPENSSL_memcpy(key->pub, in, 32);
key->has_private = 0;
x25519_free(pkey);
pkey->pkey.ptr = key;
return 1;
}
static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out,
size_t *out_len) {
const X25519_KEY *key = pkey->pkey.ptr;
if (!key->has_private) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY);
return 0;
}
if (out == NULL) {
*out_len = 32;
return 1;
}
if (*out_len < 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
OPENSSL_memcpy(out, key->priv, 32);
*out_len = 32;
return 1;
}
static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out,
size_t *out_len) {
const X25519_KEY *key = pkey->pkey.ptr;
if (out == NULL) {
*out_len = 32;
return 1;
}
if (*out_len < 32) {
OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
OPENSSL_memcpy(out, key->pub, 32);
*out_len = 32;
return 1;
}
static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
// See RFC 8410, section 4.
// The parameters must be omitted. Public keys have length 32.
if (CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key));
}
static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) {
const X25519_KEY *key = pkey->pkey.ptr;
// See RFC 8410, section 4.
CBB spki, algorithm, oid, key_bitstring;
if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) ||
!CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
!CBB_add_u8(&key_bitstring, 0 /* padding */) ||
!CBB_add_bytes(&key_bitstring, key->pub, 32) ||
!CBB_flush(out)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
return 1;
}
static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
const X25519_KEY *a_key = a->pkey.ptr;
const X25519_KEY *b_key = b->pkey.ptr;
return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0;
}
static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
// See RFC 8410, section 7.
// Parameters must be empty. The key is a 32-byte value wrapped in an extra
// OCTET STRING layer.
CBS inner;
if (CBS_len(params) != 0 ||
!CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) ||
CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner));
}
static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) {
X25519_KEY *key = pkey->pkey.ptr;
if (!key->has_private) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY);
return 0;
}
// See RFC 8410, section 7.
CBB pkcs8, algorithm, oid, private_key, inner;
if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
!CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) ||
!CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
!CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) ||
// The PKCS#8 encoding stores only the 32-byte seed which is the first 32
// bytes of the private key.
!CBB_add_bytes(&inner, key->priv, 32) ||
!CBB_flush(out)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
return 0;
}
return 1;
}
static int x25519_size(const EVP_PKEY *pkey) { return 32; }
static int x25519_bits(const EVP_PKEY *pkey) { return 253; }
const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = {
EVP_PKEY_X25519,
{0x2b, 0x65, 0x6e},
3,
x25519_pub_decode,
x25519_pub_encode,
x25519_pub_cmp,
x25519_priv_decode,
x25519_priv_encode,
x25519_set_priv_raw,
x25519_set_pub_raw,
x25519_get_priv_raw,
x25519_get_pub_raw,
NULL /* pkey_opaque */,
x25519_size,
x25519_bits,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
x25519_free,
};
int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in,
size_t len) {
// TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC|
// keys. Add support if it ever comes up.
if (pkey->type != EVP_PKEY_X25519) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return 0;
}
return x25519_set_pub_raw(pkey, in, len);
}
size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) {
// TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC|
// keys. Add support if it ever comes up.
if (pkey->type != EVP_PKEY_X25519) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return 0;
}
const X25519_KEY *key = pkey->pkey.ptr;
if (key == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
return 0;
}
*out_ptr = OPENSSL_memdup(key->pub, 32);
return *out_ptr == NULL ? 0 : 32;
}
+7 -3
View File
@@ -6,6 +6,7 @@ if(${ARCH} STREQUAL "x86_64")
aesni-gcm-x86_64.${ASM_EXT}
aesni-x86_64.${ASM_EXT}
aes-x86_64.${ASM_EXT}
ghash-ssse3-x86_64.${ASM_EXT}
ghash-x86_64.${ASM_EXT}
md5-x86_64.${ASM_EXT}
@@ -26,6 +27,7 @@ if(${ARCH} STREQUAL "x86")
set(
BCM_ASM_SOURCES
aes-586.${ASM_EXT}
aesni-x86.${ASM_EXT}
bn-586.${ASM_EXT}
co-586.${ASM_EXT}
@@ -44,6 +46,7 @@ if(${ARCH} STREQUAL "arm")
set(
BCM_ASM_SOURCES
aes-armv4.${ASM_EXT}
aesv8-armx.${ASM_EXT}
armv4-mont.${ASM_EXT}
bsaes-armv7.${ASM_EXT}
@@ -52,7 +55,6 @@ if(${ARCH} STREQUAL "arm")
sha1-armv4-large.${ASM_EXT}
sha256-armv4.${ASM_EXT}
sha512-armv4.${ASM_EXT}
vpaes-armv7.${ASM_EXT}
)
endif()
@@ -80,11 +82,14 @@ if(${ARCH} STREQUAL "ppc64le")
)
endif()
perlasm(aes-586.${ASM_EXT} aes/asm/aes-586.pl)
perlasm(aes-armv4.${ASM_EXT} aes/asm/aes-armv4.pl)
perlasm(aesni-gcm-x86_64.${ASM_EXT} modes/asm/aesni-gcm-x86_64.pl)
perlasm(aesni-x86_64.${ASM_EXT} aes/asm/aesni-x86_64.pl)
perlasm(aesni-x86.${ASM_EXT} aes/asm/aesni-x86.pl)
perlasm(aesp8-ppc.${ASM_EXT} aes/asm/aesp8-ppc.pl)
perlasm(aesv8-armx.${ASM_EXT} aes/asm/aesv8-armx.pl)
perlasm(aes-x86_64.${ASM_EXT} aes/asm/aes-x86_64.pl)
perlasm(armv4-mont.${ASM_EXT} bn/asm/armv4-mont.pl)
perlasm(armv8-mont.${ASM_EXT} bn/asm/armv8-mont.pl)
perlasm(bn-586.${ASM_EXT} bn/asm/bn-586.pl)
@@ -116,7 +121,6 @@ perlasm(sha512-586.${ASM_EXT} sha/asm/sha512-586.pl)
perlasm(sha512-armv4.${ASM_EXT} sha/asm/sha512-armv4.pl)
perlasm(sha512-armv8.${ASM_EXT} sha/asm/sha512-armv8.pl)
perlasm(sha512-x86_64.${ASM_EXT} sha/asm/sha512-x86_64.pl)
perlasm(vpaes-armv7.${ASM_EXT} aes/asm/vpaes-armv7.pl)
perlasm(vpaes-armv8.${ASM_EXT} aes/asm/vpaes-armv8.pl)
perlasm(vpaes-x86_64.${ASM_EXT} aes/asm/vpaes-x86_64.pl)
perlasm(vpaes-x86.${ASM_EXT} aes/asm/vpaes-x86.pl)
@@ -226,7 +230,7 @@ elseif(FIPS_SHARED)
add_custom_command(
OUTPUT bcm.o
COMMAND ${CMAKE_LINKER} -r -T ${CMAKE_CURRENT_SOURCE_DIR}/fips_shared.lds -o bcm.o --whole-archive $<TARGET_FILE:bcm_library>
COMMAND ld -r -T ${CMAKE_CURRENT_SOURCE_DIR}/fips_shared.lds -o bcm.o --whole-archive $<TARGET_FILE:bcm_library>
DEPENDS bcm_library fips_shared.lds
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
-11
View File
@@ -10,7 +10,6 @@ BoringCrypto has undergone the following validations:
1. 2017-06-15: certificate [#2964](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2964), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx) (in docx format).
1. 2018-07-30: certificate [#3318](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3318), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx) (in docx format).
1. 2019-08-08: certificate [#3678](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3678), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20190808.docx) (in docx format).
## Running CAVP tests
@@ -47,10 +46,6 @@ The DRBG state is kept in a thread-local structure and is seeded from one of the
In FIPS mode, each of those entropy sources is subject to a 10× overread. That is, when *n* bytes of entropy are needed, *10n* bytes will be read from the entropy source and XORed down to *n* bytes. Reads from the entropy source are also processed in blocks of 16 bytes and if two consecutive chunks are equal the process will abort.
In the case that the seed is taken from RDRAND, getrandom will also be queried with `GRND_NONBLOCK` to attempt to obtain additional entropy from the operating system. If available, that extra entropy will be XORed into the whitened seed.
On Android, only `getrandom` is supported and, when seeding for the first time, the system property `ro.boringcrypto.hwrand` is queried. If set to `true` then `getrandom` will be called with the `GRND_RANDOM` flag. Only entropy draws destined for DRBG seeds are affected by this. We are not suggesting that there is any security advantage at all to doing this, and thus recommend that Android vendors do _not_ set this flag.
The CTR-DRBG is reseeded every 4096 calls to `RAND_bytes`. Thus the process will randomly crash about every 2¹³⁵ calls.
The FIPS PRNGs allow “additional input” to be fed into a given call. We use this feature to be as robust as possible to state duplication from process forks and VM copies: for every call we read 32 bytes of “additional data” from the entropy source (without overread) which means that cloned states will diverge at the next call to `RAND_bytes`. This is called “prediction resistance” by FIPS, but we do *not* claim this property in a FIPS context because we don't implement it the way they want.
@@ -59,12 +54,6 @@ There is a second interface to the RNG which allows the caller to supply bytes t
FIPS requires that RNG state be zeroed when the process exits. In order to implement this, all per-thread RNG states are tracked in a linked list and a destructor function is included which clears them. In order for this to be safe in the presence of threads, a lock is used to stop all other threads from using the RNG once this process has begun. Thus the main thread exiting may cause other threads to deadlock, and drawing on entropy in a destructor function may also deadlock.
## Self-test optimisation
On Android, the self-tests are optimised in line with [IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf) section 9.11. The module will always perform the integrity test at power-on, but the self-tests will test for the presence of a file named after the hex encoded, HMAC-SHA-256 hash of the module in `/dev/boringssl/selftest/`. If such a file is found then the self-tests are skipped. Otherwise, after the self-tests complete successfully, that file will be written. Any I/O errors are ignored and, if they occur when testing for the presence of the file, the module acts as if it's not present.
It is intended that a `tmpfs` be mounted at that location in order to skip running the self tests for every process once they have already passed in a given instance of the operating system.
## Integrity Test
FIPS-140 mandates that a module calculate an HMAC of its own code in a constructor function and compare the result to a known-good value. Typical code produced by a C compiler includes large numbers of relocations: places in the machine code where the linker needs to resolve and inject the final value of a symbolic expression. These relocations mean that the bytes that make up any specific bit of code generally aren't known until the final link has completed.
+752
View File
@@ -56,6 +56,758 @@
#include "../modes/internal.h"
#if defined(OPENSSL_NO_ASM) || \
(!defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) && !defined(OPENSSL_ARM))
// Te0[x] = S [x].[02, 01, 01, 03];
// Te1[x] = S [x].[03, 02, 01, 01];
// Te2[x] = S [x].[01, 03, 02, 01];
// Te3[x] = S [x].[01, 01, 03, 02];
//
// Td0[x] = Si[x].[0e, 09, 0d, 0b];
// Td1[x] = Si[x].[0b, 0e, 09, 0d];
// Td2[x] = Si[x].[0d, 0b, 0e, 09];
// Td3[x] = Si[x].[09, 0d, 0b, 0e];
// Td4[x] = Si[x].[01];
static const uint32_t Te0[256] = {
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU,
0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U,
0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U,
0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU,
0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U,
0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU,
0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U,
0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U,
0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU,
0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU,
0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U,
0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U,
0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U,
0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U,
0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U,
0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU,
0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U,
0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U,
0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U,
0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U,
0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU,
0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U,
0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU,
0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U,
0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU,
0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU,
0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U,
0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U,
0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU,
0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU,
0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU,
0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U,
0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U,
0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U,
0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U,
0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U,
0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU,
0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U,
0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U,
0x2c16163aU, };
static const uint32_t Te1[256] = {
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U,
0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U,
0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU,
0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU,
0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U,
0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U,
0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U,
0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U,
0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U,
0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U,
0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU,
0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U,
0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U,
0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU,
0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U,
0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U,
0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU,
0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U,
0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U,
0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU,
0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U,
0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U,
0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU,
0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U,
0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U,
0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U,
0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U,
0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU,
0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU,
0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U,
0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU,
0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU,
0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U,
0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U,
0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U,
0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U,
0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU,
0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U,
0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU,
0x3a2c1616U, };
static const uint32_t Te2[256] = {
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U,
0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U,
0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU,
0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU,
0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U,
0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U,
0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U,
0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U,
0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U,
0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U,
0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU,
0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U,
0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U,
0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU,
0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U,
0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U,
0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU,
0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U,
0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U,
0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU,
0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U,
0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U,
0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU,
0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U,
0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U,
0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U,
0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U,
0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU,
0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU,
0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U,
0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU,
0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU,
0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U,
0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U,
0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U,
0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U,
0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU,
0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U,
0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU,
0x163a2c16U, };
static const uint32_t Te3[256] = {
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU,
0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U,
0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU,
0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U,
0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U,
0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU,
0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U,
0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U,
0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU,
0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U,
0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU,
0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U,
0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U,
0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU,
0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U,
0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU,
0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U,
0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U,
0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U,
0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U,
0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U,
0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U,
0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U,
0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU,
0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U,
0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU,
0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U,
0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U,
0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U,
0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU,
0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U,
0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU,
0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U,
0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U,
0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U,
0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U,
0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U,
0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U,
0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU,
0x16163a2cU, };
static const uint32_t Td0[256] = {
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU,
0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U,
0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U,
0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U,
0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U,
0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU,
0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U,
0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U,
0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U,
0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU,
0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U,
0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U,
0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U,
0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U,
0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U,
0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU,
0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U,
0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U,
0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU,
0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU,
0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U,
0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU,
0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U,
0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU,
0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU,
0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU,
0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU,
0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U,
0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU,
0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U,
0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU,
0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU,
0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U,
0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU,
0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U,
0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U,
0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U,
0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU,
0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U,
0xd0b85742U, };
static const uint32_t Td1[256] = {
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU,
0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU,
0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U,
0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU,
0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U,
0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU,
0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U,
0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU,
0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU,
0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU,
0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU,
0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U,
0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU,
0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U,
0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU,
0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU,
0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U,
0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U,
0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU,
0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U,
0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU,
0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U,
0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U,
0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U,
0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U,
0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U,
0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U,
0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U,
0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U,
0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U,
0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U,
0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U,
0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU,
0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U,
0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U,
0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU,
0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U,
0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U,
0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU,
0x42d0b857U, };
static const uint32_t Td2[256] = {
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU,
0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U,
0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U,
0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU,
0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U,
0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U,
0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U,
0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U,
0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU,
0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU,
0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U,
0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU,
0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U,
0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU,
0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U,
0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU,
0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU,
0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU,
0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U,
0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U,
0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U,
0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU,
0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U,
0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U,
0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U,
0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U,
0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U,
0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U,
0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU,
0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU,
0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U,
0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU,
0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU,
0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U,
0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U,
0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U,
0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU,
0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU,
0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU,
0x5742d0b8U, };
static const uint32_t Td3[256] = {
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU,
0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU,
0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U,
0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U,
0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U,
0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U,
0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U,
0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU,
0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U,
0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU,
0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U,
0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U,
0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U,
0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U,
0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U,
0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU,
0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U,
0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U,
0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU,
0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU,
0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U,
0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U,
0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU,
0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U,
0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U,
0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U,
0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU,
0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU,
0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU,
0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU,
0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U,
0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U,
0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U,
0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU,
0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U,
0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U,
0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U,
0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U,
0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U,
0xb85742d0U, };
static const uint8_t Td4[256] = {
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U,
0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU,
0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 0x54U,
0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU,
0x42U, 0xfaU, 0xc3U, 0x4eU, 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U,
0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 0x72U, 0xf8U,
0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU,
0x65U, 0xb6U, 0x92U, 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 0x90U, 0xd8U, 0xabU,
0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U,
0x45U, 0x06U, 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U,
0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 0x3aU, 0x91U, 0x11U, 0x41U,
0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U,
0x73U, 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U,
0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU,
0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U,
0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U,
0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 0x60U,
0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU,
0x93U, 0xc9U, 0x9cU, 0xefU, 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U,
0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 0x17U, 0x2bU,
0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U,
0x21U, 0x0cU, 0x7dU, };
static const uint32_t rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
// for 128-bit blocks, Rijndael never uses more than 10 rcon values
};
int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey) {
uint32_t *rk;
int i = 0;
uint32_t temp;
if (!key || !aeskey) {
return -1;
}
switch (bits) {
case 128:
aeskey->rounds = 10;
break;
case 192:
aeskey->rounds = 12;
break;
case 256:
aeskey->rounds = 14;
break;
default:
return -2;
}
rk = aeskey->rd_key;
rk[0] = GETU32(key);
rk[1] = GETU32(key + 4);
rk[2] = GETU32(key + 8);
rk[3] = GETU32(key + 12);
if (bits == 128) {
while (1) {
temp = rk[3];
rk[4] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
return 0;
}
rk += 4;
}
}
rk[4] = GETU32(key + 16);
rk[5] = GETU32(key + 20);
if (bits == 192) {
while (1) {
temp = rk[5];
rk[6] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
rk[7] = rk[1] ^ rk[6];
rk[8] = rk[2] ^ rk[7];
rk[9] = rk[3] ^ rk[8];
if (++i == 8) {
return 0;
}
rk[10] = rk[4] ^ rk[9];
rk[11] = rk[5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(key + 24);
rk[7] = GETU32(key + 28);
if (bits == 256) {
while (1) {
temp = rk[7];
rk[8] = rk[0] ^ (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24)] & 0x000000ff) ^ rcon[i];
rk[9] = rk[1] ^ rk[8];
rk[10] = rk[2] ^ rk[9];
rk[11] = rk[3] ^ rk[10];
if (++i == 7) {
return 0;
}
temp = rk[11];
rk[12] = rk[4] ^ (Te2[(temp >> 24)] & 0xff000000) ^
(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(temp) & 0xff] & 0x000000ff);
rk[13] = rk[5] ^ rk[12];
rk[14] = rk[6] ^ rk[13];
rk[15] = rk[7] ^ rk[14];
rk += 8;
}
}
return 0;
}
int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey) {
uint32_t *rk;
int i, j, status;
uint32_t temp;
// first, start with an encryption schedule
status = AES_set_encrypt_key(key, bits, aeskey);
if (status < 0) {
return status;
}
rk = aeskey->rd_key;
// invert the order of the round keys:
for (i = 0, j = 4 * aeskey->rounds; i < j; i += 4, j -= 4) {
temp = rk[i];
rk[i] = rk[j];
rk[j] = temp;
temp = rk[i + 1];
rk[i + 1] = rk[j + 1];
rk[j + 1] = temp;
temp = rk[i + 2];
rk[i + 2] = rk[j + 2];
rk[j + 2] = temp;
temp = rk[i + 3];
rk[i + 3] = rk[j + 3];
rk[j + 3] = temp;
}
// apply the inverse MixColumn transform to all round keys but the first and
// the last:
for (i = 1; i < (int)aeskey->rounds; i++) {
rk += 4;
rk[0] =
Td0[Te1[(rk[0] >> 24)] & 0xff] ^ Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[0]) & 0xff] & 0xff];
rk[1] =
Td0[Te1[(rk[1] >> 24)] & 0xff] ^ Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[1]) & 0xff] & 0xff];
rk[2] =
Td0[Te1[(rk[2] >> 24)] & 0xff] ^ Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[2]) & 0xff] & 0xff];
rk[3] =
Td0[Te1[(rk[3] >> 24)] & 0xff] ^ Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te1[(rk[3]) & 0xff] & 0xff];
}
return 0;
}
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
const uint32_t *rk;
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
int r;
assert(in && out && key);
rk = key->rd_key;
// map byte array block to cipher state
// and add initial round key:
s0 = GETU32(in) ^ rk[0];
s1 = GETU32(in + 4) ^ rk[1];
s2 = GETU32(in + 8) ^ rk[2];
s3 = GETU32(in + 12) ^ rk[3];
// Nr - 1 full rounds:
r = key->rounds >> 1;
for (;;) {
t0 = Te0[(s0 >> 24)] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[(s3) & 0xff] ^ rk[4];
t1 = Te0[(s1 >> 24)] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[(s0) & 0xff] ^ rk[5];
t2 = Te0[(s2 >> 24)] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[(s1) & 0xff] ^ rk[6];
t3 = Te0[(s3 >> 24)] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[(s2) & 0xff] ^ rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 = Te0[(t0 >> 24)] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[(t3) & 0xff] ^ rk[0];
s1 = Te0[(t1 >> 24)] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[(t0) & 0xff] ^ rk[1];
s2 = Te0[(t2 >> 24)] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[(t1) & 0xff] ^ rk[2];
s3 = Te0[(t3 >> 24)] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[(t2) & 0xff] ^ rk[3];
}
// apply last round and map cipher state to byte array block:
s0 = (Te2[(t0 >> 24)] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(out, s0);
s1 = (Te2[(t1 >> 24)] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(out + 4, s1);
s2 = (Te2[(t2 >> 24)] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(out + 8, s2);
s3 = (Te2[(t3 >> 24)] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(out + 12, s3);
}
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
const uint32_t *rk;
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
int r;
assert(in && out && key);
rk = key->rd_key;
// map byte array block to cipher state
// and add initial round key:
s0 = GETU32(in) ^ rk[0];
s1 = GETU32(in + 4) ^ rk[1];
s2 = GETU32(in + 8) ^ rk[2];
s3 = GETU32(in + 12) ^ rk[3];
// Nr - 1 full rounds:
r = key->rounds >> 1;
for (;;) {
t0 = Td0[(s0 >> 24)] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[(s1) & 0xff] ^ rk[4];
t1 = Td0[(s1 >> 24)] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[(s2) & 0xff] ^ rk[5];
t2 = Td0[(s2 >> 24)] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[(s3) & 0xff] ^ rk[6];
t3 = Td0[(s3 >> 24)] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[(s0) & 0xff] ^ rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 = Td0[(t0 >> 24)] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[(t1) & 0xff] ^ rk[0];
s1 = Td0[(t1 >> 24)] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[(t2) & 0xff] ^ rk[1];
s2 = Td0[(t2 >> 24)] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[(t3) & 0xff] ^ rk[2];
s3 = Td0[(t3 >> 24)] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[(t0) & 0xff] ^ rk[3];
}
// apply last round and
// map cipher state to byte array block:
s0 = ((uint32_t)Td4[(t0 >> 24)] << 24) ^
((uint32_t)Td4[(t3 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t2 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t1) & 0xff]) ^ rk[0];
PUTU32(out, s0);
s1 = ((uint32_t)Td4[(t1 >> 24)] << 24) ^
((uint32_t)Td4[(t0 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t3 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t2) & 0xff]) ^ rk[1];
PUTU32(out + 4, s1);
s2 = ((uint32_t)Td4[(t2 >> 24)] << 24) ^
((uint32_t)Td4[(t1 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t0 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t3) & 0xff]) ^ rk[2];
PUTU32(out + 8, s2);
s3 = ((uint32_t)Td4[(t3 >> 24)] << 24) ^
((uint32_t)Td4[(t2 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t1 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t0) & 0xff]) ^ rk[3];
PUTU32(out + 12, s3);
}
#endif // NO_ASM || (!X86 && !X86_64 && !ARM)
// Be aware that different sets of AES functions use incompatible key
// representations, varying in format of the key schedule, the |AES_KEY.rounds|
// value, or both. Therefore they cannot mix. Also, on AArch64, the plain-C
File diff suppressed because it is too large Load Diff
+24 -259
View File
@@ -16,14 +16,12 @@
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <memory>
#include <vector>
#include <gtest/gtest.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include "internal.h"
#include "../../internal.h"
@@ -177,7 +175,7 @@ TEST(AESTest, WycheproofKeyWrap) {
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
if (result.IsValid()) {
if (result != WycheproofResult::kInvalid) {
ASSERT_GE(ct.size(), 8u);
AES_KEY aes;
@@ -219,10 +217,7 @@ TEST(AESTest, WycheproofKeyWrapWithPadding) {
// should pass. However, both RFC 5649 and SP 800-38F section 5.3.1 say that
// the minimum length is one. Therefore we consider test cases with an empty
// message to be invalid.
//
// Wycheproof marks various weak parameters as acceptable. We do not enforce
// policy in the library, so we map those flags to valid.
if (result.IsValid({"SmallKey", "WeakWrapping"}) && !msg.empty()) {
if (result != WycheproofResult::kInvalid && !msg.empty()) {
AES_KEY aes;
ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
std::vector<uint8_t> out(ct.size() - 8);
@@ -288,9 +283,28 @@ TEST(AESTest, ABI) {
block_counts = {0, 1, 8};
}
CHECK_ABI(aes_nohw_set_encrypt_key, kKey, bits, &key);
CHECK_ABI(aes_nohw_encrypt, block, block, &key);
#if defined(AES_NOHW_CBC)
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
CHECK_ABI(aes_nohw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
block, AES_ENCRYPT);
}
#endif
CHECK_ABI(aes_nohw_set_decrypt_key, kKey, bits, &key);
CHECK_ABI(aes_nohw_decrypt, block, block, &key);
#if defined(AES_NOHW_CBC)
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
CHECK_ABI(aes_nohw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
block, AES_DECRYPT);
}
#endif
if (bsaes_capable()) {
vpaes_set_encrypt_key(kKey, bits, &key);
CHECK_ABI(vpaes_encrypt_key_to_bsaes, &key, &key);
aes_nohw_set_encrypt_key(kKey, bits, &key);
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
if (blocks != 0) {
@@ -298,8 +312,7 @@ TEST(AESTest, ABI) {
}
}
vpaes_set_decrypt_key(kKey, bits, &key);
CHECK_ABI(vpaes_decrypt_key_to_bsaes, &key, &key);
aes_nohw_set_decrypt_key(kKey, bits, &key);
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
CHECK_ABI(bsaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
@@ -312,10 +325,8 @@ TEST(AESTest, ABI) {
CHECK_ABI(vpaes_encrypt, block, block, &key);
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
#if defined(VPAES_CBC)
CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
block, AES_ENCRYPT);
#endif
#if defined(VPAES_CTR32)
CHECK_ABI(vpaes_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
#endif
@@ -323,13 +334,11 @@ TEST(AESTest, ABI) {
CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key);
CHECK_ABI(vpaes_decrypt, block, block, &key);
#if defined(VPAES_CBC)
for (size_t blocks : block_counts) {
SCOPED_TRACE(blocks);
CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
block, AES_DECRYPT);
}
#endif // VPAES_CBC
}
if (hwaes_capable()) {
@@ -361,247 +370,3 @@ TEST(AESTest, ABI) {
}
}
#endif // SUPPORTS_ABI_TEST
#if defined(BSAES) && !defined(BORINGSSL_SHARED_LIBRARY)
static Bytes AESKeyToBytes(const AES_KEY *key) {
return Bytes(reinterpret_cast<const uint8_t *>(key), sizeof(*key));
}
static uint8_t aes_ref_sub_byte(uint8_t b) {
static const uint8_t kSBox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16,
};
return kSBox[b];
}
static uint32_t aes_ref_sub_word(uint32_t in) {
uint32_t a0 = aes_ref_sub_byte(in);
uint32_t a1 = aes_ref_sub_byte(in >> 8);
uint32_t a2 = aes_ref_sub_byte(in >> 16);
uint32_t a3 = aes_ref_sub_byte(in >> 24);
return a0 | (a1 << 8) | (a2 << 16) | (a3 << 24);
}
static uint32_t aes_ref_rot_word(uint32_t in, uint32_t n) {
return (in >> n) | (in << (32 - n));
}
static int aes_ref_set_encrypt_key(const uint8_t *key, int key_bits,
AES_KEY *out) {
static const uint32_t kRCon[10] = {0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36};
switch (key_bits) {
case 128:
out->rounds = 10;
break;
case 192:
out->rounds = 12;
break;
case 256:
out->rounds = 14;
break;
default:
return 1;
}
size_t words = key_bits / 32;
size_t num_subkey_words = (out->rounds + 1) * 4;
OPENSSL_memcpy(out->rd_key, key, words * sizeof(uint32_t));
for (size_t i = words; i < num_subkey_words; i++) {
uint32_t tmp = out->rd_key[i - 1];
if (i % words == 0) {
tmp = aes_ref_sub_word(aes_ref_rot_word(tmp, 8)) ^ kRCon[(i / words) - 1];
} else if (key_bits == 256 && i % 4 == 0) {
tmp = aes_ref_sub_word(tmp);
}
out->rd_key[i] = tmp ^ out->rd_key[i - words];
}
// The ARM bsaes implementation expects all the keys to be byteswapped.
for (size_t i = 0; i < num_subkey_words; i++) {
out->rd_key[i] = CRYPTO_bswap4(out->rd_key[i]);
}
return 0;
}
static void aes_ref_inv_mix_columns(uint32_t block[4]) {
// This tables was generated with the following Python script:
// clang-format off
/*
def mul_unreduced(a, b):
c = 0
for i in range(8):
if b & (1 << i):
c ^= a << i
return c
def mul(a, b):
c = mul_unreduced(a, b)
# c's highest term is at most x^14.
c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
# c's highest term is at most x^10.
c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
# c's highest term is at most x^7.
assert (c >> 8) == 0
return c
def inv_mix_column(a):
ret = 0
for b in [0x0e, 0x09, 0x0d, 0x0b]:
ret <<= 8
ret |= mul(a, b)
return ret
body = ", ".join("0x%08x" % inv_mix_column(a) for a in range(256))
print("static const uint32_t kTable[256] = {%s};\n" % body)
*/
// clang-format on
// kInvMixColumn[i] is the result of InvMixColumns applied to a column
// containing [i, 0, 0, 0]. (The contributions of the other positions are
// computed by rotating bytes.)
static const uint32_t kInvMixColumn[256] = {
0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927,
0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb,
0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf,
0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28,
0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec,
0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd,
0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89,
0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815,
0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa,
0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8,
0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36,
0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742,
0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4,
0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360,
0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87,
0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3,
0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f,
0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26,
0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba,
0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce,
0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929,
0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed,
0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3};
// Note |block| is byte-swapped so block[i] >> 24 is the first element of
// block[i]. (See |aes_ref_set_encrypt_key|).
for (size_t i = 0; i < 4; i++) {
uint32_t in = block[i];
block[i] = kInvMixColumn[in >> 24];
block[i] ^= aes_ref_rot_word(kInvMixColumn[(in >> 16) & 0xff], 8);
block[i] ^= aes_ref_rot_word(kInvMixColumn[(in >> 8) & 0xff], 16);
block[i] ^= aes_ref_rot_word(kInvMixColumn[in & 0xff], 24);
}
}
static int aes_ref_set_decrypt_key(const uint8_t *key, int bits, AES_KEY *out) {
if (aes_ref_set_encrypt_key(key, bits, out) != 0) {
return 1;
}
// bsaes expects the decryption round keys in reverse order. Note there are
// |out->rounds + 1| round keys.
for (size_t i = 0; i < out->rounds / 2; i++) {
std::swap(out->rd_key[4 * i], out->rd_key[4 * (out->rounds - i)]);
std::swap(out->rd_key[4 * i + 1], out->rd_key[4 * (out->rounds - i) + 1]);
std::swap(out->rd_key[4 * i + 2], out->rd_key[4 * (out->rounds - i) + 2]);
std::swap(out->rd_key[4 * i + 3], out->rd_key[4 * (out->rounds - i) + 3]);
}
// bsaes expects round keys other than the first and last to have
// InvMixColumns applied.
for (size_t i = 1; i < out->rounds; i++) {
aes_ref_inv_mix_columns(out->rd_key + 4 * i);
}
return 0;
}
TEST(AESTest, VPAESToBSAESConvert) {
const int kNumIterations = 1000;
for (int i = 0; i < kNumIterations; i++) {
uint8_t key[256 / 8];
RAND_bytes(key, sizeof(key));
SCOPED_TRACE(Bytes(key));
for (unsigned bits : {128u, 192u, 256u}) {
SCOPED_TRACE(bits);
for (bool enc : {false, true}) {
SCOPED_TRACE(enc);
AES_KEY ref, vpaes, bsaes;
OPENSSL_memset(&ref, 0xaa, sizeof(ref));
OPENSSL_memset(&vpaes, 0xaa, sizeof(vpaes));
OPENSSL_memset(&bsaes, 0xaa, sizeof(bsaes));
if (enc) {
ASSERT_EQ(0, aes_ref_set_encrypt_key(key, bits, &ref));
ASSERT_EQ(0, vpaes_set_encrypt_key(key, bits, &vpaes));
vpaes_encrypt_key_to_bsaes(&bsaes, &vpaes);
} else {
ASSERT_EQ(0, aes_ref_set_decrypt_key(key, bits, &ref));
ASSERT_EQ(0, vpaes_set_decrypt_key(key, bits, &vpaes));
vpaes_decrypt_key_to_bsaes(&bsaes, &vpaes);
}
// Although not fatal, stop running if this fails, otherwise we'll spam
// the user's console.
ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
// Repeat the test in-place.
OPENSSL_memcpy(&bsaes, &vpaes, sizeof(AES_KEY));
if (enc) {
vpaes_encrypt_key_to_bsaes(&bsaes, &bsaes);
} else {
vpaes_decrypt_key_to_bsaes(&bsaes, &bsaes);
}
ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
}
}
}
}
#endif // BSAES && !SHARED_LIBRARY
+3000
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -84,7 +84,7 @@ open OUT,">$output";
&asm_init($ARGV[0]);
&external_label("OPENSSL_ia32cap_P");
&preprocessor_ifdef("BORINGSSL_DISPATCH_TEST")
&preprocessor_ifndef("NDEBUG")
&external_label("BORINGSSL_function_hit");
&preprocessor_endif();
&static_label("key_const");
+9 -3
View File
@@ -275,9 +275,11 @@ $code.=<<___;
.align 16
${PREFIX}_encrypt:
.cfi_startproc
#ifdef BORINGSSL_DISPATCH_TEST
#ifndef NDEBUG
#ifndef BORINGSSL_FIPS
.extern BORINGSSL_function_hit
movb \$1,BORINGSSL_function_hit+1(%rip)
#endif
#endif
movups ($inp),$inout0 # load input
mov 240($key),$rounds # key->rounds
@@ -1203,8 +1205,10 @@ $code.=<<___;
.align 16
${PREFIX}_ctr32_encrypt_blocks:
.cfi_startproc
#ifdef BORINGSSL_DISPATCH_TEST
#ifndef NDEBUG
#ifndef BORINGSSL_FIPS
movb \$1,BORINGSSL_function_hit(%rip)
#endif
#endif
cmp \$1,$len
jne .Lctr32_bulk
@@ -4350,8 +4354,10 @@ $code.=<<___;
${PREFIX}_set_encrypt_key:
__aesni_set_encrypt_key:
.cfi_startproc
#ifdef BORINGSSL_DISPATCH_TEST
#ifndef NDEBUG
#ifndef BORINGSSL_FIPS
movb \$1,BORINGSSL_function_hit+3(%rip)
#endif
#endif
.byte 0x48,0x83,0xEC,0x08 # sub rsp,8
.cfi_adjust_cfa_offset 8
+2 -4
View File
@@ -60,11 +60,9 @@ if ($flavour && $flavour ne "void") {
( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open OUT,">$output";
*STDOUT=*OUT;
open STDOUT,">$output";
}
my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -69,7 +69,7 @@ $PREFIX="vpaes";
my ($round, $base, $magic, $key, $const, $inp, $out)=
("eax", "ebx", "ecx", "edx","ebp", "esi","edi");
&preprocessor_ifdef("BORINGSSL_DISPATCH_TEST")
&preprocessor_ifndef("NDEBUG")
&external_label("BORINGSSL_function_hit");
&preprocessor_endif();
&static_label("_vpaes_consts");
+8 -4
View File
@@ -182,11 +182,11 @@ _vpaes_encrypt_core:
##
## Inputs:
## %xmm0 and %xmm6 = input
## %xmm9 and %xmm10 as in _vpaes_preheat
## %xmm12-%xmm15 as in _vpaes_preheat
## (%rdx) = scheduled keys
##
## Output in %xmm0 and %xmm6
## Clobbers %xmm1-%xmm5, %xmm7, %xmm8, %xmm11-%xmm13, %r9, %r10, %r11, %rax
## Clobbers %xmm1-%xmm5, %xmm7-%xmm11, %r9, %r10, %r11, %rax
## Preserves %xmm14 and %xmm15
##
## This function stitches two parallel instances of _vpaes_encrypt_core. x86_64
@@ -871,10 +871,12 @@ _vpaes_schedule_mangle:
.align 16
${PREFIX}_set_encrypt_key:
.cfi_startproc
#ifdef BORINGSSL_DISPATCH_TEST
#ifndef NDEBUG
#ifndef BORINGSSL_FIPS
.extern BORINGSSL_function_hit
movb \$1, BORINGSSL_function_hit+5(%rip)
#endif
#endif
___
$code.=<<___ if ($win64);
@@ -981,10 +983,12 @@ $code.=<<___;
.align 16
${PREFIX}_encrypt:
.cfi_startproc
#ifdef BORINGSSL_DISPATCH_TEST
#ifndef NDEBUG
#ifndef BORINGSSL_FIPS
.extern BORINGSSL_function_hit
movb \$1, BORINGSSL_function_hit+4(%rip)
#endif
#endif
___
$code.=<<___ if ($win64);
lea -0xb8(%rsp),%rsp
+9 -26
View File
@@ -38,7 +38,6 @@ OPENSSL_INLINE int hwaes_capable(void) {
#if defined(OPENSSL_X86_64)
#define VPAES_CTR32
#endif
#define VPAES_CBC
OPENSSL_INLINE int vpaes_capable(void) {
return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0;
}
@@ -50,15 +49,11 @@ OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); }
#if defined(OPENSSL_ARM)
#define BSAES
#define VPAES
#define VPAES_CTR32
OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); }
OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
#endif
#if defined(OPENSSL_AARCH64)
#define VPAES
#define VPAES_CBC
#define VPAES_CTR32
OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
#endif
@@ -135,14 +130,12 @@ void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
#if defined(BSAES)
// Note |bsaes_cbc_encrypt| requires |enc| to be zero.
// On platforms where BSAES gets defined (just above), then these functions are
// provided by asm. Note |bsaes_cbc_encrypt| requires |enc| to be zero.
void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t ivec[16], int enc);
void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, const uint8_t ivec[16]);
// VPAES to BSAES conversions are available on all BSAES platforms.
void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
#else
OPENSSL_INLINE char bsaes_capable(void) { return 0; }
@@ -159,16 +152,6 @@ OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
const uint8_t ivec[16]) {
abort();
}
OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes,
const AES_KEY *vpaes) {
abort();
}
OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes,
const AES_KEY *vpaes) {
abort();
}
#endif // !BSAES
@@ -181,10 +164,8 @@ int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
#if defined(VPAES_CBC)
void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int enc);
#endif
#if defined(VPAES_CTR32)
void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, const uint8_t ivec[16]);
@@ -218,17 +199,19 @@ OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
#endif // !VPAES
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
size_t blocks, const AES_KEY *key,
const uint8_t ivec[16]);
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
#define AES_NOHW_CBC
void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t *ivec, const int enc);
#endif
#if defined(__cplusplus)
+3 -17
View File
@@ -57,23 +57,7 @@
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE],
uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) {
if (hwaes_capable()) {
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
aes_hw_ctr32_encrypt_blocks);
} else if (vpaes_capable()) {
#if defined(VPAES_CTR32)
// TODO(davidben): On ARM, where |BSAES| is additionally defined, this could
// use |vpaes_ctr32_encrypt_blocks_with_bsaes|.
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
vpaes_ctr32_encrypt_blocks);
#else
CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num,
vpaes_encrypt);
#endif
} else {
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
aes_nohw_ctr32_encrypt_blocks);
}
CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num, AES_encrypt);
}
void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key,
@@ -95,10 +79,12 @@ void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
return;
}
#if defined(AES_NOHW_CBC)
if (!vpaes_capable()) {
aes_nohw_cbc_encrypt(in, out, len, key, ivec, enc);
return;
}
#endif
if (enc) {
CRYPTO_cbc128_encrypt(in, out, len, key, ivec, AES_encrypt);
} else {
+7 -88
View File
@@ -19,10 +19,6 @@
#include <openssl/crypto.h>
#include <stdlib.h>
#if defined(BORINGSSL_FIPS)
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <openssl/digest.h>
#include <openssl/hmac.h>
@@ -31,7 +27,6 @@
#include "../internal.h"
#include "aes/aes.c"
#include "aes/aes_nohw.c"
#include "aes/key_wrap.c"
#include "aes/mode_wrappers.c"
#include "bn/add.c"
@@ -70,7 +65,7 @@
#include "ec/felem.c"
#include "ec/oct.c"
#include "ec/p224-64.c"
#include "ec/p256.c"
#include "../../third_party/fiat/p256.c"
#include "ec/p256-x86_64.c"
#include "ec/scalar.c"
#include "ec/simple.c"
@@ -81,14 +76,13 @@
#include "md4/md4.c"
#include "md5/md5.c"
#include "modes/cbc.c"
#include "modes/ccm.c"
#include "modes/cfb.c"
#include "modes/ctr.c"
#include "modes/gcm.c"
#include "modes/gcm_nohw.c"
#include "modes/ofb.c"
#include "modes/polyval.c"
#include "rand/ctrdrbg.c"
#include "rand/fork_detect.c"
#include "rand/rand.c"
#include "rand/urandom.c"
#include "rsa/blinding.c"
@@ -106,7 +100,6 @@
#if defined(BORINGSSL_FIPS)
#if !defined(OPENSSL_ASAN)
// These symbols are filled in by delocate.go (in static builds) or a linker
// script (in shared builds). They point to the start and end of the module, and
// the location of the integrity hash, respectively.
@@ -117,49 +110,7 @@ extern const uint8_t BORINGSSL_bcm_text_hash[];
extern const uint8_t BORINGSSL_bcm_rodata_start[];
extern const uint8_t BORINGSSL_bcm_rodata_end[];
#endif
// assert_within is used to sanity check that certain symbols are within the
// bounds of the integrity check. It checks that start <= symbol < end and
// aborts otherwise.
static void assert_within(const void *start, const void *symbol,
const void *end) {
const uintptr_t start_val = (uintptr_t) start;
const uintptr_t symbol_val = (uintptr_t) symbol;
const uintptr_t end_val = (uintptr_t) end;
if (start_val <= symbol_val && symbol_val < end_val) {
return;
}
fprintf(
stderr,
"FIPS module doesn't span expected symbol. Expected %p <= %p < %p\n",
start, symbol, end);
BORINGSSL_FIPS_abort();
}
#if defined(OPENSSL_ANDROID) && defined(OPENSSL_AARCH64)
static void BORINGSSL_maybe_set_module_text_permissions(int permission) {
// Android may be compiled in execute-only-memory mode, in which case the
// .text segment cannot be read. That conflicts with the need for a FIPS
// module to hash its own contents, therefore |mprotect| is used to make
// the module's .text readable for the duration of the hashing process. In
// other build configurations this is a no-op.
const uintptr_t page_size = getpagesize();
const uintptr_t page_start =
((uintptr_t)BORINGSSL_bcm_text_start) & ~(page_size - 1);
if (mprotect((void *)page_start,
((uintptr_t)BORINGSSL_bcm_text_end) - page_start,
permission) != 0) {
perror("BoringSSL: mprotect");
}
}
#else
static void BORINGSSL_maybe_set_module_text_permissions(int permission) {}
#endif // !ANDROID
#endif // !ASAN
#endif
static void __attribute__((constructor))
BORINGSSL_bcm_power_on_self_test(void) {
@@ -170,48 +121,22 @@ BORINGSSL_bcm_power_on_self_test(void) {
// .text section, which triggers the global-buffer overflow detection.
const uint8_t *const start = BORINGSSL_bcm_text_start;
const uint8_t *const end = BORINGSSL_bcm_text_end;
assert_within(start, AES_encrypt, end);
assert_within(start, RSA_sign, end);
assert_within(start, RAND_bytes, end);
assert_within(start, EC_GROUP_cmp, end);
assert_within(start, SHA256_Update, end);
assert_within(start, ECDSA_do_verify, end);
assert_within(start, EVP_AEAD_CTX_seal, end);
#if defined(BORINGSSL_SHARED_LIBRARY)
const uint8_t *const rodata_start = BORINGSSL_bcm_rodata_start;
const uint8_t *const rodata_end = BORINGSSL_bcm_rodata_end;
#else
// In the static build, read-only data is placed within the .text segment.
const uint8_t *const rodata_start = BORINGSSL_bcm_text_start;
const uint8_t *const rodata_end = BORINGSSL_bcm_text_end;
#endif
assert_within(rodata_start, kPrimes, rodata_end);
assert_within(rodata_start, des_skb, rodata_end);
assert_within(rodata_start, kP256Params, rodata_end);
assert_within(rodata_start, kPKCS1SigPrefixes, rodata_end);
#if defined(OPENSSL_ANDROID)
uint8_t result[SHA256_DIGEST_LENGTH];
const EVP_MD *const kHashFunction = EVP_sha256();
#else
uint8_t result[SHA512_DIGEST_LENGTH];
const EVP_MD *const kHashFunction = EVP_sha512();
#endif
static const uint8_t kHMACKey[64] = {0};
uint8_t result[SHA512_DIGEST_LENGTH];
unsigned result_len;
HMAC_CTX hmac_ctx;
HMAC_CTX_init(&hmac_ctx);
if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), kHashFunction,
if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), EVP_sha512(),
NULL /* no ENGINE */)) {
fprintf(stderr, "HMAC_Init_ex failed.\n");
goto err;
}
BORINGSSL_maybe_set_module_text_permissions(PROT_READ | PROT_EXEC);
#if defined(BORINGSSL_SHARED_LIBRARY)
uint64_t length = end - start;
HMAC_Update(&hmac_ctx, (const uint8_t *) &length, sizeof(length));
@@ -223,8 +148,6 @@ BORINGSSL_bcm_power_on_self_test(void) {
#else
HMAC_Update(&hmac_ctx, start, end - start);
#endif
BORINGSSL_maybe_set_module_text_permissions(PROT_EXEC);
if (!HMAC_Final(&hmac_ctx, result, &result_len) ||
result_len != sizeof(result)) {
fprintf(stderr, "HMAC failed.\n");
@@ -237,15 +160,11 @@ BORINGSSL_bcm_power_on_self_test(void) {
if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) {
goto err;
}
#endif
if (!boringssl_fips_self_test(BORINGSSL_bcm_text_hash, sizeof(result))) {
goto err;
}
#else
if (!BORINGSSL_self_test()) {
goto err;
}
#endif // OPENSSL_ASAN
return;
+2 -4
View File
@@ -64,11 +64,9 @@ if ($flavour && $flavour ne "void") {
( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open OUT,">$output";
*STDOUT=*OUT;
open STDOUT,">$output";
}
$num="r0"; # starts as num argument, but holds &tp[num-1]
+209
View File
@@ -27,6 +27,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&bn_div_words("bn_div_words");
&bn_add_words("bn_add_words");
&bn_sub_words("bn_sub_words");
&bn_sub_part_words("bn_sub_part_words");
&asm_finish();
@@ -574,3 +575,211 @@ sub bn_sub_words
&function_end($name);
}
sub bn_sub_part_words
{
local($name)=@_;
&function_begin($name,"");
&comment("");
$a="esi";
$b="edi";
$c="eax";
$r="ebx";
$tmp1="ecx";
$tmp2="edx";
$num="ebp";
&mov($r,&wparam(0)); # get r
&mov($a,&wparam(1)); # get a
&mov($b,&wparam(2)); # get b
&mov($num,&wparam(3)); # get num
&xor($c,$c); # clear carry
&and($num,0xfffffff8); # num / 8
&jz(&label("aw_finish"));
&set_label("aw_loop",0);
for ($i=0; $i<8; $i++)
{
&comment("Round $i");
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
&mov($tmp2,&DWP($i*4,$b,"",0)); # *b
&sub($tmp1,$c);
&mov($c,0);
&adc($c,$c);
&sub($tmp1,$tmp2);
&adc($c,0);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
}
&comment("");
&add($a,32);
&add($b,32);
&add($r,32);
&sub($num,8);
&jnz(&label("aw_loop"));
&set_label("aw_finish",0);
&mov($num,&wparam(3)); # get num
&and($num,7);
&jz(&label("aw_end"));
for ($i=0; $i<7; $i++)
{
&comment("Tail Round $i");
&mov($tmp1,&DWP(0,$a,"",0)); # *a
&mov($tmp2,&DWP(0,$b,"",0));# *b
&sub($tmp1,$c);
&mov($c,0);
&adc($c,$c);
&sub($tmp1,$tmp2);
&adc($c,0);
&mov(&DWP(0,$r,"",0),$tmp1); # *r
&add($a, 4);
&add($b, 4);
&add($r, 4);
&dec($num) if ($i != 6);
&jz(&label("aw_end")) if ($i != 6);
}
&set_label("aw_end",0);
&cmp(&wparam(4),0);
&je(&label("pw_end"));
&mov($num,&wparam(4)); # get dl
&cmp($num,0);
&je(&label("pw_end"));
&jge(&label("pw_pos"));
&comment("pw_neg");
&mov($tmp2,0);
&sub($tmp2,$num);
&mov($num,$tmp2);
&and($num,0xfffffff8); # num / 8
&jz(&label("pw_neg_finish"));
&set_label("pw_neg_loop",0);
for ($i=0; $i<8; $i++)
{
&comment("dl<0 Round $i");
&mov($tmp1,0);
&mov($tmp2,&DWP($i*4,$b,"",0)); # *b
&sub($tmp1,$c);
&mov($c,0);
&adc($c,$c);
&sub($tmp1,$tmp2);
&adc($c,0);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
}
&comment("");
&add($b,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_neg_loop"));
&set_label("pw_neg_finish",0);
&mov($tmp2,&wparam(4)); # get dl
&mov($num,0);
&sub($num,$tmp2);
&and($num,7);
&jz(&label("pw_end"));
for ($i=0; $i<7; $i++)
{
&comment("dl<0 Tail Round $i");
&mov($tmp1,0);
&mov($tmp2,&DWP($i*4,$b,"",0));# *b
&sub($tmp1,$c);
&mov($c,0);
&adc($c,$c);
&sub($tmp1,$tmp2);
&adc($c,0);
&dec($num) if ($i != 6);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&jz(&label("pw_end")) if ($i != 6);
}
&jmp(&label("pw_end"));
&set_label("pw_pos",0);
&and($num,0xfffffff8); # num / 8
&jz(&label("pw_pos_finish"));
&set_label("pw_pos_loop",0);
for ($i=0; $i<8; $i++)
{
&comment("dl>0 Round $i");
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
&sub($tmp1,$c);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&jnc(&label("pw_nc".$i));
}
&comment("");
&add($a,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_pos_loop"));
&set_label("pw_pos_finish",0);
&mov($num,&wparam(4)); # get dl
&and($num,7);
&jz(&label("pw_end"));
for ($i=0; $i<7; $i++)
{
&comment("dl>0 Tail Round $i");
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
&sub($tmp1,$c);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&jnc(&label("pw_tail_nc".$i));
&dec($num) if ($i != 6);
&jz(&label("pw_end")) if ($i != 6);
}
&mov($c,1);
&jmp(&label("pw_end"));
&set_label("pw_nc_loop",0);
for ($i=0; $i<8; $i++)
{
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&set_label("pw_nc".$i,0);
}
&comment("");
&add($a,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_nc_loop"));
&mov($num,&wparam(4)); # get dl
&and($num,7);
&jz(&label("pw_nc_end"));
for ($i=0; $i<7; $i++)
{
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&set_label("pw_tail_nc".$i,0);
&dec($num) if ($i != 6);
&jz(&label("pw_nc_end")) if ($i != 6);
}
&set_label("pw_nc_end",0);
&mov($c,0);
&set_label("pw_end",0);
# &mov("eax",$c); # $c is "eax"
&function_end($name);
}
-17
View File
@@ -384,23 +384,6 @@ int bn_expand(BIGNUM *bn, size_t bits) {
}
int bn_resize_words(BIGNUM *bn, size_t words) {
#if defined(OPENSSL_PPC64LE)
// This is a workaround for a miscompilation bug in Clang 7.0.1 on POWER.
// The unittests catch the miscompilation, if it occurs, and it manifests
// as a crash in |bn_fits_in_words|.
//
// The bug only triggers if building in FIPS mode and with -O3. Clang 8.0.1
// has the same bug but this workaround is not effective there---I've not
// been able to find a workaround for 8.0.1.
//
// At the time of writing (2019-08-08), Clang git does *not* have this bug
// and does not need this workaroud. The current git version should go on to
// be Clang 10 thus, once we can depend on that, this can be removed.
if (value_barrier_w((size_t)bn->width == words)) {
return 1;
}
#endif
if ((size_t)bn->width <= words) {
if (!bn_wexpand(bn, words)) {
return 0;
+24 -335
View File
@@ -73,7 +73,6 @@
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <utility>
#include <gtest/gtest.h>
@@ -92,7 +91,6 @@
#include "../../test/abi_test.h"
#include "../../test/file_test.h"
#include "../../test/test_util.h"
#include "../../test/wycheproof_util.h"
static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
@@ -659,26 +657,11 @@ static void TestModMul(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_mod_mul_montgomery_small(r_words.get(), a_words.get(), b_words.get(),
m_width, mont.get());
// Use the second half of |tmp| so ASan will catch out-of-bounds writes.
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
bn_from_montgomery_small(r_words.get(), r_words.get(), m_width,
mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A * B (mod M) (Montgomery, words)", mod_mul.get(),
ret.get());
// |bn_from_montgomery_small| must additionally work on double-width
// inputs. Test this by running |bn_from_montgomery_small| on the result
// of a product. Note |a_words| * |b_words| has an extra factor of R^2, so
// we must reduce twice.
std::unique_ptr<BN_ULONG[]> prod_words(new BN_ULONG[m_width * 2]);
bn_mul_small(prod_words.get(), m_width * 2, a_words.get(), m_width,
b_words.get(), m_width);
bn_from_montgomery_small(r_words.get(), m_width, prod_words.get(),
m_width * 2, mont.get());
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A * B (mod M) (Montgomery, words)",
mod_mul.get(), ret.get());
}
#endif
}
@@ -736,8 +719,7 @@ static void TestModSquare(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_to_montgomery_small(a_words.get(), a_words.get(), m_width, mont.get());
bn_mod_mul_montgomery_small(r_words.get(), a_words.get(), a_words.get(),
m_width, mont.get());
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
mont.get());
bn_from_montgomery_small(r_words.get(), r_words.get(), m_width, mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A * A (mod M) (Montgomery, words)",
mod_square.get(), ret.get());
@@ -748,7 +730,7 @@ static void TestModSquare(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_mod_mul_montgomery_small(r_words.get(), a_words.get(),
a_copy_words.get(), m_width, mont.get());
// Use the second half of |tmp| so ASan will catch out-of-bounds writes.
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
bn_from_montgomery_small(r_words.get(), r_words.get(), m_width,
mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A * A_copy (mod M) (Montgomery, words)",
@@ -799,7 +781,7 @@ static void TestModExp(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_to_montgomery_small(a_words.get(), a_words.get(), m_width, mont.get());
bn_mod_exp_mont_small(r_words.get(), a_words.get(), m_width, e->d,
e->width, mont.get());
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
bn_from_montgomery_small(r_words.get(), r_words.get(), m_width,
mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A ^ E (mod M) (Montgomery, words)", mod_exp.get(),
@@ -2004,17 +1986,16 @@ TEST_F(BNTest, PrimeChecking) {
ASSERT_TRUE(BN_set_word(p.get(), i));
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_1, p.get(), BN_prime_checks_for_generation, ctx(),
&is_probably_prime_1, p.get(), BN_prime_checks, ctx(),
false /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(is_prime ? 1 : 0, is_probably_prime_1);
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_2, p.get(), BN_prime_checks_for_generation, ctx(),
&is_probably_prime_2, p.get(), BN_prime_checks, ctx(),
true /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(is_prime ? 1 : 0, is_probably_prime_2);
if (i > 3 && i % 2 == 1) {
ASSERT_TRUE(BN_enhanced_miller_rabin_primality_test(
&result_3, p.get(), BN_prime_checks_for_generation, ctx(),
nullptr /* callback */));
&result_3, p.get(), BN_prime_checks, ctx(), nullptr /* callback */));
EXPECT_EQ(is_prime, result_3 == bn_probably_prime);
}
}
@@ -2022,19 +2003,19 @@ TEST_F(BNTest, PrimeChecking) {
// Negative numbers are not prime.
ASSERT_TRUE(BN_set_word(p.get(), 7));
BN_set_negative(p.get(), 1);
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_1, p.get(), BN_prime_checks_for_generation, ctx(),
false /* do_trial_division */, nullptr /* callback */));
ASSERT_TRUE(BN_primality_test(&is_probably_prime_1, p.get(), BN_prime_checks,
ctx(), false /* do_trial_division */,
nullptr /* callback */));
EXPECT_EQ(0, is_probably_prime_1);
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_2, p.get(), BN_prime_checks_for_generation, ctx(),
true /* do_trial_division */, nullptr /* callback */));
ASSERT_TRUE(BN_primality_test(&is_probably_prime_2, p.get(), BN_prime_checks,
ctx(), true /* do_trial_division */,
nullptr /* callback */));
EXPECT_EQ(0, is_probably_prime_2);
static const char *kComposites[] = {
// The following composite numbers come from http://oeis.org/A014233 and
// are such that the first several primes are not a Miller-Rabin composite
// witness.
// The following composite numbers come from http://oeis.org/A014233 and are
// such that the first several primes are not a Rabin-Miller composite
// witness.
static const char *kA014233[] = {
"2047",
"1373653",
"25326001",
@@ -2045,326 +2026,34 @@ TEST_F(BNTest, PrimeChecking) {
"3825123056546413051",
"318665857834031151167461",
"3317044064679887385961981",
// The following composite numbers come from https://oeis.org/A033181
// which lists Euler pseudoprimes. These are false positives for the
// Fermat primality
// test.
"1729",
"2465",
"15841",
"41041",
"46657",
"75361",
"162401",
"172081",
"399001",
"449065",
"488881",
"530881",
"656601",
"670033",
"838201",
"997633",
"1050985",
"1615681",
"1773289",
"1857241",
"2113921",
"2433601",
"2455921",
"2704801",
"3057601",
"3224065",
"3581761",
"3664585",
"3828001",
"4463641",
"4903921",
};
for (const char *str : kComposites) {
for (const char *str : kA014233) {
SCOPED_TRACE(str);
EXPECT_NE(0, DecimalToBIGNUM(&p, str));
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_1, p.get(), BN_prime_checks_for_generation, ctx(),
&is_probably_prime_1, p.get(), BN_prime_checks, ctx(),
false /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(0, is_probably_prime_1);
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_2, p.get(), BN_prime_checks_for_generation, ctx(),
&is_probably_prime_2, p.get(), BN_prime_checks, ctx(),
true /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(0, is_probably_prime_2);
ASSERT_TRUE(BN_enhanced_miller_rabin_primality_test(
&result_3, p.get(), BN_prime_checks_for_generation, ctx(),
nullptr /* callback */));
&result_3, p.get(), BN_prime_checks, ctx(), nullptr /* callback */));
EXPECT_EQ(bn_composite, result_3);
}
static const char *kPrimesHex[] = {
// Various primes extracted from openssl genrsa:
// 512-bit primes.
"ebb00348b1308e29166f0401f7415cc3bf9c746460bcadfd1ad6838b6472f48f3afba0c1"
"446eddc4708c68e307a882771794fbba45799f5b062e090613ee8203",
"d9a896e15c5d0091e81825948f3111c615a32aa0bd9305b9591232138388176fe22ff765"
"63c893b95c0f9898029be67543144c5e76c837333f109a0ffc0fa3db",
"fdecb71e997f234111706cabdfdc515b7e7a2a8d77b3c3a4b4819493d39de84e791be692"
"9ce1c3f5136808504f351eca19884894f581f96fba2b8d652265efe9",
"dc37a778aa89eb4048267573421ac5b9d81a231d05191393bdf06a6a64c684968fd17c4f"
"41fbd5745df2ee447fcc04693e2e3fecec270145388032149da63b3f",
"fbf34841baa2dd4ecf9055328f4902532d80e82f6d8ea186311564b3680b39ea2162fed4"
"701f02bec9d5be19f2e505c58a68620ee8873e8ab8fe98506a8bf9bb",
"c3b3c3156c9d0bf3b27f9bf8274ddc8c8505bacbb4a9595d90354d1a472553d6ae3daa97"
"1396c0361f6355531de29bf8ef1d7b471b5f2267d4b49cbe48ced5f1",
"f8d1216de820efb437ca8070c5f4f34838c46cf354c998e253557cfc400eae7883d0a758"
"0b2e617cca527d9d6c598cbc03ca743791f88a5a065fea9583068f1b",
"cc12d224273b56e6765f6b42583d8da3c89ff531f14961351b5173a9017579cd7bb736e2"
"78e626a426ee5a583b8d6c7b3006687ca9df596902a281e9e9cf3ad5",
// 1024-bit primes.
"f3244013a1b0ec2fe53a684260077d2afc3b35ed77026c594091d92b2eb47fd1266095b8"
"7456cc451942f907079b8a9cd333d4bf22a892dbc632904a6423c5b19bb41fd43764a558"
"0e9a5960d84fadbebfbbfaa5ec39acb78a94937d11d7a62c54a0f983bc8b5507479290de"
"f4e979d3f24ce81f4c506ba3bfca4f402a3b11cf",
"e4a70bdbb96fefd5732e9e94f9d04b9ef16635642ee728d40626861db00d57950697e892"
"d0306de25ee35d5ccce1220e1b19fd2f98af2fdcac5796d860fd75aec31ed48baf5b39cf"
"77ebda6727e33e6f72735ab0121395deb54fd430212499043cd1e11f7d5852f146997952"
"d9959c83542b6cbad3c3a2ebb8698a0172e0c6d1",
"e85ad4595ea74bf886977f4a06120b6ae28ec2d7ee44b4bc8658a8a90a2a55311814dfed"
"ebd08f93e8241dcc87d91d6f6b498c6ec0576a7dad6e5d53b71f89fb985de290c0f02a78"
"f2143217c0b7ae1487a751ec27dfbd46046a06f5ebe337e05ed5d6fe8620b7f82b349c37"
"924d96128e42307fd708a74d608848cbdf6bc799",
"cc890f5fe88bfc4028a2ab5eff9dea7b150ffe75fb29f1904adb4709e86f74eaed44218c"
"d8058341a4b828d4fefeed5e34f50198bf643040037933f4305e1e01c3518279b9fa4131"
"e5afbc462efe9b5ddc4ab91ec2c12abf95b526bb2a6bd7b2bb1ce8203364502f7c3b87ff"
"585c94765505c20f728078a46759615ad23d4fb7",
"ebd8cd32804c6c1e7264de4f9bf1e4d2dbdaa23292c8f4688aa2770f664fe03513974e13"
"0a10ccc6b6ca95846dfecbd2d42285cf0212ff427ddb7cc222bfa459215ad4cc0f1f5fc7"
"4186bbbe96ca4de0d7c793ee050f8e10a242ab9bf03aae5b017b42c405ccee34f59ff501"
"5dbe4cab310bbb3ab50604f663cdb5af070d4a8d",
"e1dab2efc6ba8c980b86164e11fc6c6c4abb53701031de431db2b608ec75fd03c7cf07e6"
"e9d6c36da2a2aafe759f9c3e1522237d4dcae66ef03c86481428d58d4bcdffb919bb8da4"
"4b0ac1cc922d2d904c543b1a09961faf7304af4482dc839091b258523ab5e36302e1157f"
"3e6810513922c5d5c1f559e3a90b91e4cf2f0c9f",
"d76a082eb03584a6253555cf9813206a06c9fc2112b6425e030f12d7d807656175f4c58e"
"e367826ec0d89f03339fb520d7c8a735905e458f849827581e9db22fde302fc55db031fd"
"8f3afe1910eaaa8ed4d122de99fa0a66bf69b932ce84d095ffcb3f98e231199817ebc316"
"460df0c0769fef3f91777a9cf86ccf2e8233818b",
"d506fd2c6557a7f8cd0ac8f0f098bffdede4ee79f74ce6e9478d8651058ec56aa1f4683c"
"20729ee8d11d14b34170ce0cf419a7b22943d5fb443afb22e6a430fe993ac64737428f50"
"37d19398ee226484b5ca64af71012245d87aefbcbd71e867f6fbcc52e0e1c49f1363aec1"
"88c776abb67cda2fd6ce7be4bdbeee57fbafb07b",
// 1536-bit primes.
"f6aa5b151ea2cd151a720174d58c157e8dbbf3dbd93b102fcfb7ad3767cca8543d4fb168"
"7fb907561da1330c7878853859bc2b4b9d639d9b9bba4fce3a95cfd9151c19365e6ad634"
"7edc87acd4b79d2a7ce942c2a391c475cef2d4e347675487cc36a43f157562e32aff9d74"
"e15f228a0ecc8eca2392e04ddea8eda995789c94b9f85dde65e66b074c7843260ebdcd60"
"1cd49e2bf3ab83780281e4a56ada38b16e085f00c05bcce442daf1c9374a3ec2a2345309"
"5570aaa6bb3a3e4945312aed",
"e396e3ede4b0a33fe90b749b3dbc01fdb7d15e37cc3febe3f2b0ee6140204666fa4acb93"
"da893d0ce19d9e5eb09b7395394ced79261ba8b1a40ee977d1954a98031256c0e3f83c5b"
"ee234afddb80d4251b5f6f7493b3eb6156011e202fd4d8319445eb5bb3c0782e9e75077c"
"87f9f3a25a2d117793fc98441ce74255d7bd55bdb0f17710737ab4aaca99271600f03503"
"91ffbc9a5d5458414716e0c26b239096f6c6e4a680b0cccaebc4f200fa0500618d719493"
"becacf936525680233273679",
"e5e7d43632d844bd04fce45213257415a4c9c3f4bf9b6a1b74e8c31e3c66fbf3b42da531"
"aaa9cdaac160d565cd81430983c18120e98be41df6d178d0e974cc9ce6ced673423c7727"
"267ba1ba07b457a1557bffaf2c90957372c0f5f08c4940ccd858e0bc392e3050bb2adae8"
"0f509dc129a49279c01c55434b383d359b7b255f55c33be445a3dc05e0c1b3d7486a8142"
"675a3b6e7b3d3d27fbf54764d9f73ea98304612e5e1a4d566986efa53b62ad18f4ecad64"
"f197c7d48a2732745a1e5ec9",
"daa7795c70b8df8af978f9e66a19eed2a92b6f665aee3d58f3e450ac0f18772ed5cf8b2b"
"381eb55facd93b32106d0d703f2316b50069b6db38cd62b12a4b7fdd6f8f93c4f110091a"
"d972e5808afd6acf6bd6eaa0b846b50b7fe1786702a3382b8b637b8ea91ffe3225e9ad50"
"3f1f9593ea6f19d6dc2d556e5d6f3a26134df4a964e67d789e7849eaf698c976ef592052"
"6b023f2f96e96e2b89adf0ee4544e32029cfca972f824cb7af805c556a6143dcb93cb6b7"
"91ebb8dba30cbc94dff782f3",
"f48f534acee47a482ba43abc70aa8c7d4b6df27b957583fa2b23cbc1d34d9da7eb89fa3f"
"881b9db1dfa8925f38328574ca8ff7256ae0bf163ee61b471d29f5e72d98f92775693091"
"2bfbddb695a64137783232596d6c7892b89b4fb54abd5b077ccf532aaf5b9b29cf25b366"
"3845987a0a947b97000c05bfc7a239e1cb962cc43e1dceaf91935353d2d6dad7eda20798"
"9a2f0f8e367f3df5c1ee3b56209bd85832c35ff2cd7b9a67db801691c946b0a7a9a875e8"
"9e1f65198caf1ca6f3037ff9",
"ee5bc8c8d3ecd753b4c0e4e5934d8e44a9ab5d8dda127db28b32bfb357636d0c144dee78"
"8c2a901af3b02439a8a3d2125954feeac722a72272f5595a91cf4ee5ae8e69159986cc50"
"054c3a259c80ed84e7b793733eed05330b2a2ad11dee4140b5fe1f3706a0b1b28407e84c"
"27e19e3a3d9d640629c35deaa9061d33b5888a88e4220340f488f764219f9e8edb2b1d04"
"15253f5fd53835cdc6935898ecba173c5b2db3a6578fdc16e1221cac1e454864ada9f772"
"1ecd24bc77ed5cf353d5f909",
"f2f5ca816781cbae4fcea9587321497c252bfe84127f2d8ac7d6da7a34d1faa2f428911d"
"a876a42299d2cb4af35c944df51f1421b74fe11b047f871b37f1f37a0c6d0753c28a3e52"
"91a9cf54c5892408591bc932269626d1392f8c8c67d87300febbc63e4a779104ba6191f8"
"a5bbfbcf6c675a6ad8a853ac1e9a86dc16a95a9566b5287b7862f6a962bf79626a82961f"
"c378b4751da35e25d761469ad4e22072bd43951631a96026b37d7932ca8fabf22fb757b4"
"e903252c416f0f96ca0eb663",
"e01c620e4b80840816a99b5c1eed80c8bfdc040253889b2ce81e78de2f5511ea453d1492"
"56bb53b64f4f43441e464867cfd40571c2c5527f1c79eb4b8b1022018e362ae51f13b8b5"
"2426239c09369370575d873755e3bee630424e35a8024f76553f5635d26d791b5e4a8903"
"d09be560c322837c29283aee2feb6864b724007334f1af2008db7eaf773d9f4e1e8fc396"
"07969c43d7c1d106274fa24c3068d347244d5821e10153b5e1e84fef7c08c19e4f79b71e"
"ebd1205c057812a74f6e09ab",
// 2048-bit primes.
"ff9166fd6945a3f692e99001528d5f4db6a36990f755275c3b34bded64bdd9c8e0cd190b"
"3df421be41525d496478bb2c07400ea1abe2bda65aa95efaecfada8230df64405ace2594"
"3193755ecf24db8fe8cda7a399cebe66f6d760cd9815bdcc65a5ad53c5b97dad21deed9b"
"e24ba048f621a095b3ffc48d05de12e16fb53d1e81ba0ed20c601599ce3833c7f36bc481"
"ab84ba7f38e3baeb19ad27e45dfd74fd5d03073426200c4b5ebf3323b3e16a0534b8df9b"
"0359c8e56f2e8c3950803b28954f8b6f14cee76623481f3479638c4908ce88ee56a5940b"
"c9e79198fedf83e5f931740346916d745c6279f13f4ca59e1534dba4f3eaeee8d20ddf20"
"6459fac7",
"d17eaffaad2b87da90b280b3879908ef3ed395b0d7cf12daee62dd4a0bf73e536f912635"
"f109908c8ceb26f31950dbcce65e443e452ac0eddf35aef2ae03a15f57bbb5d7800c9d61"
"bae6d87f10927643bd5a2cd77bd5a70d84b0da28494e5cb7cd7ced9dd0a57177cade57d9"
"53c80efa99ff09588dc7f6cab76d18fc86ccfc74fe5acca9aba2b4c143977d7abdae2a67"
"7cb50810f6b60ccc0f77f75e9ea5733d8c7d6795f95350d91fafacd9d9ad00bafaadf558"
"d95237ff53f090c674c326f38f728dbc4a42f2978d91c19686f3793862375adb2bc8b241"
"ce9816e8e36ff105bb06e7a77ea0077371b28bbdf745dd0bf537e43a0bed8ddeff5eb29e"
"28931d17",
"df859ae517fac8682a715f666c70ad29421cb8a0186fe6016c5bd8a0fabf65ee2b018fcc"
"53c50a29daf82a2a9f7bceac45c13a2458af34998cf16eecec02fe3254758eff63b60e25"
"3e118fb1494d78de1d38b49ac0b528a04208d2b57d95a9edd7b7b02afeb2c47a628bef6b"
"4a6a0f7b91cb5b8d5900f8ad3f332360a07f3ac00907cadfe6cacc7e696e897ca541a2e7"
"12a5d419215712716b71e2a2a8b8c809bbf0cc3b24e55e7ec72cfdc5e8c9651f8a2f36a8"
"abd0ebd77ddf59b7f096b788f8081e22465e4a6082c3ad4bcdf27bf5f51f3326eb87ac9e"
"330fb6d68645299da63a1d977fb246e176afcfbc2474fca3ae40d75125f755f5a50c3080"
"e7816235",
"c6aea46d1fb7d2d1107e31399cc613a1db56174c96898e3e32688ce2a26c000486528f05"
"4cc0dc3e448016944528183a2a90ca54a1029aedc519fe6d7b599097b214aab0d16b35cb"
"b7948e2e301f4fe65fc35340a82eb25111150cd968e12ec063ac0901ec4bf5d490a39714"
"b128848ee3852dce7bfdd66a4751abe8f365d1e83fd7a86a192d02bc892c6cd9558bacdf"
"c55a61cb06be8d74c44c2d03245d9b5f003c7280e82f3f1204dc7abc3e5fa11f2168bc17"
"c73fb1dc8b84e632a26420b32118fc8aa6a98c037b662d676370d10bfb47955e9b4f4c64"
"062d32345677199b36abe1d6b1bb0badbb57ae4a65b643da7f122c1b38dad9df0318d3c9"
"d96a96bf",
"da64c031f133da1d014777b6f8c8d599f54b7e67dc3ac3883f0b78cfe27d1cb1849c72a3"
"37a6d6a0ee53633c8382a416e8851fe9c81141121d702fa8b12dc6ba62a3dbb87faec66c"
"6389e9e1df47015db6ff12ded83d2fc242e58e55cf7924b70e4cf463559705e382745006"
"1aa88b38d3795042ab0e8657ed1c77e91e39d5a29e86f9572a3ce91b8d0ca12ef6ee5f1f"
"f3930c5de357eaabe7497d7319461be00cbb1db36329baa6c298608aa7288a6926396abc"
"9a662dc2c413311ec821cb4564c247fcdd32d57cae8dd37882377f9139aea9a5a6ae1e01"
"1a356fc395682f64c08cb3130711bb759d16ed2eaf0da976876f156aa0965cb7292a5726"
"1ad31ab7",
"ce705e04e5abb0d0f3058bff82c457ef6308f2b4279026c906c0679f382d92c96ae0d11f"
"3004dfbdfd7950cc4f0aa1bcb7b06e4be6628b249e90339d8e1891e512c40f7b38ce9ad4"
"ad7c37791b833cf668b4807c2b4d4638cb10af745e349c70ae7bc8396611725c43899131"
"751729e98651b4250d680ddb1f208e971b8abaca2ba79a7665dd71fa532702f54930865c"
"52ca536f04218aeb626ff94bc4e0886ffbccba910f879e000f363b0864dfc883d2de2af5"
"70c2c4125c5b0e478f87f7b934b66af864fb63f4d13fa21db3e4cef03c395fe207764ae3"
"1b64bbc301cdeb795c580885605b11bcaa53d32a1fa72381e524ef269748ce77deb0cd37"
"ceb403ab",
"f4f7bb8ab2983afc83b6ac060dcc4d96331dbbf800b321bbde2d8f8a9fa750e7c2b42fc4"
"6baf9a167a7389812f65b52b283ad5dd95709e81f8f602031ee8a5f4929bee7b3da97b92"
"f53f61ff25de8170aeef9a6c464d4be77fa3e5aea041f51d49932d30480f33bb44fd3af5"
"e7bfad562acaaed5069b2dc003fdb207ee7db9061d02136cb4b59c2ba071ca6aa2747675"
"bf86d601a9197d92091b36299cad0d6adceca87b16ee54b48ee19a9e9df20955cdc1ca2c"
"fa07fd2b054377d6242fb1ae69209ac5ac2d98a2929dec9eb076e0c9d74083bab0797851"
"b6eca68e3de7440001706cebee6adc8b317b0ef8332863aad26ec18f8156998566f32207"
"3777e817",
"da20f268b7254f3ed0ad35372ad4c78c1fc89465fc1a256ee0064b3c11980917d4d0b6fe"
"c8546c5e4cea1e18ccd23f20dc096506062afeb57be9edd2443ec1cecd84108911c99ac0"
"2d388bc7c415aa41b7a4396c3ed823f3c0921163e85e2dec186862e945affa069dee3dea"
"3b382d7c5a9695aa76e2e25a516457d4eee12ef0c18bf09076c8f739189887492e4aecae"
"2999ec305c2e66d444d14251caa1b546deb3c07c6d9c0ed9d1a33f405e780661684be318"
"61db7030b2f0b5b6e6f1616ab017955a6025c89c6945329aa10567a5f26724dc074cae1a"
"623c64fcda5241674bb4c9954342b1bac8cb13a4b98e893ee42b4ccebf788c2267de2d70"
"8a5b93ed",
};
for (const char *str : kPrimesHex) {
SCOPED_TRACE(str);
EXPECT_NE(0, HexToBIGNUM(&p, str));
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_1, p.get(), BN_prime_checks_for_generation, ctx(),
false /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(1, is_probably_prime_1);
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_2, p.get(), BN_prime_checks_for_generation, ctx(),
true /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(1, is_probably_prime_2);
ASSERT_TRUE(BN_enhanced_miller_rabin_primality_test(
&result_3, p.get(), BN_prime_checks_for_generation, ctx(),
nullptr /* callback */));
EXPECT_EQ(bn_probably_prime, result_3);
}
// BN_primality_test works with null |BN_CTX|.
ASSERT_TRUE(BN_set_word(p.get(), 5));
ASSERT_TRUE(
BN_primality_test(&is_probably_prime_1, p.get(),
BN_prime_checks_for_generation, nullptr /* ctx */,
false /* do_trial_division */, nullptr /* callback */));
ASSERT_TRUE(BN_primality_test(
&is_probably_prime_1, p.get(), BN_prime_checks, nullptr /* ctx */,
false /* do_trial_division */, nullptr /* callback */));
EXPECT_EQ(1, is_probably_prime_1);
}
TEST_F(BNTest, MillerRabinIteration) {
FileTestGTest(
"crypto/fipsmodule/bn/miller_rabin_tests.txt", [&](FileTest *t) {
BIGNUMFileTest bn_test(t, /*large_mask=*/0);
bssl::UniquePtr<BIGNUM> w = bn_test.GetBIGNUM("W");
ASSERT_TRUE(w);
bssl::UniquePtr<BIGNUM> b = bn_test.GetBIGNUM("B");
ASSERT_TRUE(b);
bssl::UniquePtr<BN_MONT_CTX> mont(
BN_MONT_CTX_new_consttime(w.get(), ctx()));
ASSERT_TRUE(mont);
bssl::BN_CTXScope scope(ctx());
BN_MILLER_RABIN miller_rabin;
ASSERT_TRUE(bn_miller_rabin_init(&miller_rabin, mont.get(), ctx()));
int possibly_prime;
ASSERT_TRUE(bn_miller_rabin_iteration(&miller_rabin, &possibly_prime,
b.get(), mont.get(), ctx()));
std::string result;
ASSERT_TRUE(t->GetAttribute(&result, "Result"));
EXPECT_EQ(result, possibly_prime ? "PossiblyPrime" : "Composite");
});
}
// These tests are very slow, so we disable them by default to avoid timing out
// downstream consumers. They are enabled when running tests standalone via
// all_tests.go.
TEST_F(BNTest, DISABLED_WycheproofPrimality) {
FileTestGTest(
"third_party/wycheproof_testvectors/primality_test.txt",
[&](FileTest *t) {
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
bssl::UniquePtr<BIGNUM> value = GetWycheproofBIGNUM(t, "value", false);
ASSERT_TRUE(value);
for (int checks :
{BN_prime_checks_for_validation, BN_prime_checks_for_generation}) {
SCOPED_TRACE(checks);
if (checks == BN_prime_checks_for_generation &&
std::find(result.flags.begin(), result.flags.end(),
"WorstCaseMillerRabin") != result.flags.end()) {
// Skip the worst case Miller-Rabin cases.
// |BN_prime_checks_for_generation| relies on such values being rare
// when generating primes.
continue;
}
int is_probably_prime;
ASSERT_TRUE(BN_primality_test(&is_probably_prime, value.get(), checks,
ctx(),
/*do_trial_division=*/false, nullptr));
EXPECT_EQ(result.IsValid() ? 1 : 0, is_probably_prime);
ASSERT_TRUE(BN_primality_test(&is_probably_prime, value.get(), checks,
ctx(),
/*do_trial_division=*/true, nullptr));
EXPECT_EQ(result.IsValid() ? 1 : 0, is_probably_prime);
}
});
}
TEST_F(BNTest, NumBitsWord) {
constexpr BN_ULONG kOne = 1;

Some files were not shown because too many files have changed in this diff Show More