Compare commits
417 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cd846f24f | |||
| 74161f485b | |||
| 7d3a24d9db | |||
| 70fee17204 | |||
| 281a8f5ea3 | |||
| db129f3f3f | |||
| 8b601c88fb | |||
| cac93924ab | |||
| 54858b63c1 | |||
| d054e1bc61 | |||
| 1a63507c41 | |||
| f0558c359c | |||
| 8c0a6ebfc2 | |||
| 83b74c6a7a | |||
| 8f88b27d6a | |||
| de196121b0 | |||
| eda849d2e6 | |||
| 5d7c2f8b1d | |||
| d0637e901d | |||
| b9fbf4069e | |||
| fb0c05cac2 | |||
| c655065273 | |||
| 25638f06e3 | |||
| 939d426f6b | |||
| e2abade424 | |||
| 5d74463301 | |||
| 7361ee42cf | |||
| 5fa22ed85e | |||
| b3c5ac51d5 | |||
| 86f86cbdf7 | |||
| 430a742303 | |||
| d1d8eee76b | |||
| 33f8d33af0 | |||
| d206a11d48 | |||
| beaf594f8b | |||
| 991d31bbf1 | |||
| 9dd9d4fc24 | |||
| a3cc7780e7 | |||
| dd86e75b24 | |||
| fd86eaa868 | |||
| cbac9c3a2d | |||
| 5ddc5b14d9 | |||
| 1b8194715e | |||
| c179854243 | |||
| 8afdbf04bd | |||
| 884614c24f | |||
| cd8f3d36fe | |||
| 72b095d0d4 | |||
| 7f90eda55e | |||
| 9c256d1d7f | |||
| 0313b59d5f | |||
| fbaf1c0546 | |||
| 251b5169fd | |||
| 88024df121 | |||
| 53a17f5524 | |||
| 2309f645e5 | |||
| 8819e0be62 | |||
| 81a998a637 | |||
| 851943277f | |||
| 9701e84eff | |||
| 7b31d69f19 | |||
| 8f12996be3 | |||
| 78b3337a10 | |||
| 3e4dfbb2f8 | |||
| 9cf9d3eb06 | |||
| be28dd623f | |||
| b7acfff8e7 | |||
| 49e95dc0f3 | |||
| 1274d1d977 | |||
| d4d501c159 | |||
| a810d82575 | |||
| b55a8c1580 | |||
| 7c522995d1 | |||
| e32549edf9 | |||
| d4a97fa65f | |||
| 5f43b12d52 | |||
| ce1665b825 | |||
| 54a59c68b7 | |||
| 54304734eb | |||
| 802523aa5f | |||
| 73e0401e3d | |||
| cccfb9bcf2 | |||
| aa764c46eb | |||
| 69402f33f3 | |||
| 239634da1b | |||
| ad5582985c | |||
| 90bb72c6a6 | |||
| 090ee96bf6 | |||
| 17078f21a5 | |||
| dc06e320d8 | |||
| eeb5bb3561 | |||
| 6a7184066f | |||
| b36f52d187 | |||
| 21aede9179 | |||
| b1086cdb12 | |||
| 14d192e930 | |||
| 21f694210c | |||
| 47b1e39042 | |||
| 25ab623a86 | |||
| 8bbc5e9a61 | |||
| 1d8ef2c666 | |||
| 21712d52c4 | |||
| c878b651ce | |||
| e2af857ddc | |||
| cbe128b3e3 | |||
| 13d09f0527 | |||
| baca5b4fa0 | |||
| a27ed585fa | |||
| 188b65a791 | |||
| 78987bb7bb | |||
| 367d64f84c | |||
| 8f3019e849 | |||
| 7853619553 | |||
| 538a124d70 | |||
| f37eb8d6a8 | |||
| 9a798eb531 | |||
| 3c11bf53e9 | |||
| 9fc31378f0 | |||
| f883b98cfd | |||
| 3d22c8260a | |||
| 2a8e294b70 | |||
| 28987cf081 | |||
| f9e0cda2d8 | |||
| 5902657734 | |||
| d2c5b7da2f | |||
| 0f86c142a7 | |||
| f20772cc0a | |||
| a49c617197 | |||
| 4143943085 | |||
| 7a22a65098 | |||
| ea53011c6e | |||
| ad5e3e3597 | |||
| 58add794d9 | |||
| 1d43e57c30 | |||
| 47a6f5b4bf | |||
| e8434d304c | |||
| b65e630ec0 | |||
| bd1fa86feb | |||
| 243a29241c | |||
| 12840915a1 | |||
| 300ef4767d | |||
| af6bfbee47 | |||
| 72cff81939 | |||
| ee2660203b | |||
| 6bfd25c755 | |||
| d5aae81fb7 | |||
| 7c719d1246 | |||
| cdc5c184b3 | |||
| 0cf14d3ec8 | |||
| 732b70ee20 | |||
| 577eadc424 | |||
| 141062fe7f | |||
| ce9b8737cb | |||
| 8b4fa1b6b5 | |||
| 6c17797205 | |||
| 9ae40ce9ad | |||
| 5cd0724ecb | |||
| 0064c290d1 | |||
| dea1d44988 | |||
| 7fe639cc2d | |||
| 964256d066 | |||
| 5298ef99bf | |||
| 80ddfc7d1b | |||
| 959c76d928 | |||
| 0b710a305b | |||
| 1e859054c3 | |||
| bfe527fa35 | |||
| 2fb729d4f3 | |||
| 44099d5925 | |||
| 3280287c06 | |||
| b092192965 | |||
| 6432bb46ab | |||
| 472d91c39c | |||
| a12a2497ff | |||
| 7940ed1f30 | |||
| f1efbc8f8b | |||
| aadb46369a | |||
| 754d4c99c8 | |||
| 83ea777db5 | |||
| 0dc70e462c | |||
| 0c30649ba6 | |||
| f9cc26f9c1 | |||
| 21a879a78a | |||
| 82a4b2234e | |||
| f6cc8ddf52 | |||
| 8f299d5e03 | |||
| 4f3e8212ea | |||
| 7964a1d676 | |||
| 7e43e2e8ee | |||
| 1766935f76 | |||
| 6ab75bf21f | |||
| 2a4ce17243 | |||
| fbea9de163 | |||
| 921bb9e224 | |||
| bf17f4f6f1 | |||
| f0a815cce5 | |||
| ebad508ef1 | |||
| 10165d82c1 | |||
| 3d53d1ffe6 | |||
| 9e23361aa0 | |||
| 032fc660bc | |||
| 6192ccbbfd | |||
| f3c98ce9b7 | |||
| 093a823923 | |||
| bc7e2cb92d | |||
| 1cc95ac07c | |||
| a0cdbf989c | |||
| a965a25952 | |||
| 89730072b8 | |||
| f22e5fbaba | |||
| e1148bdf89 | |||
| f249840c94 | |||
| 986afedaa7 | |||
| 0416e8c305 | |||
| 31e64a295e | |||
| 98b4cdba1e | |||
| 0dcc6e231d | |||
| f06254c739 | |||
| 8e8759f0d3 | |||
| ff631133c4 | |||
| f50a8a77bd | |||
| 9351266ba5 | |||
| c556d87ddf | |||
| 3e96cd4b76 | |||
| b0d449aea2 | |||
| 0deb91ab3f | |||
| 604320f8a3 | |||
| 2feab0c085 | |||
| 63d06626d3 | |||
| 056035edcc | |||
| 2c58c2fda1 | |||
| aaa1a84d63 | |||
| 8959a49cc1 | |||
| 6c95434cc9 | |||
| b3ac6bb39a | |||
| cbae965ca0 | |||
| 6c5e4a4bc9 | |||
| 6887d5e81b | |||
| 522e2df089 | |||
| c58a85f8ca | |||
| cfd80a9b24 | |||
| cc0c28654a | |||
| be1d14b789 | |||
| 0df6edff4f | |||
| 9511ca4c03 | |||
| a165168277 | |||
| 355828a2f7 | |||
| e5905d01c3 | |||
| 305a03a8b0 | |||
| 55ed2a60d3 | |||
| 906bbef001 | |||
| 62f662dbeb | |||
| b19efcc1cf | |||
| 8e71fe9ca8 | |||
| 82dbb53f77 | |||
| 15cd8bf433 | |||
| b14530e636 | |||
| cb3f04f584 | |||
| b63123ca02 | |||
| 243b5cc9e3 | |||
| 134fb89c4f | |||
| 9ad9cda088 | |||
| 08e1fe05e6 | |||
| 31db68195b | |||
| c73375467c | |||
| b8b0e9f485 | |||
| 469446c736 | |||
| 5746add69c | |||
| 98ba3bd6e7 | |||
| f8fcab9d81 | |||
| e0d95adb24 | |||
| 35c1075e83 | |||
| ee0716f386 | |||
| fd32089f47 | |||
| 75148d7abf | |||
| 6ba98ff601 | |||
| af609d885b | |||
| 913a240c28 | |||
| 5d62952b2a | |||
| a2518dd077 | |||
| 9855c1c59a | |||
| 98f969491c | |||
| 43890dbd69 | |||
| 279740ed8d | |||
| d709b0d892 | |||
| 58d56f4c59 | |||
| 9294306578 | |||
| f0bdf5c9a1 | |||
| 6be491b7bb | |||
| bf7b331d1b | |||
| 2085c7c2c6 | |||
| 706da620b2 | |||
| b11902a385 | |||
| fe37af11a6 | |||
| 3ab3b1283f | |||
| de1d2881ae | |||
| 3ba9586bc0 | |||
| 31f94b0bf7 | |||
| c951e5560b | |||
| 7f02881e96 | |||
| 7de9498a88 | |||
| e481d94a6f | |||
| da8caf5b10 | |||
| 20ae5e6f6c | |||
| 3e502c84f0 | |||
| 76918d0164 | |||
| 9709ad52eb | |||
| eec840da62 | |||
| a93bebafb8 | |||
| 31302a473a | |||
| a7a75f208c | |||
| f3bd757ee5 | |||
| 642664838a | |||
| 841a40a276 | |||
| fba30c389c | |||
| 18d145e651 | |||
| 5cf3298140 | |||
| 2865bce1b2 | |||
| bc4c09df64 | |||
| 7458ded264 | |||
| 86ee70b6ff | |||
| c48c8b6f64 | |||
| 12049fd3ad | |||
| 4ca15d5dcb | |||
| 56b6c714c9 | |||
| 8fe1584023 | |||
| ff746c103f | |||
| 49de1fc291 | |||
| 9c49713ba8 | |||
| 6a2609dae2 | |||
| 0e7dbd579b | |||
| f10ea55e91 | |||
| 95017b9bf4 | |||
| 6e7255c17e | |||
| 9638f8fba9 | |||
| 1458b49a9e | |||
| 40633ac196 | |||
| 6f80629b6c | |||
| b9a8fd766e | |||
| 45610f9afb | |||
| 6784dc718c | |||
| e7e5a23b4e | |||
| 6dfb479755 | |||
| bd522862a0 | |||
| 0bb4345bfe | |||
| 0de64a749b | |||
| 63e96f2a29 | |||
| 3a3552247e | |||
| 622e46bf27 | |||
| 1f1af82f40 | |||
| 15b4fb2acf | |||
| 09a9ec0360 | |||
| 6e8d5f4a4f | |||
| 398ca1c3d6 | |||
| bb50783805 | |||
| 04a89c8435 | |||
| 98e848aa34 | |||
| 0c4d013916 | |||
| a7d9ac2af4 | |||
| 053880d3f7 | |||
| 0142c87a26 | |||
| 012a444265 | |||
| ec92ec471c | |||
| b82f945ebc | |||
| 68489e6da5 | |||
| f4d8b96920 | |||
| ccaee0a64c | |||
| 701d95a2a8 | |||
| 7d4b13b445 | |||
| 68fb238645 | |||
| 5588ec7a8b | |||
| 25e36da50f | |||
| e60b080dda | |||
| 5ce7022394 | |||
| f7b830d8df | |||
| 356a9a0895 | |||
| d041f11134 | |||
| 3b62960c5c | |||
| d0b979432e | |||
| d63435779f | |||
| 95dd54e57f | |||
| 1e547722d4 | |||
| fbebe833b1 | |||
| cf67ec09e4 | |||
| 05cd93068b | |||
| a8ffaf1bf2 | |||
| f350351a9a | |||
| e39d136568 | |||
| 9747a53284 | |||
| bd2a8d689b | |||
| f492830ed9 | |||
| e530ea387c | |||
| b244e3a5fc | |||
| 79b8b3a419 | |||
| 9806ae005b | |||
| 44544d9d2d | |||
| 8c98bac1ac | |||
| eca48e52ed | |||
| fd863b6a20 | |||
| bc2a2013e0 | |||
| ae223d6138 | |||
| f5270004a2 | |||
| ab26b556a4 | |||
| 67f3ada0c5 | |||
| 2c880a2047 | |||
| 81080a729a | |||
| 974f4dddfb | |||
| 303f1a86ac | |||
| 621c9d45e7 | |||
| 9f6acfc1f2 | |||
| 57de2c357b | |||
| ee4888c5ec | |||
| bc42402f31 | |||
| 94b2871bc5 | |||
| 2c65707928 | |||
| a866ba5d70 | |||
| ef0183c537 |
@@ -4,4 +4,8 @@ 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
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
build/
|
||||
build32/
|
||||
build64/
|
||||
ssl/test/runner/runner
|
||||
*.pyc
|
||||
*.swp
|
||||
|
||||
+54
-20
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
|
||||
# Defer enabling C and CXX languages.
|
||||
project(BoringSSL NONE)
|
||||
@@ -59,9 +59,15 @@ if(BORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
add_definitions(-DBORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
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")
|
||||
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()
|
||||
endif()
|
||||
|
||||
# Add a RelWithAsserts build configuration. It is the same as Release, except it
|
||||
@@ -104,10 +110,14 @@ 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")
|
||||
set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -Wvla")
|
||||
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.
|
||||
@@ -117,7 +127,14 @@ 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()
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -ggdb -fvisibility=hidden -fno-common")
|
||||
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")
|
||||
endif()
|
||||
|
||||
if(CLANG)
|
||||
@@ -231,11 +248,10 @@ 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. 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>)
|
||||
# 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")
|
||||
endif()
|
||||
|
||||
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.99") OR
|
||||
@@ -371,6 +387,14 @@ 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)
|
||||
@@ -434,6 +458,10 @@ 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")
|
||||
@@ -443,7 +471,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_CL_64)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(ARCH "x86_64")
|
||||
else()
|
||||
set(ARCH "x86")
|
||||
@@ -545,10 +573,21 @@ 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 ${CRYPTO_TEST_DATA} >
|
||||
${CMAKE_CURRENT_BINARY_DIR}/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"
|
||||
DEPENDS util/embed_test_data.go ${CRYPTO_TEST_DATA}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -574,11 +613,6 @@ 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()
|
||||
@@ -592,4 +626,4 @@ add_custom_target(
|
||||
${HANDSHAKER_ARGS} ${RUNNER_ARGS}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS all_tests bssl_shim handshaker
|
||||
${MAYBE_USES_TERMINAL})
|
||||
USES_TERMINAL)
|
||||
|
||||
@@ -26,6 +26,7 @@ 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 |
|
||||
|
||||
@@ -181,29 +181,6 @@ 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
|
||||
-------------------------
|
||||
|
||||
|
||||
@@ -21,6 +21,13 @@ 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.
|
||||
@@ -32,3 +39,4 @@ 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
@@ -0,0 +1,138 @@
|
||||
# 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.
|
||||
+41
-13
@@ -115,7 +115,14 @@ if(${ARCH} STREQUAL "aarch64")
|
||||
|
||||
chacha/chacha-armv8.${ASM_EXT}
|
||||
test/trampoline-armv8.${ASM_EXT}
|
||||
third_party/sike/asm/fp-armv8.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(${ARCH} STREQUAL "ppc64le")
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
|
||||
test/trampoline-ppc.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -137,7 +144,6 @@ 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()
|
||||
|
||||
@@ -147,10 +153,9 @@ 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)
|
||||
|
||||
@@ -179,6 +184,7 @@ 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
|
||||
@@ -257,6 +263,7 @@ add_library(
|
||||
cpu-intel.c
|
||||
cpu-ppc64le.c
|
||||
crypto.c
|
||||
curve25519/curve25519.c
|
||||
curve25519/spake25519.c
|
||||
dh/dh.c
|
||||
dh/params.c
|
||||
@@ -268,6 +275,8 @@ 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
|
||||
@@ -282,12 +291,15 @@ 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
|
||||
@@ -326,6 +338,8 @@ 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
|
||||
@@ -408,12 +422,6 @@ 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>
|
||||
|
||||
@@ -422,13 +430,17 @@ 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
|
||||
-o libcrypto.so -in-object libcrypto.so ${EXTRA_INJECT_HASH_ARGS}
|
||||
# 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.
|
||||
@@ -445,7 +457,7 @@ endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(crypto PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(NOT MSVC AND NOT ANDROID)
|
||||
if(NOT WIN32 AND NOT ANDROID)
|
||||
target_link_libraries(crypto pthread)
|
||||
endif()
|
||||
|
||||
@@ -455,6 +467,20 @@ 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
|
||||
|
||||
@@ -491,8 +517,10 @@ 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
|
||||
@@ -512,11 +540,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>
|
||||
|
||||
+286
-1
@@ -341,7 +341,6 @@ 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);
|
||||
@@ -521,3 +520,289 @@ 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
|
||||
|
||||
@@ -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(ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
int i2c_ASN1_BIT_STRING(const 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(ASN1_BIT_STRING *a, int n)
|
||||
int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w, v;
|
||||
|
||||
@@ -250,7 +250,7 @@ int ASN1_BIT_STRING_get_bit(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(ASN1_BIT_STRING *a,
|
||||
int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
|
||||
@@ -108,7 +108,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
@@ -147,7 +147,7 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len, j;
|
||||
@@ -183,7 +183,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
|
||||
+1
-1
@@ -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(ASN1_INTEGER *a, unsigned char **pp)
|
||||
int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
int pad = 0, ret, i, neg;
|
||||
unsigned char *p, *n, pb = 0;
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
|
||||
{
|
||||
unsigned char *p, *allocated = NULL;
|
||||
int objsize;
|
||||
@@ -98,12 +98,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
return objsize;
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
}
|
||||
|
||||
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
|
||||
int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -101,7 +100,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(ASN1_TIME *t)
|
||||
int ASN1_TIME_check(const ASN1_TIME *t)
|
||||
{
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_check(t);
|
||||
@@ -111,7 +110,7 @@ int ASN1_TIME_check(ASN1_TIME *t)
|
||||
}
|
||||
|
||||
/* Convert an ASN1_TIME structure to GeneralizedTime */
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME **out)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret = NULL;
|
||||
@@ -143,11 +142,11 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
|
||||
str = (char *)ret->data;
|
||||
/* Work out the century and prepend */
|
||||
if (t->data[0] >= '5')
|
||||
BUF_strlcpy(str, "19", newlen);
|
||||
OPENSSL_strlcpy(str, "19", newlen);
|
||||
else
|
||||
BUF_strlcpy(str, "20", newlen);
|
||||
OPENSSL_strlcpy(str, "20", newlen);
|
||||
|
||||
BUF_strlcat(str, (char *)t->data, newlen);
|
||||
OPENSSL_strlcat(str, (char *)t->data, newlen);
|
||||
|
||||
done:
|
||||
if (out != NULL && *out == NULL)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
|
||||
int ASN1_TYPE_get(ASN1_TYPE *a)
|
||||
int ASN1_TYPE_get(const ASN1_TYPE *a)
|
||||
{
|
||||
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
|
||||
return (a->type);
|
||||
|
||||
@@ -430,7 +430,7 @@ void ASN1_STRING_length_set(ASN1_STRING *x, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
int ASN1_STRING_type(ASN1_STRING *x)
|
||||
int ASN1_STRING_type(const ASN1_STRING *x)
|
||||
{
|
||||
return M_ASN1_STRING_type(x);
|
||||
}
|
||||
|
||||
@@ -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(const_cast<ASN1_OBJECT *>(obj), i2d_ASN1_OBJECT, kDER);
|
||||
TestSerialize(obj, i2d_ASN1_OBJECT, kDER);
|
||||
}
|
||||
|
||||
TEST(ASN1Test, SerializeBoolean) {
|
||||
|
||||
@@ -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(ASN1_STRING *oct, const ASN1_ITEM *it)
|
||||
void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
|
||||
{
|
||||
const unsigned char *p;
|
||||
void *ret;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/* Based on a_int.c: equivalent ENUMERATED functions */
|
||||
|
||||
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
|
||||
int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
|
||||
int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
|
||||
int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
@@ -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;
|
||||
/* fall through */
|
||||
OPENSSL_FALLTHROUGH;
|
||||
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
i = asn1_enc_restore(&seqcontlen, out, pval, it);
|
||||
|
||||
@@ -105,7 +105,7 @@ static const Base64TestVector kTestVectors[] = {
|
||||
|
||||
class Base64Test : public testing::TestWithParam<Base64TestVector> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(, Base64Test, testing::ValuesIn(kTestVectors));
|
||||
INSTANTIATE_TEST_SUITE_P(All, Base64Test, testing::ValuesIn(kTestVectors));
|
||||
|
||||
// RemoveNewlines returns a copy of |in| with all '\n' characters removed.
|
||||
static std::string RemoveNewlines(const char *in) {
|
||||
|
||||
@@ -220,7 +220,7 @@ TEST_P(BIOASN1Test, ReadASN1) {
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
|
||||
INSTANTIATE_TEST_SUITE_P(All, 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(, BIOPairTest, testing::Values(false, true));
|
||||
INSTANTIATE_TEST_SUITE_P(All, BIOPairTest, testing::Values(false, true));
|
||||
|
||||
@@ -74,7 +74,6 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
|
||||
OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
#endif
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -149,7 +148,7 @@ static int split_host_and_port(char **out_host, char **out_port, const char *nam
|
||||
}
|
||||
}
|
||||
|
||||
*out_host = BUF_strndup(host, host_len);
|
||||
*out_host = OPENSSL_strndup(host, host_len);
|
||||
if (*out_host == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -429,13 +428,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 = BUF_strdup(ptr);
|
||||
data->param_hostname = OPENSSL_strdup(ptr);
|
||||
if (data->param_hostname == NULL) {
|
||||
ret = 0;
|
||||
}
|
||||
} else if (num == 1) {
|
||||
OPENSSL_free(data->param_port);
|
||||
data->param_port = BUF_strdup(ptr);
|
||||
data->param_port = OPENSSL_strdup(ptr);
|
||||
if (data->param_port == NULL) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
|
||||
OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
#endif
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
+5
-6
@@ -79,7 +79,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -208,16 +207,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) {
|
||||
BUF_strlcpy(p, "a+", sizeof(p));
|
||||
OPENSSL_strlcpy(p, "a+", sizeof(p));
|
||||
} else {
|
||||
BUF_strlcpy(p, "a", sizeof(p));
|
||||
OPENSSL_strlcpy(p, "a", sizeof(p));
|
||||
}
|
||||
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) {
|
||||
BUF_strlcpy(p, "r+", sizeof(p));
|
||||
OPENSSL_strlcpy(p, "r+", sizeof(p));
|
||||
} else if (num & BIO_FP_WRITE) {
|
||||
BUF_strlcpy(p, "w", sizeof(p));
|
||||
OPENSSL_strlcpy(p, "w", sizeof(p));
|
||||
} else if (num & BIO_FP_READ) {
|
||||
BUF_strlcpy(p, "r", sizeof(p));
|
||||
OPENSSL_strlcpy(p, "r", sizeof(p));
|
||||
} else {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
|
||||
ret = 0;
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
+10
-69
@@ -132,6 +132,10 @@ 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);
|
||||
@@ -145,87 +149,24 @@ int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *BUF_strdup(const char *str) {
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BUF_strndup(str, strlen(str));
|
||||
}
|
||||
char *BUF_strdup(const char *str) { return OPENSSL_strdup(str); }
|
||||
|
||||
size_t BUF_strnlen(const char *str, size_t max_len) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < max_len; i++) {
|
||||
if (str[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
return OPENSSL_strnlen(str, max_len);
|
||||
}
|
||||
|
||||
char *BUF_strndup(const char *str, size_t 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;
|
||||
return OPENSSL_strndup(str, size);
|
||||
}
|
||||
|
||||
size_t BUF_strlcpy(char *dst, const char *src, size_t 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);
|
||||
return OPENSSL_strlcpy(dst, src, dst_size);
|
||||
}
|
||||
|
||||
size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) {
|
||||
size_t l = 0;
|
||||
for (; dst_size > 0 && *dst; dst_size--, dst++) {
|
||||
l++;
|
||||
}
|
||||
return l + BUF_strlcpy(dst, src, dst_size);
|
||||
return OPENSSL_strlcat(dst, src, dst_size);
|
||||
}
|
||||
|
||||
void *BUF_memdup(const void *data, size_t 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;
|
||||
return OPENSSL_memdup(data, size);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,14 @@ 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) {
|
||||
@@ -316,7 +324,9 @@ 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};
|
||||
0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 3, 2,
|
||||
10, 9, 8, 7, 0x12, 0x11, 0x10,
|
||||
0xf, 0xe, 0xd, 0xc, 0xb};
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
|
||||
@@ -331,6 +341,9 @@ 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);
|
||||
@@ -754,6 +767,79 @@ 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);
|
||||
|
||||
+41
-2
@@ -18,7 +18,6 @@
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
@@ -448,6 +447,10 @@ 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;
|
||||
@@ -464,6 +467,10 @@ 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;
|
||||
@@ -471,6 +478,10 @@ 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;
|
||||
@@ -517,6 +528,34 @@ 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) ||
|
||||
@@ -649,7 +688,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 = BUF_memdup(CBB_data(cbb), buf_len);
|
||||
uint8_t *buf = OPENSSL_memdup(CBB_data(cbb), buf_len);
|
||||
CBS *children = OPENSSL_malloc(num_children * sizeof(CBS));
|
||||
if (buf == NULL || children == NULL) {
|
||||
goto err;
|
||||
|
||||
+60
-3
@@ -12,7 +12,6 @@
|
||||
* 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>
|
||||
|
||||
@@ -61,7 +60,7 @@ int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
|
||||
if (cbs->len == 0) {
|
||||
return 1;
|
||||
}
|
||||
*out_ptr = BUF_memdup(cbs->data, cbs->len);
|
||||
*out_ptr = OPENSSL_memdup(cbs->data, cbs->len);
|
||||
if (*out_ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -73,7 +72,7 @@ int CBS_strdup(const CBS *cbs, char **out_ptr) {
|
||||
if (*out_ptr != NULL) {
|
||||
OPENSSL_free(*out_ptr);
|
||||
}
|
||||
*out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
|
||||
*out_ptr = OPENSSL_strndup((const char*)cbs->data, cbs->len);
|
||||
return (*out_ptr != NULL);
|
||||
}
|
||||
|
||||
@@ -121,6 +120,14 @@ 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)) {
|
||||
@@ -139,10 +146,26 @@ 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;
|
||||
@@ -438,6 +461,40 @@ 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) ||
|
||||
|
||||
@@ -44,9 +44,11 @@ if ($flavour && $flavour ne "void") {
|
||||
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
|
||||
die "can't locate arm-xlate.pl";
|
||||
|
||||
open STDOUT,"| \"$^X\" $xlate $flavour $output";
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
} else {
|
||||
open STDOUT,">$output";
|
||||
open OUT,">$output";
|
||||
*STDOUT=*OUT;
|
||||
}
|
||||
|
||||
sub AUTOLOAD() # thunk [simplified] x86-style perlasm
|
||||
|
||||
@@ -131,12 +131,6 @@ $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
|
||||
@@ -146,11 +140,14 @@ $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
|
||||
add @x[0],@x[0],:lo12:OPENSSL_armcap_P
|
||||
ldr w17,[@x[0]]
|
||||
ldr w17,[@x[0],:lo12:OPENSSL_armcap_P]
|
||||
tst w17,#ARMV7_NEON
|
||||
b.ne ChaCha20_neon
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#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"
|
||||
@@ -53,6 +54,8 @@ 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",
|
||||
@@ -101,7 +104,7 @@ class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
|
||||
const EVP_AEAD *aead() { return GetParam().func(); }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(, PerAEADTest, testing::ValuesIn(kAEADs),
|
||||
INSTANTIATE_TEST_SUITE_P(All, PerAEADTest, testing::ValuesIn(kAEADs),
|
||||
[](const testing::TestParamInfo<KnownAEAD> ¶ms)
|
||||
-> std::string { return params.param.name; });
|
||||
|
||||
@@ -540,10 +543,10 @@ TEST_P(PerAEADTest, AliasedBuffers) {
|
||||
}
|
||||
|
||||
TEST_P(PerAEADTest, UnalignedInput) {
|
||||
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];
|
||||
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];
|
||||
OPENSSL_memset(key, 'K', sizeof(key));
|
||||
OPENSSL_memset(nonce, 'N', sizeof(nonce));
|
||||
OPENSSL_memset(plaintext, 'P', sizeof(plaintext));
|
||||
@@ -561,7 +564,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(64) uint8_t ciphertext[sizeof(plaintext) + EVP_AEAD_MAX_OVERHEAD];
|
||||
alignas(16) 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,
|
||||
@@ -569,7 +572,7 @@ TEST_P(PerAEADTest, UnalignedInput) {
|
||||
ad_len));
|
||||
|
||||
// It must successfully decrypt.
|
||||
alignas(64) uint8_t out[sizeof(ciphertext)];
|
||||
alignas(16) 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,
|
||||
@@ -583,7 +586,7 @@ TEST_P(PerAEADTest, UnalignedInput) {
|
||||
}
|
||||
|
||||
TEST_P(PerAEADTest, Overflow) {
|
||||
alignas(64) uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
|
||||
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
|
||||
OPENSSL_memset(key, 'K', sizeof(key));
|
||||
|
||||
bssl::ScopedEVP_AEAD_CTX ctx;
|
||||
@@ -662,6 +665,91 @@ 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');
|
||||
@@ -726,8 +814,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 "acceptable" as "valid" here.
|
||||
if (result != WycheproofResult::kInvalid) {
|
||||
// supports those, so we treat SmallIv tests as valid.
|
||||
if (result.IsValid({"SmallIv"})) {
|
||||
// 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(),
|
||||
@@ -801,9 +889,8 @@ TEST(AEADTest, WycheproofAESGCM) {
|
||||
aead = EVP_aead_aes_128_gcm();
|
||||
break;
|
||||
case 192:
|
||||
// Skip AES-192-GCM tests.
|
||||
t->SkipCurrent();
|
||||
return;
|
||||
aead = EVP_aead_aes_192_gcm();
|
||||
break;
|
||||
case 256:
|
||||
aead = EVP_aead_aes_256_gcm();
|
||||
break;
|
||||
@@ -822,3 +909,12 @@ 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 * 6) + 288 + 32
|
||||
.cfi_adjust_cfa_offset (8 * 7) + 288 + 32
|
||||
################################################################################
|
||||
seal_sse_128:
|
||||
movdqu .chacha20_consts(%rip), $A0\nmovdqa $A0, $A1\nmovdqa $A0, $A2
|
||||
@@ -2478,6 +2478,7 @@ if (!$win64) {
|
||||
print $code;
|
||||
} else {
|
||||
print <<___;
|
||||
.text
|
||||
.globl dummy_chacha20_poly1305_asm
|
||||
.type dummy_chacha20_poly1305_asm,\@abi-omnipotent
|
||||
dummy_chacha20_poly1305_asm:
|
||||
|
||||
@@ -61,8 +61,10 @@
|
||||
|
||||
#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"
|
||||
@@ -118,7 +120,8 @@ 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) {
|
||||
bssl::Span<const uint8_t> in, size_t chunk,
|
||||
bool in_place) {
|
||||
size_t max_out = in.size();
|
||||
if ((EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_NO_PADDING) == 0 &&
|
||||
EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
@@ -126,6 +129,10 @@ 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;
|
||||
@@ -150,7 +157,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, size_t chunk_size,
|
||||
bool copy, bool in_place, size_t chunk_size,
|
||||
const std::vector<uint8_t> &key,
|
||||
const std::vector<uint8_t> &iv,
|
||||
const std::vector<uint8_t> &plaintext,
|
||||
@@ -207,7 +214,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));
|
||||
ASSERT_TRUE(DoCipher(ctx, &result, *in, chunk_size, in_place));
|
||||
EXPECT_EQ(Bytes(*out), Bytes(result));
|
||||
if (encrypt && is_aead) {
|
||||
uint8_t rtag[16];
|
||||
@@ -216,6 +223,91 @@ 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) {
|
||||
@@ -257,21 +349,24 @@ static void TestCipher(FileTest *t) {
|
||||
|
||||
for (size_t chunk_size : chunk_sizes) {
|
||||
SCOPED_TRACE(chunk_size);
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
if (operation != kEncrypt) {
|
||||
SCOPED_TRACE("decrypt");
|
||||
TestOperation(t, cipher, false /* decrypt */, copy, in_place,
|
||||
chunk_size, key, iv, plaintext, ciphertext, aad, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,59 +414,63 @@ 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);
|
||||
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));
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
});
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
if (addmd++) {
|
||||
if (!EVP_DigestUpdate(&c, md_buf, mds)) {
|
||||
|
||||
+254
-12
@@ -1,21 +1,56 @@
|
||||
/* Copyright (c) 2018, Google Inc.
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 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. */
|
||||
* 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.
|
||||
* ==================================================================== */
|
||||
|
||||
#include <openssl/aead.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -23,6 +58,213 @@
|
||||
#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 {
|
||||
@@ -30,7 +272,7 @@ struct aead_aes_ccm_ctx {
|
||||
double align;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
CCM128_CONTEXT ccm;
|
||||
struct ccm128_context ccm;
|
||||
};
|
||||
|
||||
OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
|
||||
|
||||
@@ -723,6 +723,14 @@ 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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# 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
|
||||
@@ -133,6 +133,7 @@ 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.
|
||||
|
||||
@@ -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_EQ(WycheproofResult::kInvalid, result);
|
||||
EXPECT_FALSE(result.IsValid());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ TEST(CMACTest, Wycheproof) {
|
||||
// Truncate the tag, if requested.
|
||||
out_len = std::min(out_len, tag_len);
|
||||
|
||||
if (result == WycheproofResult::kValid) {
|
||||
if (result.IsValid()) {
|
||||
EXPECT_EQ(Bytes(tag), Bytes(out, out_len));
|
||||
|
||||
// Test the streaming API as well.
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/arm_arch.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "cpu-arm-linux.h"
|
||||
@@ -147,11 +146,13 @@ extern uint32_t OPENSSL_armcap_P;
|
||||
static int g_has_broken_neon, g_needs_hwcap2_workaround;
|
||||
|
||||
void OPENSSL_cpuid_setup(void) {
|
||||
char *cpuinfo_data;
|
||||
size_t cpuinfo_len;
|
||||
if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) {
|
||||
return;
|
||||
}
|
||||
// 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");
|
||||
STRING_PIECE cpuinfo;
|
||||
cpuinfo.data = cpuinfo_data;
|
||||
cpuinfo.len = cpuinfo_len;
|
||||
|
||||
@@ -220,6 +220,13 @@ TEST(ARMLinuxTest, CPUInfo) {
|
||||
0,
|
||||
false,
|
||||
},
|
||||
// If opening /proc/cpuinfo fails, we process the empty string.
|
||||
{
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
},
|
||||
};
|
||||
|
||||
for (const auto &t : kTests) {
|
||||
|
||||
+29
-6
@@ -123,15 +123,28 @@ 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] == '~';
|
||||
uint64_t v;
|
||||
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';
|
||||
|
||||
if (!sscanf(in + invert, "%" PRIu64, &v)) {
|
||||
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) {
|
||||
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;
|
||||
@@ -164,17 +177,23 @@ 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) {
|
||||
if (family < 0x17 || (family == 0x17 && 0x70 <= model && model <= 0x7f)) {
|
||||
// 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 0x70–0x7f, due to possible RDRAND
|
||||
// failures there too.
|
||||
ecx &= ~(1u << 30);
|
||||
}
|
||||
}
|
||||
@@ -250,10 +269,14 @@ 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 '~' may be given.
|
||||
// indicate a hex value. Prior to the 64-bit value, a '~' or '|' may be given.
|
||||
//
|
||||
// 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.
|
||||
// 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
|
||||
//
|
||||
// The first value determines OPENSSL_ia32cap_P[0] and [1]. The second [2]
|
||||
// and [3].
|
||||
|
||||
+12
-1
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#include "fipsmodule/rand/fork_detect.h"
|
||||
#include "fipsmodule/rand/internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
@@ -60,7 +62,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(NDEBUG) && !defined(BORINGSSL_FIPS)
|
||||
#if defined(BORINGSSL_DISPATCH_TEST)
|
||||
// This value must be explicitly initialised to zero in order to work around a
|
||||
// bug in libtool or the linker on OS X.
|
||||
//
|
||||
@@ -174,6 +176,15 @@ 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) {
|
||||
|
||||
@@ -2130,3 +2130,7 @@ vpop {q4,q5,q6,q7}
|
||||
bx lr
|
||||
|
||||
#endif /* !OPENSSL_NO_ASM && __arm__ && !__APPLE__ */
|
||||
|
||||
#if defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
@@ -1,29 +1,21 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
|
||||
//
|
||||
// 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.
|
||||
/* 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. */
|
||||
|
||||
// Some of this code is taken from the ref10 version of Ed25519 in SUPERCOP
|
||||
// 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
|
||||
// public domain but parts have been replaced with code generated by Fiat
|
||||
// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed.
|
||||
// public domain. Other parts have been replaced to call into code generated by
|
||||
// Fiat (https://github.com/mit-plv/fiat-crypto) in //third_party/fiat.
|
||||
//
|
||||
// The field functions are shared by Ed25519 and X25519 where possible.
|
||||
|
||||
@@ -39,16 +31,16 @@
|
||||
#include <openssl/type_check.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../../crypto/internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
// Various pre-computed constants.
|
||||
#include "./curve25519_tables.h"
|
||||
|
||||
#if defined(BORINGSSL_CURVE25519_64BIT)
|
||||
#include "./curve25519_64.h"
|
||||
#include "../../third_party/fiat/curve25519_64.h"
|
||||
#else
|
||||
#include "./curve25519_32.h"
|
||||
#include "../../third_party/fiat/curve25519_32.h"
|
||||
#endif // BORINGSSL_CURVE25519_64BIT
|
||||
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
|
||||
//
|
||||
// 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.
|
||||
/* 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. */
|
||||
|
||||
// This file is generated from
|
||||
// ./make_curve25519_tables.py > curve25519_tables.h
|
||||
@@ -1,24 +1,16 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
|
||||
//
|
||||
// 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.
|
||||
/* 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_CURVE25519_INTERNAL_H
|
||||
#define OPENSSL_HEADER_CURVE25519_INTERNAL_H
|
||||
@@ -29,7 +21,7 @@ extern "C" {
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include "../../crypto/internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE)
|
||||
+24
-40
@@ -1,26 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
# The MIT License (MIT)
|
||||
# Copyright (c) 2020, Google Inc.
|
||||
#
|
||||
# Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
import StringIO
|
||||
import subprocess
|
||||
@@ -149,27 +141,19 @@ def main():
|
||||
|
||||
|
||||
buf = StringIO.StringIO()
|
||||
buf.write("""// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
|
||||
//
|
||||
// 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.
|
||||
buf.write("""/* 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. */
|
||||
|
||||
// This file is generated from
|
||||
// ./make_curve25519_tables.py > curve25519_tables.h
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../third_party/fiat/internal.h"
|
||||
#include "./internal.h"
|
||||
|
||||
|
||||
// The following precomputation tables are for the following
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../third_party/fiat/internal.h"
|
||||
#include "./internal.h"
|
||||
|
||||
|
||||
// TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../internal.h"
|
||||
#include "../test/file_test.h"
|
||||
#include "../test/test_util.h"
|
||||
#include "../test/wycheproof_util.h"
|
||||
|
||||
|
||||
TEST(X25519Test, TestVector) {
|
||||
@@ -132,11 +133,8 @@ TEST(X25519Test, Wycheproof) {
|
||||
t->IgnoreInstruction("curve");
|
||||
t->IgnoreAttribute("curve");
|
||||
|
||||
// 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");
|
||||
|
||||
WycheproofResult result;
|
||||
ASSERT_TRUE(GetWycheproofResult(t, &result));
|
||||
std::vector<uint8_t> priv, pub, shared;
|
||||
ASSERT_TRUE(t->GetBytes(&priv, "private"));
|
||||
ASSERT_TRUE(t->GetBytes(&pub, "public"));
|
||||
@@ -144,7 +142,8 @@ TEST(X25519Test, Wycheproof) {
|
||||
ASSERT_EQ(32u, priv.size());
|
||||
ASSERT_EQ(32u, pub.size());
|
||||
uint8_t secret[32];
|
||||
X25519(secret, priv.data(), pub.data());
|
||||
int ret = X25519(secret, priv.data(), pub.data());
|
||||
EXPECT_EQ(ret, result.IsValid({"NonCanonicalPublic", "Twist"}) ? 1 : 0);
|
||||
EXPECT_EQ(Bytes(secret), Bytes(shared));
|
||||
});
|
||||
}
|
||||
|
||||
+3
-3
@@ -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, ctx, NULL);
|
||||
r = BN_is_prime_ex(dh->q, BN_prime_checks_for_validation, 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, ctx, NULL);
|
||||
r = BN_is_prime_ex(dh->p, BN_prime_checks_for_validation, 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, ctx, NULL);
|
||||
r = BN_is_prime_ex(t1, BN_prime_checks_for_validation, ctx, NULL);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
+16
-2
@@ -59,7 +59,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ex_data.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -114,6 +113,16 @@ 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) {
|
||||
@@ -175,6 +184,11 @@ 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.
|
||||
@@ -476,7 +490,7 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942) {
|
||||
to->seedlen = 0;
|
||||
|
||||
if (from->seed) {
|
||||
to->seed = BUF_memdup(from->seed, from->seedlen);
|
||||
to->seed = OPENSSL_memdup(from->seed, from->seedlen);
|
||||
if (!to->seed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ 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 {
|
||||
@@ -69,94 +70,88 @@ 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" },
|
||||
{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"},
|
||||
|
||||
// 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) {
|
||||
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);
|
||||
EXPECT_EQ(test->expected_hex,
|
||||
EncodeHex(bssl::MakeConstSpan(digest, digest_len)));
|
||||
}
|
||||
|
||||
static void TestDigest(const DigestTestVector *test) {
|
||||
|
||||
+13
-3
@@ -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
|
||||
// Rabin-Miller
|
||||
// Miller-Rabin.
|
||||
#define DSS_prime_checks 50
|
||||
|
||||
static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
@@ -131,6 +131,16 @@ 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) {
|
||||
@@ -256,7 +266,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, 0, m++)) {
|
||||
if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, m++)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -319,7 +329,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, 0, counter)) {
|
||||
if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,8 @@ 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;
|
||||
CBS params, field_id, field_type, curve, base, cofactor;
|
||||
int has_cofactor;
|
||||
uint64_t version;
|
||||
if (!CBS_get_asn1(in, ¶ms, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1_uint64(¶ms, &version) ||
|
||||
@@ -272,7 +273,8 @@ static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
|
||||
!CBS_get_asn1(¶ms, &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 ||
|
||||
@@ -280,16 +282,26 @@ 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(¶ms, &base, CBS_ASN1_OCTETSTRING) ||
|
||||
!CBS_get_asn1(¶ms, out_order, CBS_ASN1_INTEGER) ||
|
||||
!is_unsigned_integer(out_order)) {
|
||||
!is_unsigned_integer(out_order) ||
|
||||
!CBS_get_optional_asn1(¶ms, &cofactor, &has_cofactor,
|
||||
CBS_ASN1_INTEGER) ||
|
||||
CBS_len(¶ms) != 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
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.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Require that the base point use uncompressed form.
|
||||
uint8_t form;
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* 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
|
||||
@@ -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_point_get_affine_coordinate_bytes(group, buf, NULL, &buf_len,
|
||||
sizeof(buf), &shared_point)) {
|
||||
!ec_get_x_coordinate_as_bytes(group, buf, &buf_len, sizeof(buf),
|
||||
&shared_point)) {
|
||||
OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -140,22 +140,16 @@ 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) {
|
||||
// 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);
|
||||
if (!peer_evp || CBS_len(&cbs) != 0) {
|
||||
EXPECT_FALSE(is_valid);
|
||||
return;
|
||||
}
|
||||
EC_KEY *peer_ec = EVP_PKEY_get0_EC_KEY(peer_evp.get());
|
||||
@@ -170,11 +164,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 (result == WycheproofResult::kInvalid) {
|
||||
EXPECT_EQ(-1, ret);
|
||||
} else {
|
||||
if (is_valid) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+39
-38
@@ -382,18 +382,16 @@ char *ERR_error_string(uint32_t packed_error, char *ret) {
|
||||
OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN);
|
||||
#endif
|
||||
|
||||
ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
|
||||
|
||||
return ret;
|
||||
return ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
|
||||
}
|
||||
|
||||
void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
|
||||
char *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;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lib = ERR_GET_LIB(packed_error);
|
||||
@@ -425,7 +423,7 @@ void 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;
|
||||
return buf;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_colons; i++) {
|
||||
@@ -444,6 +442,8 @@ void 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,38 +495,39 @@ 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
|
||||
"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
|
||||
"Trust Token functions", // ERR_LIB_TRUST_TOKEN
|
||||
"User defined functions", // ERR_LIB_USER
|
||||
};
|
||||
|
||||
const char *ERR_lib_error_string(uint32_t packed_error) {
|
||||
|
||||
@@ -63,6 +63,7 @@ var libraryNames = []string{
|
||||
"DIGEST",
|
||||
"CIPHER",
|
||||
"HKDF",
|
||||
"TRUST_TOKEN",
|
||||
"USER",
|
||||
}
|
||||
|
||||
|
||||
@@ -235,3 +235,51 @@ 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);
|
||||
}
|
||||
|
||||
@@ -15,12 +15,14 @@ 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
|
||||
|
||||
@@ -23,7 +23,6 @@ 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
|
||||
@@ -37,6 +36,7 @@ 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,6 +64,7 @@ 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
|
||||
@@ -72,6 +73,7 @@ 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
|
||||
@@ -84,6 +86,7 @@ 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
|
||||
@@ -131,6 +134,7 @@ 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
|
||||
@@ -171,6 +175,10 @@ 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
|
||||
@@ -178,18 +186,15 @@ 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
|
||||
@@ -199,6 +204,7 @@ 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
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
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
|
||||
@@ -6,13 +6,16 @@ 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
|
||||
|
||||
@@ -71,6 +71,11 @@
|
||||
#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;
|
||||
|
||||
@@ -200,6 +205,8 @@ 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;
|
||||
}
|
||||
@@ -427,3 +434,10 @@ 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);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../bytestring/internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
@@ -73,6 +74,7 @@ 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) {
|
||||
@@ -385,3 +387,145 @@ 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;
|
||||
}
|
||||
|
||||
@@ -67,15 +67,14 @@
|
||||
|
||||
|
||||
static const EVP_PKEY_METHOD *const evp_methods[] = {
|
||||
&rsa_pkey_meth,
|
||||
&ec_pkey_meth,
|
||||
&ed25519_pkey_meth,
|
||||
&rsa_pkey_meth,
|
||||
&ec_pkey_meth,
|
||||
&ed25519_pkey_meth,
|
||||
&x25519_pkey_meth,
|
||||
};
|
||||
|
||||
static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) {
|
||||
for (size_t i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) {
|
||||
if (evp_methods[i]->pkey_id == type) {
|
||||
return evp_methods[i];
|
||||
}
|
||||
|
||||
+317
-81
@@ -70,7 +70,6 @@ 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>
|
||||
@@ -119,6 +118,9 @@ 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;
|
||||
}
|
||||
@@ -245,7 +247,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, EVP_PKEY_CTX *ctx) {
|
||||
static bool SetupContext(FileTest *t, KeyMap *key_map, EVP_PKEY_CTX *ctx) {
|
||||
if (t->HasAttribute("RSAPadding")) {
|
||||
int padding;
|
||||
if (!GetRSAPadding(t, &padding, t->GetAttributeOrDie("RSAPadding")) ||
|
||||
@@ -277,14 +279,82 @@ static bool SetupContext(FileTest *t, 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 *>(BUF_memdup(label.data(), label.size())));
|
||||
bssl::UniquePtr<uint8_t> buf(reinterpret_cast<uint8_t *>(
|
||||
OPENSSL_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;
|
||||
}
|
||||
|
||||
@@ -298,6 +368,14 @@ 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;
|
||||
@@ -321,19 +399,13 @@ 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"));
|
||||
@@ -355,7 +427,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, pctx) ||
|
||||
!SetupContext(t, key_map, pctx) ||
|
||||
!EVP_MD_CTX_copy_ex(copy.get(), ctx.get())) {
|
||||
return false;
|
||||
}
|
||||
@@ -402,7 +474,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, ctx.get())) {
|
||||
!SetupContext(t, key_map, ctx.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -436,7 +508,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, decrypt_ctx.get()) ||
|
||||
!SetupContext(t, key_map, decrypt_ctx.get()) ||
|
||||
!EVP_PKEY_decrypt(decrypt_ctx.get(), nullptr, &plaintext_len,
|
||||
actual.data(), actual.size())) {
|
||||
return false;
|
||||
@@ -456,7 +528,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, verify_ctx.get())) {
|
||||
!SetupContext(t, key_map, verify_ctx.get())) {
|
||||
return false;
|
||||
}
|
||||
if (t->HasAttribute("VerifyPSSSaltLength")) {
|
||||
@@ -495,40 +567,10 @@ TEST(EVPTest, TestVectors) {
|
||||
});
|
||||
}
|
||||
|
||||
static void RunWycheproofTest(const char *path) {
|
||||
static void RunWycheproofVerifyTest(const char *path) {
|
||||
SCOPED_TRACE(path);
|
||||
FileTestGTest(path, [](FileTest *t) {
|
||||
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");
|
||||
t->IgnoreAllUnusedInstructions();
|
||||
|
||||
std::vector<uint8_t> der;
|
||||
ASSERT_TRUE(t->GetInstructionBytes(&der, "keyDer"));
|
||||
@@ -573,13 +615,7 @@ static void RunWycheproofTest(const char *path) {
|
||||
bool sig_ok = DSA_check_signature(&valid, digest, digest_len, sig.data(),
|
||||
sig.size(), dsa) &&
|
||||
valid;
|
||||
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.
|
||||
}
|
||||
EXPECT_EQ(sig_ok, result.IsValid());
|
||||
} else {
|
||||
bssl::ScopedEVP_MD_CTX ctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
@@ -592,75 +628,275 @@ static void RunWycheproofTest(const char *path) {
|
||||
}
|
||||
int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
|
||||
msg.size());
|
||||
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);
|
||||
}
|
||||
// BoringSSL does not enforce policies on weak keys and leaves it to the
|
||||
// caller.
|
||||
EXPECT_EQ(ret,
|
||||
result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"})
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofDSA) {
|
||||
RunWycheproofTest("third_party/wycheproof_testvectors/dsa_test.txt");
|
||||
RunWycheproofVerifyTest("third_party/wycheproof_testvectors/dsa_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofECDSAP224) {
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofECDSAP256) {
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofECDSAP384) {
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofECDSAP521) {
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofEdDSA) {
|
||||
RunWycheproofTest("third_party/wycheproof_testvectors/eddsa_test.txt");
|
||||
RunWycheproofVerifyTest("third_party/wycheproof_testvectors/eddsa_test.txt");
|
||||
}
|
||||
|
||||
TEST(EVPTest, WycheproofRSAPKCS1) {
|
||||
RunWycheproofTest(
|
||||
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(
|
||||
"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) {
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/"
|
||||
"rsa_pss_2048_sha256_mgf1_32_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/"
|
||||
"rsa_pss_3072_sha256_mgf1_32_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/"
|
||||
"rsa_pss_4096_sha256_mgf1_32_test.txt");
|
||||
RunWycheproofTest(
|
||||
RunWycheproofVerifyTest(
|
||||
"third_party/wycheproof_testvectors/"
|
||||
"rsa_pss_4096_sha512_mgf1_32_test.txt");
|
||||
RunWycheproofTest("third_party/wycheproof_testvectors/rsa_pss_misc_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");
|
||||
}
|
||||
|
||||
@@ -73,6 +73,32 @@ 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
|
||||
@@ -1607,3 +1633,42 @@ 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
|
||||
|
||||
@@ -244,14 +244,22 @@ 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)
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ec_key.h>
|
||||
|
||||
@@ -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 256; }
|
||||
static int ed25519_bits(const EVP_PKEY *pkey) { return 253; }
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
EVP_PKEY_ED25519,
|
||||
|
||||
+14
-2
@@ -59,7 +59,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -135,7 +134,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 = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
|
||||
dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
|
||||
if (!dctx->oaep_label) {
|
||||
return 0;
|
||||
}
|
||||
@@ -569,6 +568,19 @@ 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),
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* 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,
|
||||
};
|
||||
@@ -0,0 +1,248 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -6,7 +6,6 @@ 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}
|
||||
@@ -27,7 +26,6 @@ if(${ARCH} STREQUAL "x86")
|
||||
set(
|
||||
BCM_ASM_SOURCES
|
||||
|
||||
aes-586.${ASM_EXT}
|
||||
aesni-x86.${ASM_EXT}
|
||||
bn-586.${ASM_EXT}
|
||||
co-586.${ASM_EXT}
|
||||
@@ -46,7 +44,6 @@ if(${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
BCM_ASM_SOURCES
|
||||
|
||||
aes-armv4.${ASM_EXT}
|
||||
aesv8-armx.${ASM_EXT}
|
||||
armv4-mont.${ASM_EXT}
|
||||
bsaes-armv7.${ASM_EXT}
|
||||
@@ -55,6 +52,7 @@ if(${ARCH} STREQUAL "arm")
|
||||
sha1-armv4-large.${ASM_EXT}
|
||||
sha256-armv4.${ASM_EXT}
|
||||
sha512-armv4.${ASM_EXT}
|
||||
vpaes-armv7.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -82,14 +80,11 @@ 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)
|
||||
@@ -121,6 +116,7 @@ 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)
|
||||
@@ -230,7 +226,7 @@ elseif(FIPS_SHARED)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT bcm.o
|
||||
COMMAND ld -r -T ${CMAKE_CURRENT_SOURCE_DIR}/fips_shared.lds -o bcm.o --whole-archive $<TARGET_FILE:bcm_library>
|
||||
COMMAND ${CMAKE_LINKER} -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}
|
||||
)
|
||||
|
||||
@@ -10,6 +10,7 @@ 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
|
||||
|
||||
@@ -46,6 +47,10 @@ 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.
|
||||
@@ -54,6 +59,12 @@ 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.
|
||||
|
||||
@@ -56,758 +56,6 @@
|
||||
#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
@@ -16,12 +16,14 @@
|
||||
#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"
|
||||
@@ -175,7 +177,7 @@ TEST(AESTest, WycheproofKeyWrap) {
|
||||
WycheproofResult result;
|
||||
ASSERT_TRUE(GetWycheproofResult(t, &result));
|
||||
|
||||
if (result != WycheproofResult::kInvalid) {
|
||||
if (result.IsValid()) {
|
||||
ASSERT_GE(ct.size(), 8u);
|
||||
|
||||
AES_KEY aes;
|
||||
@@ -217,7 +219,10 @@ 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.
|
||||
if (result != WycheproofResult::kInvalid && !msg.empty()) {
|
||||
//
|
||||
// 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()) {
|
||||
AES_KEY aes;
|
||||
ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
|
||||
std::vector<uint8_t> out(ct.size() - 8);
|
||||
@@ -283,28 +288,9 @@ 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()) {
|
||||
aes_nohw_set_encrypt_key(kKey, bits, &key);
|
||||
vpaes_set_encrypt_key(kKey, bits, &key);
|
||||
CHECK_ABI(vpaes_encrypt_key_to_bsaes, &key, &key);
|
||||
for (size_t blocks : block_counts) {
|
||||
SCOPED_TRACE(blocks);
|
||||
if (blocks != 0) {
|
||||
@@ -312,7 +298,8 @@ TEST(AESTest, ABI) {
|
||||
}
|
||||
}
|
||||
|
||||
aes_nohw_set_decrypt_key(kKey, bits, &key);
|
||||
vpaes_set_decrypt_key(kKey, bits, &key);
|
||||
CHECK_ABI(vpaes_decrypt_key_to_bsaes, &key, &key);
|
||||
for (size_t blocks : block_counts) {
|
||||
SCOPED_TRACE(blocks);
|
||||
CHECK_ABI(bsaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
|
||||
@@ -325,8 +312,10 @@ 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
|
||||
@@ -334,11 +323,13 @@ 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()) {
|
||||
@@ -370,3 +361,247 @@ 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
|
||||
|
||||
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
@@ -84,7 +84,7 @@ open OUT,">$output";
|
||||
&asm_init($ARGV[0]);
|
||||
|
||||
&external_label("OPENSSL_ia32cap_P");
|
||||
&preprocessor_ifndef("NDEBUG")
|
||||
&preprocessor_ifdef("BORINGSSL_DISPATCH_TEST")
|
||||
&external_label("BORINGSSL_function_hit");
|
||||
&preprocessor_endif();
|
||||
&static_label("key_const");
|
||||
|
||||
@@ -275,11 +275,9 @@ $code.=<<___;
|
||||
.align 16
|
||||
${PREFIX}_encrypt:
|
||||
.cfi_startproc
|
||||
#ifndef NDEBUG
|
||||
#ifndef BORINGSSL_FIPS
|
||||
#ifdef BORINGSSL_DISPATCH_TEST
|
||||
.extern BORINGSSL_function_hit
|
||||
movb \$1,BORINGSSL_function_hit+1(%rip)
|
||||
#endif
|
||||
#endif
|
||||
movups ($inp),$inout0 # load input
|
||||
mov 240($key),$rounds # key->rounds
|
||||
@@ -1205,10 +1203,8 @@ $code.=<<___;
|
||||
.align 16
|
||||
${PREFIX}_ctr32_encrypt_blocks:
|
||||
.cfi_startproc
|
||||
#ifndef NDEBUG
|
||||
#ifndef BORINGSSL_FIPS
|
||||
#ifdef BORINGSSL_DISPATCH_TEST
|
||||
movb \$1,BORINGSSL_function_hit(%rip)
|
||||
#endif
|
||||
#endif
|
||||
cmp \$1,$len
|
||||
jne .Lctr32_bulk
|
||||
@@ -4354,10 +4350,8 @@ $code.=<<___;
|
||||
${PREFIX}_set_encrypt_key:
|
||||
__aesni_set_encrypt_key:
|
||||
.cfi_startproc
|
||||
#ifndef NDEBUG
|
||||
#ifndef BORINGSSL_FIPS
|
||||
#ifdef BORINGSSL_DISPATCH_TEST
|
||||
movb \$1,BORINGSSL_function_hit+3(%rip)
|
||||
#endif
|
||||
#endif
|
||||
.byte 0x48,0x83,0xEC,0x08 # sub rsp,8
|
||||
.cfi_adjust_cfa_offset 8
|
||||
|
||||
@@ -60,9 +60,11 @@ if ($flavour && $flavour ne "void") {
|
||||
( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or
|
||||
die "can't locate arm-xlate.pl";
|
||||
|
||||
open STDOUT,"| \"$^X\" $xlate $flavour $output";
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
} else {
|
||||
open STDOUT,">$output";
|
||||
open OUT,">$output";
|
||||
*STDOUT=*OUT;
|
||||
}
|
||||
|
||||
my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,7 @@ $PREFIX="vpaes";
|
||||
my ($round, $base, $magic, $key, $const, $inp, $out)=
|
||||
("eax", "ebx", "ecx", "edx","ebp", "esi","edi");
|
||||
|
||||
&preprocessor_ifndef("NDEBUG")
|
||||
&preprocessor_ifdef("BORINGSSL_DISPATCH_TEST")
|
||||
&external_label("BORINGSSL_function_hit");
|
||||
&preprocessor_endif();
|
||||
&static_label("_vpaes_consts");
|
||||
|
||||
@@ -182,11 +182,11 @@ _vpaes_encrypt_core:
|
||||
##
|
||||
## Inputs:
|
||||
## %xmm0 and %xmm6 = input
|
||||
## %xmm12-%xmm15 as in _vpaes_preheat
|
||||
## %xmm9 and %xmm10 as in _vpaes_preheat
|
||||
## (%rdx) = scheduled keys
|
||||
##
|
||||
## Output in %xmm0 and %xmm6
|
||||
## Clobbers %xmm1-%xmm5, %xmm7-%xmm11, %r9, %r10, %r11, %rax
|
||||
## Clobbers %xmm1-%xmm5, %xmm7, %xmm8, %xmm11-%xmm13, %r9, %r10, %r11, %rax
|
||||
## Preserves %xmm14 and %xmm15
|
||||
##
|
||||
## This function stitches two parallel instances of _vpaes_encrypt_core. x86_64
|
||||
@@ -871,12 +871,10 @@ _vpaes_schedule_mangle:
|
||||
.align 16
|
||||
${PREFIX}_set_encrypt_key:
|
||||
.cfi_startproc
|
||||
#ifndef NDEBUG
|
||||
#ifndef BORINGSSL_FIPS
|
||||
#ifdef BORINGSSL_DISPATCH_TEST
|
||||
.extern BORINGSSL_function_hit
|
||||
movb \$1, BORINGSSL_function_hit+5(%rip)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
@@ -983,12 +981,10 @@ $code.=<<___;
|
||||
.align 16
|
||||
${PREFIX}_encrypt:
|
||||
.cfi_startproc
|
||||
#ifndef NDEBUG
|
||||
#ifndef BORINGSSL_FIPS
|
||||
#ifdef BORINGSSL_DISPATCH_TEST
|
||||
.extern BORINGSSL_function_hit
|
||||
movb \$1, BORINGSSL_function_hit+4(%rip)
|
||||
#endif
|
||||
#endif
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0xb8(%rsp),%rsp
|
||||
|
||||
@@ -38,6 +38,7 @@ 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;
|
||||
}
|
||||
@@ -49,11 +50,15 @@ 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
|
||||
@@ -130,12 +135,14 @@ void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
|
||||
|
||||
#if defined(BSAES)
|
||||
// On platforms where BSAES gets defined (just above), then these functions are
|
||||
// provided by asm. Note |bsaes_cbc_encrypt| requires |enc| to be zero.
|
||||
// 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; }
|
||||
|
||||
@@ -152,6 +159,16 @@ 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
|
||||
|
||||
|
||||
@@ -164,8 +181,10 @@ 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]);
|
||||
@@ -199,19 +218,17 @@ 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);
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
#define AES_NOHW_CBC
|
||||
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]);
|
||||
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)
|
||||
|
||||
@@ -57,7 +57,23 @@
|
||||
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) {
|
||||
CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num, AES_encrypt);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key,
|
||||
@@ -79,12 +95,10 @@ 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 {
|
||||
|
||||
+88
-7
@@ -19,6 +19,10 @@
|
||||
#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>
|
||||
@@ -27,6 +31,7 @@
|
||||
#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"
|
||||
@@ -65,7 +70,7 @@
|
||||
#include "ec/felem.c"
|
||||
#include "ec/oct.c"
|
||||
#include "ec/p224-64.c"
|
||||
#include "../../third_party/fiat/p256.c"
|
||||
#include "ec/p256.c"
|
||||
#include "ec/p256-x86_64.c"
|
||||
#include "ec/scalar.c"
|
||||
#include "ec/simple.c"
|
||||
@@ -76,13 +81,14 @@
|
||||
#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"
|
||||
@@ -100,6 +106,7 @@
|
||||
#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.
|
||||
@@ -110,7 +117,49 @@ 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
|
||||
#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
|
||||
|
||||
static void __attribute__((constructor))
|
||||
BORINGSSL_bcm_power_on_self_test(void) {
|
||||
@@ -121,22 +170,48 @@ 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), EVP_sha512(),
|
||||
if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), kHashFunction,
|
||||
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));
|
||||
@@ -148,6 +223,8 @@ 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");
|
||||
@@ -160,11 +237,15 @@ 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;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user