Compare commits
477 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f7bd6b559 | |||
| 8df8e64205 | |||
| 8d4f7e5421 | |||
| 4702db6306 | |||
| 8041d8c40e | |||
| c01786403f | |||
| e745b25dcb | |||
| 672f6fc248 | |||
| 36714fc8ee | |||
| 02d696f2a1 | |||
| ed626ec99b | |||
| 085955c567 | |||
| f16cd4278f | |||
| 78a832d793 | |||
| c03ecb93a2 | |||
| 1bf2337fe1 | |||
| 67968895b3 | |||
| 02cca1987b | |||
| 10443f5a6e | |||
| 862e0d2e1b | |||
| 638a408cd2 | |||
| 6e4ff114fc | |||
| f6cf8bbc84 | |||
| 6dc994265e | |||
| 0f4f6c2e02 | |||
| 02808ddcaa | |||
| 05640fd373 | |||
| 8ae929f1e9 | |||
| d25e62e772 | |||
| 38c20fe8d5 | |||
| 61dedd6815 | |||
| 376f3f1727 | |||
| d24cb22c55 | |||
| ac383701b7 | |||
| 6488f4e2ba | |||
| 2bf82975ad | |||
| 6541308ff3 | |||
| 34a2c5e476 | |||
| b01dd1c622 | |||
| 3b3e12d81e | |||
| be837402a9 | |||
| 150ad30d28 | |||
| 5b10def1cf | |||
| 6f564afbdd | |||
| eaa80b7069 | |||
| 08805fe279 | |||
| c7b6e0a664 | |||
| 08d774a45f | |||
| 09633cc34e | |||
| 23223ebbc1 | |||
| cb4e300f17 | |||
| 226b4b51b5 | |||
| 45210dd4e2 | |||
| 2044181e01 | |||
| a312391050 | |||
| 091b455f09 | |||
| 472ba2c2dd | |||
| f4b708cc1e | |||
| feffb87168 | |||
| 385e4e9d98 | |||
| 6c41465548 | |||
| 7979dbede2 | |||
| 76ce04bec8 | |||
| 0758b6837e | |||
| 9a5bfc0350 | |||
| 2ccdf584aa | |||
| dc8b1abb75 | |||
| 43cf27e7d7 | |||
| ad5cfdf541 | |||
| 884086e0e2 | |||
| fa65113400 | |||
| 48669209b7 | |||
| ddb57cfb51 | |||
| 3fe8fa74ac | |||
| 7e5dd25d47 | |||
| 3c034b2cf3 | |||
| a62dbf88d8 | |||
| 5301c10c53 | |||
| e8d2439cd3 | |||
| 0ab3f0ca25 | |||
| 0ab86cf6f9 | |||
| 449a9e6a9e | |||
| ab5a947d8e | |||
| c61b577197 | |||
| 5a869aa3e8 | |||
| 610cdbb102 | |||
| 32b5940267 | |||
| cb1ad205d0 | |||
| a1bc1ba47c | |||
| 8017cdde38 | |||
| b9f30bb6fe | |||
| d86c0d2889 | |||
| 6ca09409cc | |||
| a42d7bee85 | |||
| 0c1eafc6fe | |||
| 522ad7e8fc | |||
| 338eeb0c4f | |||
| 2d77d4084a | |||
| 042b49cf3c | |||
| 5d9408714c | |||
| 4111dd2fc2 | |||
| 186df3a655 | |||
| a7bc94489f | |||
| 44fd6eeef5 | |||
| 98e24197ee | |||
| a4f78775b9 | |||
| cb15cfda29 | |||
| f2e7b220c0 | |||
| 36fcc4ca5d | |||
| 8d67f6f0cf | |||
| 017fbf0940 | |||
| 05a8434484 | |||
| bb1e5cbbe3 | |||
| 5ab5484044 | |||
| c7ef069ac9 | |||
| 37c6eb4284 | |||
| e80c7c065c | |||
| 92b8ecdd0d | |||
| afd1cd959e | |||
| 7c5e1400dd | |||
| 94cd196a80 | |||
| b6317b98ee | |||
| 11a5726ee3 | |||
| 512a289a8a | |||
| 3c92e80d7a | |||
| 9d1f96606c | |||
| 53ff70f68c | |||
| e2b8466fa7 | |||
| 74666da5b3 | |||
| 0c9b7b5de2 | |||
| 9112631c1f | |||
| 3ab6ad6abd | |||
| 99084cdd76 | |||
| 1eddb4be29 | |||
| 9770532afa | |||
| 92e332501a | |||
| 00208b443c | |||
| 2f9b47fb19 | |||
| 11850d5f61 | |||
| 915c121bb5 | |||
| 3144d92ab8 | |||
| d9f49974e3 | |||
| 5bcaa113e2 | |||
| e15019572b | |||
| ef16f19ef2 | |||
| 380bc30f0c | |||
| f8d05579b4 | |||
| 0a54e99848 | |||
| 80ede1df8e | |||
| 36fce983b6 | |||
| 6df6540766 | |||
| 02e6256b16 | |||
| a0c87adbf0 | |||
| 0551feb3a1 | |||
| d90b8033d7 | |||
| 287ac180ee | |||
| 64cc121f41 | |||
| ea52ec98a5 | |||
| f88242d1c1 | |||
| ebd87230ac | |||
| 875095aa7c | |||
| 9894ee9de2 | |||
| 528877962b | |||
| 4358f104cf | |||
| a9c5b7b3fb | |||
| d870cbdd97 | |||
| 0c9c1aad35 | |||
| f98b582ded | |||
| 6fe960d174 | |||
| 650d8c393e | |||
| 8f53fc0a94 | |||
| 46304abf7d | |||
| 21baf6421a | |||
| eb9232f06f | |||
| 2b63addf6a | |||
| 296a61d600 | |||
| 2bc937068d | |||
| d8dbde79f9 | |||
| 6979c7e8eb | |||
| 56d5d7085d | |||
| 494e4d0e89 | |||
| a5462d3050 | |||
| d3ec6f1adb | |||
| bc37ad91fe | |||
| 9986f6b045 | |||
| 48eaa28a12 | |||
| 2fc4f362cd | |||
| 095b6c9baa | |||
| 1530ef3ec5 | |||
| fb535892e5 | |||
| c5c31abe2b | |||
| e6cefe41bb | |||
| fc9c67599d | |||
| a7673facf8 | |||
| 28b267b357 | |||
| bd911af514 | |||
| 7ce2378750 | |||
| 47b8f00fdc | |||
| be8c8b4b1d | |||
| 8c9ceadc58 | |||
| 56aaf164ac | |||
| 27bc0f26c8 | |||
| 2fce1beda0 | |||
| e3b2a5d30d | |||
| 61e9245543 | |||
| 86c2b854b0 | |||
| a838f9dc7e | |||
| 66801feb17 | |||
| 02514002fd | |||
| 2056d7290a | |||
| 42a8cbe37c | |||
| 8dc226ca8f | |||
| 855d5046c7 | |||
| 67623735e0 | |||
| c367ee5439 | |||
| 8c565fa86c | |||
| 8793942c5c | |||
| 6d218d6d7a | |||
| 0a5f006736 | |||
| e7c95d91f8 | |||
| 3bba5ccf35 | |||
| ac4d5346ad | |||
| b8d677bfd0 | |||
| 66f8235510 | |||
| a08bba51a5 | |||
| 40e4ecb793 | |||
| a01aa9aa9f | |||
| 6bc18a3bd4 | |||
| 64619deaa3 | |||
| bd275702d2 | |||
| 73df153be8 | |||
| b25140c7b6 | |||
| 8db94be1d6 | |||
| 74b828f263 | |||
| e6f30e4ce1 | |||
| 13761f2833 | |||
| ba8f1864c1 | |||
| 4ddbc7bd0d | |||
| ca8c2c7eab | |||
| 964b2377d0 | |||
| 3bcbb37552 | |||
| a00fd08c2c | |||
| d66bbf3413 | |||
| 607f9807e5 | |||
| bf3f6caaf3 | |||
| 0a9222b824 | |||
| 238c274054 | |||
| 6aedfc137b | |||
| 896332581e | |||
| 929f842810 | |||
| 0967853d68 | |||
| ee2c1f3e68 | |||
| fa60369d6d | |||
| b8e2d6327a | |||
| 40e8c921ca | |||
| aa4c3f218e | |||
| d5dda9b803 | |||
| b1cbe19790 | |||
| 5b90eb98f6 | |||
| fdd5fed036 | |||
| b2c312d670 | |||
| 5b280a80df | |||
| 55761e6802 | |||
| 431e767c23 | |||
| 6cc352e216 | |||
| 2eb2889702 | |||
| 6dda166d21 | |||
| a02ed04d52 | |||
| f7412cb072 | |||
| 2d07d30c44 | |||
| cd8470f7fa | |||
| cfc120eb22 | |||
| 3b903f252a | |||
| 5be3a74c49 | |||
| dca1afb326 | |||
| f1db1a398d | |||
| 2637f3c431 | |||
| 696c13bd6a | |||
| 08e817d3e9 | |||
| ba94746eb2 | |||
| 4281bcd5d2 | |||
| 8f06074a91 | |||
| 4f94a8381a | |||
| a67b101594 | |||
| 98ca81daae | |||
| cb16f17b36 | |||
| 2a768d04c6 | |||
| f5beb883c2 | |||
| af92418b8b | |||
| 51073ce055 | |||
| d24fd47ff4 | |||
| ed84291188 | |||
| b26ab5c7bf | |||
| 3f5d13812a | |||
| fed560ff2a | |||
| cba7987978 | |||
| f6942f0d22 | |||
| acf2f34df5 | |||
| 6675cfddef | |||
| 4455e59980 | |||
| 883b5461d5 | |||
| 75d43b5785 | |||
| dd6c2e880f | |||
| 800046fecf | |||
| fadc975bf9 | |||
| 049fdfc7e0 | |||
| 71ea6b127d | |||
| 32ce0ac0d8 | |||
| 8e7bbbab15 | |||
| 941725789b | |||
| a37f286f4e | |||
| ea712e317f | |||
| 38636aba74 | |||
| 3b358b25b0 | |||
| 7f8c553d7f | |||
| f6632dae5f | |||
| a031b61230 | |||
| e8d0746b88 | |||
| d9229f9802 | |||
| 33febf6048 | |||
| 97250f4d64 | |||
| 31aad2dc2c | |||
| f8de2af7e3 | |||
| a05d427b41 | |||
| 3b777adb61 | |||
| 40e94701dc | |||
| f66e88228a | |||
| 2eb4bc5e89 | |||
| 619c8cec83 | |||
| e1068b76bd | |||
| 168fb2e98c | |||
| 11ac519d79 | |||
| fdb7a3580f | |||
| 24f5b18f93 | |||
| 75a1f23684 | |||
| dbf12fc2ce | |||
| 5dde62364e | |||
| 00f48c8273 | |||
| d1e3ce1fb0 | |||
| 64950cb07f | |||
| 4e840357fd | |||
| b15aa0aaef | |||
| 01f26f3f32 | |||
| 771df4416a | |||
| 1f1ac63bff | |||
| 666d16e262 | |||
| 31640931e6 | |||
| 7e58c5ef20 | |||
| 664e99a648 | |||
| be165a2e70 | |||
| e05b72c257 | |||
| 2450027e59 | |||
| 03a4b96c12 | |||
| 23c25d5b3a | |||
| a84b6f26a9 | |||
| c64d123933 | |||
| 751d1a1c22 | |||
| e52f4c4642 | |||
| b25a8999be | |||
| 89bd372a02 | |||
| 73ffb74b9e | |||
| e091af4f37 | |||
| 10154320fd | |||
| 2e9bb4eb96 | |||
| 861f28a624 | |||
| 4519a5a063 | |||
| 3b5b87f579 | |||
| 75d36eacf8 | |||
| 02afbd338e | |||
| 392cedd0a2 | |||
| 12fdd08a40 | |||
| 1de690b992 | |||
| 6c1f2b77de | |||
| a65c252f78 | |||
| 1c58471cc9 | |||
| e7136a978f | |||
| a4bafd33b3 | |||
| 4c7f5fa023 | |||
| 51776b0aeb | |||
| e1c3dad959 | |||
| f496249405 | |||
| ed9aed1ac6 | |||
| 63a0797ff2 | |||
| b949355132 | |||
| 312e1e4f66 | |||
| 575334657f | |||
| 81f030b106 | |||
| ced6e76661 | |||
| 737d2dffdf | |||
| e9c7b1c8ae | |||
| 21fa684236 | |||
| 9eaa3bd55d | |||
| 73d42e614c | |||
| b1cf48ea41 | |||
| 879efc3f3b | |||
| 08f5c76898 | |||
| 6b3ab72602 | |||
| cf0ce676d6 | |||
| 499742c60f | |||
| 6666886a9c | |||
| 15868b3bba | |||
| 42e93b6cf5 | |||
| 3a18bf0474 | |||
| e58f8a6b9a | |||
| 38570b26b8 | |||
| b7e5b08a20 | |||
| b1b76aee3c | |||
| cecf1a72ba | |||
| c03c218190 | |||
| 4015000e19 | |||
| 60931e2d8a | |||
| 6b35262272 | |||
| 40b24c8154 | |||
| 5663b634f4 | |||
| 1d6e36525d | |||
| 2186fbc22c | |||
| 246e27d807 | |||
| f231d6bfa6 | |||
| 6dc892fcdf | |||
| c5cc88d800 | |||
| e314e1c000 | |||
| 32c5b8dee3 | |||
| e64ef27cbe | |||
| 9a127b43b8 | |||
| 82dfea8d9e | |||
| 288ca7dcb4 | |||
| 9a4876e193 | |||
| f51f273ee8 | |||
| 36d59479a5 | |||
| 5a79ff5efd | |||
| 33fc2ba4e2 | |||
| 368cc3b7e7 | |||
| 683ffbbe57 | |||
| 9c2b36adbd | |||
| a16e86ced5 | |||
| c7d4d21413 | |||
| aba057a4e0 | |||
| 1682126fd8 | |||
| 54c259dec3 | |||
| a9c96bae8a | |||
| 6881ec0465 | |||
| 2978d055f6 | |||
| 2ff44b183a | |||
| a196ea15af | |||
| e51fb0fa71 | |||
| 769b386e97 | |||
| b86be3617d | |||
| 3c995f30e7 | |||
| d0beda01f9 | |||
| 3d8f0808e4 | |||
| a861460c89 | |||
| c0e15d1d9d | |||
| a23b68f564 | |||
| be90bf764a | |||
| 28d6979b7e | |||
| 24e36099ce | |||
| 8459d06599 | |||
| ce3773f9fe | |||
| 74795b32c6 | |||
| 046bc1fbe8 | |||
| 4cbb93195f | |||
| fd45ee7da8 | |||
| d816874c52 | |||
| 1ab133a9da | |||
| 6abaa316f0 | |||
| 0a471910b4 | |||
| 2762b3542d | |||
| 3536809644 | |||
| c11ea942b7 | |||
| 66d49b4952 | |||
| c79ae7aa8b | |||
| 3969fdf860 | |||
| 398085ba04 | |||
| e2ec654c9a | |||
| 617b818b49 | |||
| 4d71a9a2ca | |||
| 8997b2aa57 |
@@ -5,6 +5,7 @@ ssl/test/runner/runner
|
||||
doc/*.html
|
||||
doc/doc.css
|
||||
|
||||
util/bot/android_ndk
|
||||
util/bot/android_tools
|
||||
util/bot/cmake-linux64
|
||||
util/bot/cmake-linux64.tar.gz
|
||||
|
||||
+9
-16
@@ -79,14 +79,15 @@ for other variables which may be used to configure the build.
|
||||
|
||||
### Building for Android
|
||||
|
||||
It's possible to build BoringSSL with the Android NDK using CMake. This has
|
||||
been tested with version 10d of the NDK.
|
||||
It's possible to build BoringSSL with the Android NDK using CMake. Recent
|
||||
versions of the NDK include a CMake toolchain file which works with CMake 3.6.0
|
||||
or later. This has been tested with version r16b of the NDK.
|
||||
|
||||
Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
|
||||
directory. Then make a build directory as above and run CMake like this:
|
||||
|
||||
cmake -DANDROID_ABI=armeabi-v7a \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../third_party/android-cmake/android.toolchain.cmake \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
|
||||
-DANDROID_NATIVE_API_LEVEL=16 \
|
||||
-GNinja ..
|
||||
|
||||
@@ -94,7 +95,11 @@ Once you've run that, Ninja should produce Android-compatible binaries. You
|
||||
can replace `armeabi-v7a` in the above with `arm64-v8a` and use API level 21 or
|
||||
higher to build aarch64 binaries.
|
||||
|
||||
For other options, see [android-cmake's documentation](./third_party/android-cmake/README.md).
|
||||
For older NDK versions, BoringSSL ships a third-party CMake toolchain file. Use
|
||||
`../third_party/android-cmake/android.toolchain.cmake` for
|
||||
`CMAKE_TOOLCHAIN_FILE` instead.
|
||||
|
||||
For other options, see the documentation in the toolchain file.
|
||||
|
||||
### Building for iOS
|
||||
|
||||
@@ -145,18 +150,6 @@ corresponding ARM feature.
|
||||
Note that if a feature is enabled in this way, but not actually supported at
|
||||
run-time, BoringSSL will likely crash.
|
||||
|
||||
## Assembling ARMv8 with Clang
|
||||
|
||||
In order to support the ARMv8 crypto instructions, Clang requires that the
|
||||
architecture be `armv8-a+crypto`. However, setting that as a general build flag
|
||||
would allow the compiler to assume that crypto instructions are *always*
|
||||
supported, even without testing for them.
|
||||
|
||||
It's possible to set the architecture in an assembly file using the `.arch`
|
||||
directive, but only very recent versions of Clang support this. If
|
||||
`BORINGSSL_CLANG_SUPPORTS_DOT_ARCH` is defined then `.arch` directives will be
|
||||
used with Clang, otherwise you may need to craft acceptable assembler flags.
|
||||
|
||||
# Running tests
|
||||
|
||||
There are two sets of tests: the C/C++ tests and the blackbox tests. For former
|
||||
|
||||
+92
-25
@@ -1,5 +1,11 @@
|
||||
cmake_minimum_required (VERSION 2.8.11)
|
||||
|
||||
# Report AppleClang separately from Clang. Their version numbers are different.
|
||||
# https://cmake.org/cmake/help/v3.0/policy/CMP0025.html
|
||||
if(POLICY CMP0025)
|
||||
cmake_policy(SET CMP0025 NEW)
|
||||
endif()
|
||||
|
||||
# Defer enabling C and CXX languages.
|
||||
project (BoringSSL NONE)
|
||||
|
||||
@@ -36,20 +42,61 @@ if (BORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
add_definitions(-DBORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -ggdb -fvisibility=hidden -fno-common")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CLANG 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")
|
||||
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.
|
||||
# See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -W3 -Wno-unused-parameter -fmsc-version=1900")
|
||||
# googletest suppresses warning C4996 via a pragma, but clang-cl does not
|
||||
# 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")
|
||||
endif()
|
||||
|
||||
if(CLANG)
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wnewline-eof -fcolor-diagnostics")
|
||||
else()
|
||||
# GCC (at least 4.8.4) has a bug where it'll find unreachable free() calls
|
||||
# and declare that the code is trying to free a stack pointer.
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-free-nonheap-object")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${C_CXX_FLAGS} -Wmissing-declarations")
|
||||
|
||||
if(NOT BORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
NOT "6.0.0" VERSION_GREATER CMAKE_C_COMPILER_VERSION)
|
||||
# Clang's -Wtautological-constant-compare is far too aggressive and does not
|
||||
# account for, say, wanting the same code to work on both 32-bit and 64-bit
|
||||
# platforms.
|
||||
#
|
||||
# Note "Clang" and "AppleClang" version differently, so we check for an
|
||||
# exact match on the COMPILER_ID. As of writing, the warning is not in any
|
||||
# release of AppleClang yet.
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-tautological-constant-compare -Wtautological-constant-out-of-range-compare")
|
||||
endif()
|
||||
|
||||
if(CLANG OR NOT "7.0.0" VERSION_GREATER CMAKE_C_COMPILER_VERSION)
|
||||
set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wimplicit-fallthrough")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} -Wmissing-declarations")
|
||||
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
if(NOT BORINGSSL_ALLOW_CXX_RUNTIME)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes
|
||||
@@ -59,9 +106,14 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Warning-Options.html#Warning-Options
|
||||
# https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-prototypes
|
||||
# https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-declarations
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-prototypes -Wimplicit-fallthrough")
|
||||
if(CLANG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-prototypes")
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND "4.8" VERSION_GREATER CMAKE_C_COMPILER_VERSION)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-array-bounds")
|
||||
endif()
|
||||
|
||||
elseif(MSVC)
|
||||
set(MSVC_DISABLED_WARNINGS_LIST
|
||||
"C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not
|
||||
@@ -78,8 +130,6 @@ elseif(MSVC)
|
||||
# possible loss of data
|
||||
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
# possible loss of data
|
||||
"C4245" # 'initializing' : conversion from 'long' to
|
||||
# 'unsigned long', signed/unsigned mismatch
|
||||
"C4267" # conversion from 'size_t' to 'int', possible loss of data
|
||||
"C4371" # layout of class may have changed from a previous version of the
|
||||
# compiler due to better packing of member '...'
|
||||
@@ -124,7 +174,6 @@ elseif(MSVC)
|
||||
${MSVC_LEVEL4_WARNINGS_LIST})
|
||||
set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
|
||||
set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
|
||||
set(CMAKE_ASM_NASM_FLAGS "-g cv8")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@@ -138,14 +187,13 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.99") OR
|
||||
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if ((CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR
|
||||
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if ((CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||
@@ -158,7 +206,7 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
if(FUZZ)
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT CLANG)
|
||||
message(FATAL_ERROR "You need to build with Clang for fuzzing to work")
|
||||
endif()
|
||||
|
||||
@@ -186,7 +234,7 @@ if (BUILD_SHARED_LIBS)
|
||||
endif()
|
||||
|
||||
if (MSAN)
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT CLANG)
|
||||
message(FATAL_ERROR "Cannot enable MSAN unless using Clang")
|
||||
endif()
|
||||
|
||||
@@ -200,7 +248,7 @@ if (MSAN)
|
||||
endif()
|
||||
|
||||
if (ASAN)
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT CLANG)
|
||||
message(FATAL_ERROR "Cannot enable ASAN unless using Clang")
|
||||
endif()
|
||||
|
||||
@@ -209,6 +257,24 @@ if (ASAN)
|
||||
set(OPENSSL_NO_ASM "1")
|
||||
endif()
|
||||
|
||||
if(CFI)
|
||||
if(NOT CLANG)
|
||||
message(FATAL_ERROR "Cannot enable CFI unless using Clang")
|
||||
endif()
|
||||
|
||||
# TODO(crbug.com/785442): Remove -fsanitize-cfi-icall-generalize-pointers.
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-cfi-icall-generalize-pointers -flto")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-cfi-icall-generalize-pointers -flto")
|
||||
# We use Chromium's copy of clang, which requires -fuse-ld=lld if building
|
||||
# with -flto. That, in turn, can't handle -ggdb.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
|
||||
string(REPLACE "-ggdb" "-g" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REPLACE "-ggdb" "-g" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
# -flto causes object files to contain LLVM bitcode. Mixing those with
|
||||
# assembly output in the same static library breaks the linker.
|
||||
set(OPENSSL_NO_ASM "1")
|
||||
endif()
|
||||
|
||||
if (GCOV)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||
@@ -274,14 +340,14 @@ else()
|
||||
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (ANDROID AND ${ARCH} STREQUAL "arm")
|
||||
# The Android-NDK CMake files somehow fail to set the -march flag for
|
||||
# assembly files. Without this flag, the compiler believes that it's
|
||||
if (ANDROID AND NOT ANDROID_NDK_REVISION AND ${ARCH} STREQUAL "arm")
|
||||
# The third-party Android-NDK CMake files somehow fail to set the -march flag
|
||||
# for assembly files. Without this flag, the compiler believes that it's
|
||||
# building for ARMv5.
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CMAKE_ASM_FLAGS "-march=${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_ASM_FLAGS}")
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86" AND APPLE)
|
||||
if (${ARCH} STREQUAL "x86" AND APPLE AND ${CMAKE_VERSION} VERSION_LESS "3.0")
|
||||
# With CMake 2.8.x, ${CMAKE_SYSTEM_PROCESSOR} evalutes to i386 on OS X,
|
||||
# but clang defaults to 64-bit builds on OS X unless otherwise told.
|
||||
# Set ARCH to x86_64 so clang and CMake agree. This is fixed in CMake 3.
|
||||
@@ -290,8 +356,8 @@ endif()
|
||||
|
||||
# Add minimal googletest targets. The provided one has many side-effects, and
|
||||
# googletest has a very straightforward build.
|
||||
add_library(gtest third_party/googletest/src/gtest-all.cc)
|
||||
target_include_directories(gtest PRIVATE third_party/googletest)
|
||||
add_library(boringssl_gtest third_party/googletest/src/gtest-all.cc)
|
||||
target_include_directories(boringssl_gtest PRIVATE third_party/googletest)
|
||||
|
||||
include_directories(third_party/googletest/include)
|
||||
|
||||
@@ -309,6 +375,7 @@ add_custom_command(
|
||||
add_library(crypto_test_data OBJECT crypto_test_data.cc)
|
||||
|
||||
add_subdirectory(crypto)
|
||||
add_subdirectory(third_party/fiat)
|
||||
add_subdirectory(ssl)
|
||||
add_subdirectory(ssl/test)
|
||||
add_subdirectory(fipstools)
|
||||
|
||||
@@ -5,8 +5,9 @@ license. This license is reproduced at the bottom of this file.
|
||||
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
|
||||
https://cla.developers.google.com/clas
|
||||
|
||||
Some files from Intel are under yet another license, which is also included
|
||||
underneath.
|
||||
Files in third_party/ have their own licenses, as described therein. The MIT
|
||||
license, for third_party/fiat, which, unlike other third_party directories, is
|
||||
compiled into non-test libraries, is included below.
|
||||
|
||||
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
|
||||
OpenSSL License and the original SSLeay license apply to the toolkit. See below
|
||||
@@ -156,37 +157,25 @@ ISC license used for completely new code in BoringSSL:
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
|
||||
Some files from Intel carry the following license:
|
||||
The code in third_party/fiat carries the MIT license:
|
||||
|
||||
# Copyright (c) 2012, Intel Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * 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.
|
||||
#
|
||||
# * Neither the name of the Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
|
||||
# EXPRESS 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 INTEL CORPORATION OR
|
||||
# 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.
|
||||
Copyright (c) 2015-2016 the fiat-crypto authors (see
|
||||
https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS).
|
||||
|
||||
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.
|
||||
|
||||
+42
-17
@@ -6,17 +6,27 @@ BoringSSL support, provided they do not use removed APIs. In general, see if the
|
||||
library compiles and, on failure, consult the documentation in the header files
|
||||
and see if problematic features can be removed.
|
||||
|
||||
In some cases, BoringSSL-specific code may be necessary. In that case, the
|
||||
`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
|
||||
should also be used in lieu of the presence of any particular function to detect
|
||||
OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
|
||||
Before using the preprocessor, however, contact the BoringSSL maintainers about
|
||||
the missing APIs. If not an intentionally removed feature, BoringSSL will
|
||||
typically add compatibility functions for convenience.
|
||||
BoringSSL's `OPENSSL_VERSION_NUMBER` matches the OpenSSL version it targets.
|
||||
Version checks for OpenSSL should ideally work as-is in BoringSSL. BoringSSL
|
||||
also defines upstream's `OPENSSL_NO_*` feature macros corresponding to removed
|
||||
features. If the preprocessor is needed, use these version checks or feature
|
||||
macros where possible, especially when patching third-party projects. Such
|
||||
patches are more generally useful to OpenSSL consumers and thus more
|
||||
appropriate to send upstream.
|
||||
|
||||
For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
|
||||
corresponding to removed features. These may also be used to disable code which
|
||||
uses a removed feature.
|
||||
In some cases, BoringSSL-specific code may be necessary. Use the
|
||||
`OPENSSL_IS_BORINGSSL` preprocessor macro in `#ifdef`s. However, first contact
|
||||
the BoringSSL maintainers about the missing APIs. We will typically add
|
||||
compatibility functions for convenience. In particular, *contact BoringSSL
|
||||
maintainers before working around missing OpenSSL 1.1.0 accessors*. BoringSSL
|
||||
was originally derived from OpenSSL 1.0.2 but now targets OpenSSL 1.1.0. Some
|
||||
newer APIs may be missing but can be added on request. (Not all projects have
|
||||
been ported to OpenSSL 1.1.0, so BoringSSL also remains largely compatible with
|
||||
OpenSSL 1.0.2.)
|
||||
|
||||
The `OPENSSL_IS_BORINGSSL` macro may also be used to distinguish OpenSSL from
|
||||
BoringSSL in configure scripts. Do not use the presence or absence of particular
|
||||
symbols to detect BoringSSL.
|
||||
|
||||
Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
|
||||
consumers. It is not suitable for, say, a system library in a traditional Linux
|
||||
@@ -39,15 +49,19 @@ code, particularly to avoid compiler warnings.
|
||||
Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
|
||||
instead of `int` for indices and lengths.
|
||||
|
||||
### Reference counts
|
||||
### Reference counts and opaque types
|
||||
|
||||
Some external consumers increment reference counts directly by calling
|
||||
`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
|
||||
`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value. These APIs no longer
|
||||
exist in BoringSSL. Instead, code which increments reference counts should call
|
||||
the corresponding `FOO_up_ref` function, such as `EVP_PKEY_up_ref`.
|
||||
|
||||
These APIs no longer exist in BoringSSL. Instead, code which increments
|
||||
reference counts should call the corresponding `FOO_up_ref` function, such as
|
||||
`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
|
||||
may require `#ifdef`s.
|
||||
BoringSSL also hides some structs which were previously exposed in OpenSSL
|
||||
1.0.2, particularly in libssl. Use the relevant accessors instead.
|
||||
|
||||
Note that some of these APIs were added in OpenSSL 1.1.0, so projects which do
|
||||
not yet support 1.1.0 may need additional `#ifdef`s. Projects supporting OpenSSL
|
||||
1.1.0 should not require modification.
|
||||
|
||||
### Error codes
|
||||
|
||||
@@ -165,6 +179,17 @@ recommended to avoid the `out` parameter completely and always pass in `NULL`.
|
||||
Note that less error-prone APIs are available for BoringSSL-specific code (see
|
||||
below).
|
||||
|
||||
### Memory allocation
|
||||
|
||||
OpenSSL provides wrappers `OPENSSL_malloc` and `OPENSSL_free` over the standard
|
||||
`malloc` and `free`. Memory allocated by OpenSSL should be released with
|
||||
`OPENSSL_free`, not the standard `free`. However, by default, they are
|
||||
implemented directly using `malloc` and `free`, so code which mixes them up
|
||||
usually works.
|
||||
|
||||
In BoringSSL, these functions maintain additional book-keeping to zero memory
|
||||
on `OPENSSL_free`, so any mixups must be fixed.
|
||||
|
||||
## Optional BoringSSL-specific simplifications
|
||||
|
||||
BoringSSL makes some changes to OpenSSL which simplify the API but remain
|
||||
@@ -185,7 +210,7 @@ strings and loading algorithms, etc. All of these functions still exist in
|
||||
BoringSSL for convenience, but they do nothing and are not necessary.
|
||||
|
||||
The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER`
|
||||
builds, it must be called to query CPU capabitilies before the rest of the
|
||||
builds, it must be called to query CPU capabilities before the rest of the
|
||||
library. In the default configuration, this is done with a static initializer
|
||||
and is also unnecessary.
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ Variable declarations in the middle of a function or inside a `for` loop are
|
||||
allowed and preferred where possible. Note that the common `goto err` cleanup
|
||||
pattern requires lifting some variable declarations.
|
||||
|
||||
Comments should be `/* C-style */` for consistency.
|
||||
Comments should be `// C99-style` for consistency with C++.
|
||||
|
||||
When declaration pointer types, `*` should be placed next to the variable
|
||||
name, not the type. So
|
||||
When declaring pointer types, `*` should be placed next to the variable name,
|
||||
not the type. So
|
||||
|
||||
uint8_t *ptr;
|
||||
|
||||
@@ -60,6 +60,19 @@ constants for flags. If adding values to an existing set of `#define`s,
|
||||
continue with `#define`.
|
||||
|
||||
|
||||
## libssl
|
||||
|
||||
libssl was originally written in C but is being incrementally rewritten in
|
||||
C++11. As of writing, much of the style matches our C conventions rather than
|
||||
Google C++. Additionally, libssl on Linux currently may not depend on the C++
|
||||
runtime. See the C++ utilities in `ssl/internal.h` for replacements for
|
||||
problematic C++ constructs. The `util/check_imported_libraries.go` script may be
|
||||
used with a shared library build to check if a new construct is okay.
|
||||
|
||||
If unsure, match surrounding code. Discrepancies between it and Google C++ style
|
||||
will be fixed over time.
|
||||
|
||||
|
||||
## Formatting
|
||||
|
||||
Single-statement blocks are not allowed. All conditions and loops must
|
||||
@@ -185,23 +198,23 @@ behavior of the function. Pay special note to success/failure behaviors
|
||||
and caller obligations on object lifetimes. If this sacrifices
|
||||
conciseness, consider simplifying the function's behavior.
|
||||
|
||||
/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
|
||||
* will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
|
||||
* zero otherwise. */
|
||||
// EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
|
||||
// will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
|
||||
// zero otherwise.
|
||||
OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
|
||||
size_t len);
|
||||
|
||||
Explicitly mention any surprising edge cases or deviations from common
|
||||
return value patterns in legacy functions.
|
||||
|
||||
/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
|
||||
* |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
|
||||
* least |RSA_size| bytes of space. It returns the number of bytes written, or
|
||||
* -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
|
||||
* values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
|
||||
*
|
||||
* WARNING: this function is dangerous because it breaks the usual return value
|
||||
* convention. Use |RSA_sign_raw| instead. */
|
||||
// RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
|
||||
// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
|
||||
// least |RSA_size| bytes of space. It returns the number of bytes written, or
|
||||
// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
|
||||
// values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
|
||||
//
|
||||
// WARNING: this function is dangerous because it breaks the usual return value
|
||||
// convention. Use |RSA_sign_raw| instead.
|
||||
OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
|
||||
uint8_t *to, RSA *rsa, int padding);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ if(NOT OPENSSL_NO_ASM)
|
||||
# CMake does not add -isysroot and -arch flags to assembly.
|
||||
if (APPLE)
|
||||
if (CMAKE_OSX_SYSROOT)
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}")
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"")
|
||||
endif()
|
||||
foreach(arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}")
|
||||
@@ -53,6 +53,7 @@ if(NOT OPENSSL_NO_ASM)
|
||||
set(PERLASM_STYLE win32n)
|
||||
set(PERLASM_FLAGS "-DOPENSSL_IA32_SSE2")
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_FLAGS "-gcv8")
|
||||
|
||||
# On Windows, we use the NASM output, specifically built with Yasm.
|
||||
set(ASM_EXT asm)
|
||||
@@ -133,6 +134,7 @@ add_library(
|
||||
|
||||
OBJECT
|
||||
|
||||
cpu-aarch64-fuchsia.c
|
||||
cpu-aarch64-linux.c
|
||||
cpu-arm.c
|
||||
cpu-arm-linux.c
|
||||
@@ -178,6 +180,7 @@ add_library(
|
||||
$<TARGET_OBJECTS:chacha>
|
||||
$<TARGET_OBJECTS:poly1305>
|
||||
$<TARGET_OBJECTS:curve25519>
|
||||
$<TARGET_OBJECTS:fiat>
|
||||
$<TARGET_OBJECTS:buf>
|
||||
$<TARGET_OBJECTS:bn_extra>
|
||||
$<TARGET_OBJECTS:bio>
|
||||
@@ -219,6 +222,7 @@ add_executable(
|
||||
|
||||
asn1/asn1_test.cc
|
||||
base64/base64_test.cc
|
||||
buf/buf_test.cc
|
||||
bio/bio_test.cc
|
||||
bytestring/bytestring_test.cc
|
||||
chacha/chacha_test.cc
|
||||
@@ -257,6 +261,7 @@ add_executable(
|
||||
pool/pool_test.cc
|
||||
refcount_test.cc
|
||||
rsa_extra/rsa_test.cc
|
||||
self_test.cc
|
||||
test/file_test_gtest.cc
|
||||
thread_test.cc
|
||||
x509/x509_test.cc
|
||||
@@ -264,11 +269,11 @@ add_executable(
|
||||
x509v3/v3name_test.cc
|
||||
|
||||
$<TARGET_OBJECTS:crypto_test_data>
|
||||
$<TARGET_OBJECTS:gtest_main>
|
||||
$<TARGET_OBJECTS:boringssl_gtest_main>
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(crypto_test crypto gtest)
|
||||
target_link_libraries(crypto_test crypto boringssl_gtest)
|
||||
if (WIN32)
|
||||
target_link_libraries(crypto_test ws2_32)
|
||||
endif()
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
@@ -139,6 +140,11 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
@@ -211,8 +217,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
if (a->data == NULL)
|
||||
c = (unsigned char *)OPENSSL_malloc(w + 1);
|
||||
else
|
||||
c = (unsigned char *)OPENSSL_realloc_clean(a->data,
|
||||
a->length, w + 1);
|
||||
c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
|
||||
if (c == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
|
||||
+22
-11
@@ -56,6 +56,7 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
@@ -110,7 +111,6 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
long r = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
@@ -120,20 +120,31 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
else if (i != V_ASN1_ENUMERATED)
|
||||
return -1;
|
||||
|
||||
if (a->length > (int)sizeof(long)) {
|
||||
/* hmm... a bit ugly */
|
||||
return (0xffffffffL);
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
long_larger_than_uint64_t);
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r <<= 8;
|
||||
r |= (unsigned char)a->data[i];
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly */
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
return (r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
|
||||
@@ -81,6 +81,9 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
|
||||
int i, j = 0, n, ret = 1;
|
||||
|
||||
n = i2d(x, NULL);
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
|
||||
b = (char *)OPENSSL_malloc(n);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
+52
-36
@@ -57,6 +57,7 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -346,46 +347,50 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
|
||||
|
||||
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
|
||||
{
|
||||
int j, k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long) + 1];
|
||||
long d;
|
||||
|
||||
a->type = V_ASN1_INTEGER;
|
||||
if (a->length < (int)(sizeof(long) + 1)) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data =
|
||||
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
|
||||
OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
|
||||
if (v >= 0) {
|
||||
return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
|
||||
}
|
||||
if (a->data == NULL) {
|
||||
|
||||
if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
a->type = V_ASN1_NEG_INTEGER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
|
||||
{
|
||||
uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
|
||||
if (newdata == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
d = v;
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
a->type = V_ASN1_NEG_INTEGER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(long); i++) {
|
||||
if (d == 0)
|
||||
OPENSSL_free(out->data);
|
||||
out->data = newdata;
|
||||
v = CRYPTO_bswap8(v);
|
||||
memcpy(out->data, &v, sizeof(v));
|
||||
|
||||
out->type = V_ASN1_INTEGER;
|
||||
|
||||
size_t leading_zeros;
|
||||
for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
|
||||
leading_zeros++) {
|
||||
if (out->data[leading_zeros] != 0) {
|
||||
break;
|
||||
buf[i] = (int)d & 0xff;
|
||||
d >>= 8;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
a->data[j++] = buf[k];
|
||||
a->length = j;
|
||||
return (1);
|
||||
|
||||
out->length = sizeof(uint64_t) - leading_zeros;
|
||||
OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
long r = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
@@ -395,20 +400,31 @@ long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||
else if (i != V_ASN1_INTEGER)
|
||||
return -1;
|
||||
|
||||
if (a->length > (int)sizeof(long)) {
|
||||
OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
long_larger_than_uint64_t);
|
||||
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly, return all ones */
|
||||
return -1;
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r <<= 8;
|
||||
r |= (unsigned char)a->data[i];
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
return (r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
||||
|
||||
+24
-22
@@ -61,17 +61,19 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
|
||||
static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
int (*rfunc) (unsigned long value, void *in),
|
||||
int (*rfunc) (uint32_t value, void *in),
|
||||
void *arg);
|
||||
static int in_utf8(unsigned long value, void *arg);
|
||||
static int out_utf8(unsigned long value, void *arg);
|
||||
static int type_str(unsigned long value, void *arg);
|
||||
static int cpy_asc(unsigned long value, void *arg);
|
||||
static int cpy_bmp(unsigned long value, void *arg);
|
||||
static int cpy_univ(unsigned long value, void *arg);
|
||||
static int cpy_utf8(unsigned long value, void *arg);
|
||||
static int is_printable(unsigned long value);
|
||||
static int in_utf8(uint32_t value, void *arg);
|
||||
static int out_utf8(uint32_t value, void *arg);
|
||||
static int type_str(uint32_t value, void *arg);
|
||||
static int cpy_asc(uint32_t value, void *arg);
|
||||
static int cpy_bmp(uint32_t value, void *arg);
|
||||
static int cpy_univ(uint32_t value, void *arg);
|
||||
static int cpy_utf8(uint32_t value, void *arg);
|
||||
static int is_printable(uint32_t value);
|
||||
|
||||
/*
|
||||
* These functions take a string in UTF8, ASCII or multibyte form and a mask
|
||||
@@ -100,7 +102,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
unsigned char *p;
|
||||
int nchar;
|
||||
char strbuf[32];
|
||||
int (*cpyfunc) (unsigned long, void *) = NULL;
|
||||
int (*cpyfunc) (uint32_t, void *) = NULL;
|
||||
if (len == -1)
|
||||
len = strlen((const char *)in);
|
||||
if (!mask)
|
||||
@@ -253,10 +255,10 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
*/
|
||||
|
||||
static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
int (*rfunc) (unsigned long value, void *in),
|
||||
int (*rfunc) (uint32_t value, void *in),
|
||||
void *arg)
|
||||
{
|
||||
unsigned long value;
|
||||
uint32_t value;
|
||||
int ret;
|
||||
while (len) {
|
||||
if (inform == MBSTRING_ASC) {
|
||||
@@ -267,8 +269,8 @@ static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
value |= *p++;
|
||||
len -= 2;
|
||||
} else if (inform == MBSTRING_UNIV) {
|
||||
value = ((unsigned long)*p++) << 24;
|
||||
value |= ((unsigned long)*p++) << 16;
|
||||
value = ((uint32_t)*p++) << 24;
|
||||
value |= ((uint32_t)*p++) << 16;
|
||||
value |= *p++ << 8;
|
||||
value |= *p++;
|
||||
len -= 4;
|
||||
@@ -292,7 +294,7 @@ static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
|
||||
/* Just count number of characters */
|
||||
|
||||
static int in_utf8(unsigned long value, void *arg)
|
||||
static int in_utf8(uint32_t value, void *arg)
|
||||
{
|
||||
int *nchar;
|
||||
nchar = arg;
|
||||
@@ -302,7 +304,7 @@ static int in_utf8(unsigned long value, void *arg)
|
||||
|
||||
/* Determine size of output as a UTF8 String */
|
||||
|
||||
static int out_utf8(unsigned long value, void *arg)
|
||||
static int out_utf8(uint32_t value, void *arg)
|
||||
{
|
||||
int *outlen;
|
||||
outlen = arg;
|
||||
@@ -315,7 +317,7 @@ static int out_utf8(unsigned long value, void *arg)
|
||||
* "mask".
|
||||
*/
|
||||
|
||||
static int type_str(unsigned long value, void *arg)
|
||||
static int type_str(uint32_t value, void *arg)
|
||||
{
|
||||
unsigned long types;
|
||||
types = *((unsigned long *)arg);
|
||||
@@ -335,7 +337,7 @@ static int type_str(unsigned long value, void *arg)
|
||||
|
||||
/* Copy one byte per character ASCII like strings */
|
||||
|
||||
static int cpy_asc(unsigned long value, void *arg)
|
||||
static int cpy_asc(uint32_t value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
@@ -347,7 +349,7 @@ static int cpy_asc(unsigned long value, void *arg)
|
||||
|
||||
/* Copy two byte per character BMPStrings */
|
||||
|
||||
static int cpy_bmp(unsigned long value, void *arg)
|
||||
static int cpy_bmp(uint32_t value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
@@ -360,7 +362,7 @@ static int cpy_bmp(unsigned long value, void *arg)
|
||||
|
||||
/* Copy four byte per character UniversalStrings */
|
||||
|
||||
static int cpy_univ(unsigned long value, void *arg)
|
||||
static int cpy_univ(uint32_t value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
@@ -375,7 +377,7 @@ static int cpy_univ(unsigned long value, void *arg)
|
||||
|
||||
/* Copy to a UTF8String */
|
||||
|
||||
static int cpy_utf8(unsigned long value, void *arg)
|
||||
static int cpy_utf8(uint32_t value, void *arg)
|
||||
{
|
||||
unsigned char **p;
|
||||
int ret;
|
||||
@@ -387,7 +389,7 @@ static int cpy_utf8(unsigned long value, void *arg)
|
||||
}
|
||||
|
||||
/* Return 1 if the character is permitted in a PrintableString */
|
||||
static int is_printable(unsigned long value)
|
||||
static int is_printable(uint32_t value)
|
||||
{
|
||||
int ch;
|
||||
if (value > 0x7f)
|
||||
|
||||
@@ -87,134 +87,6 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
return (objsize);
|
||||
}
|
||||
|
||||
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
|
||||
{
|
||||
int i, first, len = 0, c, use_bn;
|
||||
char ftmp[24], *tmp = ftmp;
|
||||
int tmpsize = sizeof ftmp;
|
||||
const char *p;
|
||||
unsigned long l;
|
||||
BIGNUM *bl = NULL;
|
||||
|
||||
if (num == 0)
|
||||
return (0);
|
||||
else if (num == -1)
|
||||
num = strlen(buf);
|
||||
|
||||
p = buf;
|
||||
c = *(p++);
|
||||
num--;
|
||||
if ((c >= '0') && (c <= '2')) {
|
||||
first = c - '0';
|
||||
} else {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (num <= 0) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
c = *(p++);
|
||||
num--;
|
||||
for (;;) {
|
||||
if (num <= 0)
|
||||
break;
|
||||
if ((c != '.') && (c != ' ')) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
|
||||
goto err;
|
||||
}
|
||||
l = 0;
|
||||
use_bn = 0;
|
||||
for (;;) {
|
||||
if (num <= 0)
|
||||
break;
|
||||
num--;
|
||||
c = *(p++);
|
||||
if ((c == ' ') || (c == '.'))
|
||||
break;
|
||||
if ((c < '0') || (c > '9')) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
|
||||
goto err;
|
||||
}
|
||||
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
|
||||
use_bn = 1;
|
||||
if (!bl)
|
||||
bl = BN_new();
|
||||
if (!bl || !BN_set_word(bl, l))
|
||||
goto err;
|
||||
}
|
||||
if (use_bn) {
|
||||
if (!BN_mul_word(bl, 10L)
|
||||
|| !BN_add_word(bl, c - '0'))
|
||||
goto err;
|
||||
} else
|
||||
l = l * 10L + (long)(c - '0');
|
||||
}
|
||||
if (len == 0) {
|
||||
if ((first < 2) && (l >= 40)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
if (use_bn) {
|
||||
if (!BN_add_word(bl, first * 40))
|
||||
goto err;
|
||||
} else
|
||||
l += (long)first *40;
|
||||
}
|
||||
i = 0;
|
||||
if (use_bn) {
|
||||
int blsize;
|
||||
blsize = BN_num_bits(bl);
|
||||
blsize = (blsize + 6) / 7;
|
||||
if (blsize > tmpsize) {
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
tmpsize = blsize + 32;
|
||||
tmp = OPENSSL_malloc(tmpsize);
|
||||
if (!tmp)
|
||||
goto err;
|
||||
}
|
||||
while (blsize--) {
|
||||
BN_ULONG t = BN_div_word(bl, 0x80L);
|
||||
if (t == (BN_ULONG)-1)
|
||||
goto err;
|
||||
tmp[i++] = (unsigned char)t;
|
||||
}
|
||||
} else {
|
||||
|
||||
for (;;) {
|
||||
tmp[i++] = (unsigned char)l & 0x7f;
|
||||
l >>= 7L;
|
||||
if (l == 0L)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (out != NULL) {
|
||||
if (len + i > olen) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
while (--i > 0)
|
||||
out[len++] = tmp[i] | 0x80;
|
||||
out[len++] = tmp[0];
|
||||
} else
|
||||
len += i;
|
||||
}
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return (len);
|
||||
err:
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
|
||||
+13
-11
@@ -59,6 +59,8 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
|
||||
/* UTF8 utilities */
|
||||
|
||||
/*
|
||||
@@ -70,10 +72,10 @@
|
||||
* incorrectly (not minimal length).
|
||||
*/
|
||||
|
||||
int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
int UTF8_getc(const unsigned char *str, int len, uint32_t *val)
|
||||
{
|
||||
const unsigned char *p;
|
||||
unsigned long value;
|
||||
uint32_t value;
|
||||
int ret;
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
@@ -112,7 +114,7 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x7)) << 18;
|
||||
value = ((uint32_t)(*p++ & 0x7)) << 18;
|
||||
value |= (*p++ & 0x3f) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
@@ -127,9 +129,9 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
|| ((p[3] & 0xc0) != 0x80)
|
||||
|| ((p[4] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x3)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value = ((uint32_t)(*p++ & 0x3)) << 24;
|
||||
value |= ((uint32_t)(*p++ & 0x3f)) << 18;
|
||||
value |= ((uint32_t)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x200000)
|
||||
@@ -144,10 +146,10 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
|| ((p[4] & 0xc0) != 0x80)
|
||||
|| ((p[5] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x1)) << 30;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value = ((uint32_t)(*p++ & 0x1)) << 30;
|
||||
value |= ((uint32_t)(*p++ & 0x3f)) << 24;
|
||||
value |= ((uint32_t)(*p++ & 0x3f)) << 18;
|
||||
value |= ((uint32_t)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x4000000)
|
||||
@@ -167,7 +169,7 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
* most 6 characters.
|
||||
*/
|
||||
|
||||
int UTF8_putc(unsigned char *str, int len, unsigned long value)
|
||||
int UTF8_putc(unsigned char *str, int len, uint32_t value)
|
||||
{
|
||||
if (!str)
|
||||
len = 6; /* Maximum we will need */
|
||||
|
||||
@@ -435,3 +435,8 @@ unsigned char *ASN1_STRING_data(ASN1_STRING *x)
|
||||
{
|
||||
return M_ASN1_STRING_data(x);
|
||||
}
|
||||
|
||||
const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
|
||||
{
|
||||
return x->data;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,12 @@ int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
|
||||
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
|
||||
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
|
||||
|
||||
void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine);
|
||||
|
||||
int UTF8_getc(const unsigned char *str, int len, uint32_t *val);
|
||||
int UTF8_putc(unsigned char *str, int len, uint32_t value);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -60,3 +61,30 @@ TEST(ASN1Test, LargeTags) {
|
||||
EXPECT_EQ(Bytes(&kZero, 1), Bytes(obj->value.asn1_string->data,
|
||||
obj->value.asn1_string->length));
|
||||
}
|
||||
|
||||
TEST(ASN1Test, IntegerSetting) {
|
||||
bssl::UniquePtr<ASN1_INTEGER> by_bn(M_ASN1_INTEGER_new());
|
||||
bssl::UniquePtr<ASN1_INTEGER> by_long(M_ASN1_INTEGER_new());
|
||||
bssl::UniquePtr<ASN1_INTEGER> by_uint64(M_ASN1_INTEGER_new());
|
||||
bssl::UniquePtr<BIGNUM> bn(BN_new());
|
||||
|
||||
const std::vector<int64_t> kValues = {
|
||||
LONG_MIN, -2, -1, 0, 1, 2, 0xff, 0x100, 0xffff, 0x10000, LONG_MAX,
|
||||
};
|
||||
for (const auto &i : kValues) {
|
||||
SCOPED_TRACE(i);
|
||||
|
||||
ASSERT_EQ(1, ASN1_INTEGER_set(by_long.get(), i));
|
||||
const uint64_t abs = i < 0 ? (0 - (uint64_t) i) : i;
|
||||
ASSERT_TRUE(BN_set_u64(bn.get(), abs));
|
||||
BN_set_negative(bn.get(), i < 0);
|
||||
ASSERT_TRUE(BN_to_ASN1_INTEGER(bn.get(), by_bn.get()));
|
||||
|
||||
EXPECT_EQ(0, ASN1_INTEGER_cmp(by_bn.get(), by_long.get()));
|
||||
|
||||
if (i >= 0) {
|
||||
ASSERT_EQ(1, ASN1_INTEGER_set_uint64(by_uint64.get(), i));
|
||||
EXPECT_EQ(0, ASN1_INTEGER_cmp(by_bn.get(), by_uint64.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -147,15 +148,6 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ASN1_template_d2i(ASN1_VALUE **pval,
|
||||
const unsigned char **in, long len,
|
||||
const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
ASN1_TLC c;
|
||||
asn1_tlc_clear_nc(&c);
|
||||
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
|
||||
* tag mismatch return -1 to handle OPTIONAL
|
||||
@@ -188,6 +180,14 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
else
|
||||
asn1_cb = 0;
|
||||
|
||||
/*
|
||||
* Bound |len| to comfortably fit in an int. Lengths in this module often
|
||||
* switch between int and long without overflow checks.
|
||||
*/
|
||||
if (len > INT_MAX/2) {
|
||||
len = INT_MAX/2;
|
||||
}
|
||||
|
||||
switch (it->itype) {
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates) {
|
||||
|
||||
@@ -256,12 +256,6 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
|
||||
const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
return asn1_template_ex_i2d(pval, out, tt, -1, 0);
|
||||
}
|
||||
|
||||
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
|
||||
const ASN1_TEMPLATE *tt, int tag, int iclass)
|
||||
{
|
||||
|
||||
@@ -59,8 +59,7 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine);
|
||||
#include "asn1_locl.h"
|
||||
|
||||
/* Free up an ASN1 structure */
|
||||
|
||||
@@ -74,8 +73,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
asn1_item_combine_free(pval, it, 0);
|
||||
}
|
||||
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine)
|
||||
void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
|
||||
{
|
||||
const ASN1_TEMPLATE *tt = NULL, *seqtt;
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
@@ -201,7 +202,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
return 1;
|
||||
|
||||
memerr2:
|
||||
ASN1_item_ex_free(pval, it);
|
||||
asn1_item_combine_free(pval, it, combine);
|
||||
memerr:
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
@@ -211,7 +212,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
return 0;
|
||||
|
||||
auxerr2:
|
||||
ASN1_item_ex_free(pval, it);
|
||||
asn1_item_combine_free(pval, it, combine);
|
||||
auxerr:
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
|
||||
@@ -555,3 +555,82 @@ void BIO_set_retry_special(BIO *bio) {
|
||||
}
|
||||
|
||||
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
|
||||
|
||||
static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT;
|
||||
static int g_index = BIO_TYPE_START;
|
||||
|
||||
int BIO_get_new_index(void) {
|
||||
CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock);
|
||||
// If |g_index| exceeds 255, it will collide with the flags bits.
|
||||
int ret = g_index > 255 ? -1 : g_index++;
|
||||
CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BIO_METHOD *BIO_meth_new(int type, const char *name) {
|
||||
BIO_METHOD *method = OPENSSL_malloc(sizeof(BIO_METHOD));
|
||||
if (method == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
OPENSSL_memset(method, 0, sizeof(BIO_METHOD));
|
||||
method->type = type;
|
||||
method->name = name;
|
||||
return method;
|
||||
}
|
||||
|
||||
void BIO_meth_free(BIO_METHOD *method) {
|
||||
OPENSSL_free(method);
|
||||
}
|
||||
|
||||
int BIO_meth_set_create(BIO_METHOD *method,
|
||||
int (*create)(BIO *)) {
|
||||
method->create = create;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_destroy(BIO_METHOD *method,
|
||||
int (*destroy)(BIO *)) {
|
||||
method->destroy = destroy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_write(BIO_METHOD *method,
|
||||
int (*write)(BIO *, const char *, int)) {
|
||||
method->bwrite = write;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_read(BIO_METHOD *method,
|
||||
int (*read)(BIO *, char *, int)) {
|
||||
method->bread = read;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_gets(BIO_METHOD *method,
|
||||
int (*gets)(BIO *, char *, int)) {
|
||||
method->bgets = gets;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_ctrl(BIO_METHOD *method,
|
||||
long (*ctrl)(BIO *, int, long, void *)) {
|
||||
method->ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; }
|
||||
|
||||
void *BIO_get_data(BIO *bio) { return bio->ptr; }
|
||||
|
||||
void BIO_set_init(BIO *bio, int init) { bio->init = init; }
|
||||
|
||||
int BIO_get_init(BIO *bio) { return bio->init; }
|
||||
|
||||
void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; }
|
||||
|
||||
int BIO_get_shutdown(BIO *bio) { return bio->shutdown; }
|
||||
|
||||
int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) {
|
||||
// Ignore the parameter. We implement |BIO_puts| using |BIO_write|.
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#if !defined(_POSIX_C_SOURCE)
|
||||
#define _POSIX_C_SOURCE 201410L
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
@@ -31,6 +27,7 @@
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -73,6 +73,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
static int bio_fd_non_fatal_error(int err) {
|
||||
@@ -190,6 +191,7 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
num = 0;
|
||||
OPENSSL_FALLTHROUGH;
|
||||
case BIO_C_FILE_SEEK:
|
||||
ret = 0;
|
||||
if (b->init) {
|
||||
|
||||
@@ -81,6 +81,8 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#define BIO_FP_READ 0x02
|
||||
#define BIO_FP_WRITE 0x04
|
||||
@@ -183,6 +185,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
num = 0;
|
||||
OPENSSL_FALLTHROUGH;
|
||||
case BIO_C_FILE_SEEK:
|
||||
ret = (long)fseek(fp, num, 0);
|
||||
break;
|
||||
|
||||
@@ -54,10 +54,6 @@
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#if !defined(_POSIX_C_SOURCE)
|
||||
#define _POSIX_C_SOURCE 201410L // for snprintf, vprintf etc
|
||||
#endif
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -42,22 +42,6 @@ int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) {
|
||||
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
|
||||
}
|
||||
|
||||
int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret) {
|
||||
CBS child;
|
||||
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
|
||||
CBS_len(&child) == 0) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function intentionally does not reject negative numbers or non-minimal
|
||||
// encodings. Estonian IDs issued between September 2014 to September 2015 are
|
||||
// broken. See https://crbug.com/532048 and https://crbug.com/534766.
|
||||
//
|
||||
// TODO(davidben): Remove this code and callers in March 2016.
|
||||
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
|
||||
}
|
||||
|
||||
int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) {
|
||||
// Negative numbers are unsupported.
|
||||
if (BN_is_negative(bn)) {
|
||||
|
||||
@@ -77,8 +77,9 @@ int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) {
|
||||
static const char hextable[] = "0123456789abcdef";
|
||||
|
||||
char *BN_bn2hex(const BIGNUM *bn) {
|
||||
int width = bn_minimal_width(bn);
|
||||
char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ +
|
||||
bn->top * BN_BYTES * 2 + 1 /* trailing NUL */);
|
||||
width * BN_BYTES * 2 + 1 /* trailing NUL */);
|
||||
if (buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
@@ -94,7 +95,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
|
||||
}
|
||||
|
||||
int z = 0;
|
||||
for (int i = bn->top - 1; i >= 0; i--) {
|
||||
for (int i = width - 1; i >= 0; i--) {
|
||||
for (int j = BN_BITS2 - 8; j >= 0; j -= 8) {
|
||||
// strip leading zeros
|
||||
int v = ((int)(bn->d[i] >> (long)j)) & 0xff;
|
||||
@@ -153,7 +154,7 @@ static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
|
||||
in_len -= todo;
|
||||
}
|
||||
assert(i <= bn->dmax);
|
||||
bn->top = i;
|
||||
bn->width = i;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -222,7 +223,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
|
||||
goto err;
|
||||
}
|
||||
|
||||
bn_correct_top(ret);
|
||||
bn_set_minimal_width(ret);
|
||||
if (!BN_is_zero(ret)) {
|
||||
ret->neg = neg;
|
||||
}
|
||||
@@ -347,7 +348,7 @@ int BN_print(BIO *bp, const BIGNUM *a) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
for (i = bn_minimal_width(a) - 1; i >= 0; i--) {
|
||||
for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
|
||||
// strip leading zeros
|
||||
v = ((int)(a->d[i] >> (long)j)) & 0x0f;
|
||||
|
||||
+19
-27
@@ -82,15 +82,11 @@ void BUF_MEM_free(BUF_MEM *buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf->data != NULL) {
|
||||
OPENSSL_cleanse(buf->data, buf->max);
|
||||
OPENSSL_free(buf->data);
|
||||
}
|
||||
|
||||
OPENSSL_free(buf->data);
|
||||
OPENSSL_free(buf);
|
||||
}
|
||||
|
||||
static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) {
|
||||
int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) {
|
||||
if (buf->max >= cap) {
|
||||
return 1;
|
||||
}
|
||||
@@ -109,17 +105,7 @@ static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *new_buf;
|
||||
if (buf->data == NULL) {
|
||||
new_buf = OPENSSL_malloc(alloc_size);
|
||||
} else {
|
||||
if (clean) {
|
||||
new_buf = OPENSSL_realloc_clean(buf->data, buf->max, alloc_size);
|
||||
} else {
|
||||
new_buf = OPENSSL_realloc(buf->data, alloc_size);
|
||||
}
|
||||
}
|
||||
|
||||
char *new_buf = OPENSSL_realloc(buf->data, alloc_size);
|
||||
if (new_buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
@@ -130,12 +116,8 @@ static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) {
|
||||
return buf_mem_reserve(buf, cap, 0 /* don't clear old buffer contents. */);
|
||||
}
|
||||
|
||||
static size_t buf_mem_grow(BUF_MEM *buf, size_t len, int clean) {
|
||||
if (!buf_mem_reserve(buf, len, clean)) {
|
||||
size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) {
|
||||
if (!BUF_MEM_reserve(buf, len)) {
|
||||
return 0;
|
||||
}
|
||||
if (buf->length < len) {
|
||||
@@ -145,12 +127,22 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, int clean) {
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) {
|
||||
return buf_mem_grow(buf, len, 0 /* don't clear old buffer contents. */);
|
||||
size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) {
|
||||
return BUF_MEM_grow(buf, len);
|
||||
}
|
||||
|
||||
size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) {
|
||||
return buf_mem_grow(buf, len, 1 /* clear old buffer contents. */);
|
||||
int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
|
||||
size_t new_len = buf->length + len;
|
||||
if (new_len < len) {
|
||||
OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
if (!BUF_MEM_reserve(buf, new_len)) {
|
||||
return 0;
|
||||
}
|
||||
OPENSSL_memcpy(buf->data + buf->length, in, len);
|
||||
buf->length = new_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *BUF_strdup(const char *str) {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Copyright (c) 2017, 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/buf.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
TEST(BufTest, Basic) {
|
||||
bssl::UniquePtr<BUF_MEM> buf(BUF_MEM_new());
|
||||
ASSERT_TRUE(buf);
|
||||
EXPECT_EQ(0u, buf->length);
|
||||
|
||||
// Use BUF_MEM_reserve to increase buf->max.
|
||||
ASSERT_TRUE(BUF_MEM_reserve(buf.get(), 200));
|
||||
EXPECT_GE(buf->max, 200u);
|
||||
EXPECT_EQ(0u, buf->length);
|
||||
|
||||
// BUF_MEM_reserve with a smaller cap is a no-op.
|
||||
size_t old_max = buf->max;
|
||||
ASSERT_TRUE(BUF_MEM_reserve(buf.get(), 100));
|
||||
EXPECT_EQ(old_max, buf->max);
|
||||
EXPECT_EQ(0u, buf->length);
|
||||
|
||||
// BUF_MEM_grow can increase the length without reallocating.
|
||||
ASSERT_EQ(100u, BUF_MEM_grow(buf.get(), 100));
|
||||
EXPECT_EQ(100u, buf->length);
|
||||
EXPECT_EQ(old_max, buf->max);
|
||||
memset(buf->data, 'A', buf->length);
|
||||
|
||||
// If BUF_MEM_reserve reallocates, it preserves the contents.
|
||||
ASSERT_TRUE(BUF_MEM_reserve(buf.get(), old_max + 1));
|
||||
ASSERT_GE(buf->max, old_max + 1);
|
||||
EXPECT_EQ(100u, buf->length);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
EXPECT_EQ('A', buf->data[i]);
|
||||
}
|
||||
|
||||
// BUF_MEM_grow should zero everything beyond buf->length.
|
||||
memset(buf->data, 'B', buf->max);
|
||||
ASSERT_EQ(150u, BUF_MEM_grow(buf.get(), 150));
|
||||
EXPECT_EQ(150u, buf->length);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
EXPECT_EQ('B', buf->data[i]);
|
||||
}
|
||||
for (size_t i = 100; i < 150; i++) {
|
||||
EXPECT_EQ(0, buf->data[i]);
|
||||
}
|
||||
|
||||
// BUF_MEM_grow can rellocate if necessary.
|
||||
size_t new_len = buf->max + 1;
|
||||
ASSERT_EQ(new_len, BUF_MEM_grow(buf.get(), new_len));
|
||||
EXPECT_GE(buf->max, new_len);
|
||||
EXPECT_EQ(new_len, buf->length);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
EXPECT_EQ('B', buf->data[i]);
|
||||
}
|
||||
for (size_t i = 100; i < new_len; i++) {
|
||||
EXPECT_EQ(0, buf->data[i]);
|
||||
}
|
||||
|
||||
// BUF_MEM_grow can shink.
|
||||
ASSERT_EQ(50u, BUF_MEM_grow(buf.get(), 50));
|
||||
EXPECT_EQ(50u, buf->length);
|
||||
for (size_t i = 0; i < 50; i++) {
|
||||
EXPECT_EQ('B', buf->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BufTest, Append) {
|
||||
bssl::UniquePtr<BUF_MEM> buf(BUF_MEM_new());
|
||||
ASSERT_TRUE(buf);
|
||||
|
||||
ASSERT_TRUE(BUF_MEM_append(buf.get(), nullptr, 0));
|
||||
ASSERT_TRUE(BUF_MEM_append(buf.get(), "hello ", 6));
|
||||
ASSERT_TRUE(BUF_MEM_append(buf.get(), nullptr, 0));
|
||||
ASSERT_TRUE(BUF_MEM_append(buf.get(), "world", 5));
|
||||
std::string str(128, 'A');
|
||||
ASSERT_TRUE(BUF_MEM_append(buf.get(), str.data(), str.size()));
|
||||
|
||||
EXPECT_EQ("hello world" + str, std::string(buf->data, buf->length));
|
||||
}
|
||||
@@ -29,10 +29,7 @@ static const unsigned kMaxDepth = 2048;
|
||||
// is_string_type returns one if |tag| is a string type and zero otherwise. It
|
||||
// ignores the constructed bit.
|
||||
static int is_string_type(unsigned tag) {
|
||||
if ((tag & 0xc0) != 0) {
|
||||
return 0;
|
||||
}
|
||||
switch (tag & 0x1f) {
|
||||
switch (tag & ~CBS_ASN1_CONSTRUCTED) {
|
||||
case CBS_ASN1_BITSTRING:
|
||||
case CBS_ASN1_OCTETSTRING:
|
||||
case CBS_ASN1_UTF8STRING:
|
||||
|
||||
@@ -123,27 +123,27 @@ TEST(CBSTest, GetASN1) {
|
||||
uint64_t value;
|
||||
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
EXPECT_FALSE(CBS_peek_asn1_tag(&data, 0x1));
|
||||
EXPECT_TRUE(CBS_peek_asn1_tag(&data, 0x30));
|
||||
EXPECT_FALSE(CBS_peek_asn1_tag(&data, CBS_ASN1_BOOLEAN));
|
||||
EXPECT_TRUE(CBS_peek_asn1_tag(&data, CBS_ASN1_SEQUENCE));
|
||||
|
||||
ASSERT_TRUE(CBS_get_asn1(&data, &contents, 0x30));
|
||||
ASSERT_TRUE(CBS_get_asn1(&data, &contents, CBS_ASN1_SEQUENCE));
|
||||
EXPECT_EQ(Bytes("\x01\x02"), Bytes(CBS_data(&contents), CBS_len(&contents)));
|
||||
|
||||
CBS_init(&data, kData2, sizeof(kData2));
|
||||
// data is truncated
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, CBS_ASN1_SEQUENCE));
|
||||
|
||||
CBS_init(&data, kData3, sizeof(kData3));
|
||||
// zero byte length of length
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, CBS_ASN1_SEQUENCE));
|
||||
|
||||
CBS_init(&data, kData4, sizeof(kData4));
|
||||
// long form mistakenly used.
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, CBS_ASN1_SEQUENCE));
|
||||
|
||||
CBS_init(&data, kData5, sizeof(kData5));
|
||||
// length takes too many bytes.
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
|
||||
EXPECT_FALSE(CBS_get_asn1(&data, &contents, CBS_ASN1_SEQUENCE));
|
||||
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
// wrong tag.
|
||||
@@ -151,56 +151,72 @@ TEST(CBSTest, GetASN1) {
|
||||
|
||||
CBS_init(&data, NULL, 0);
|
||||
// peek at empty data.
|
||||
EXPECT_FALSE(CBS_peek_asn1_tag(&data, 0x30));
|
||||
EXPECT_FALSE(CBS_peek_asn1_tag(&data, CBS_ASN1_SEQUENCE));
|
||||
|
||||
CBS_init(&data, NULL, 0);
|
||||
// optional elements at empty data.
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
|
||||
EXPECT_FALSE(present);
|
||||
ASSERT_TRUE(
|
||||
CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_octet_string(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
|
||||
EXPECT_FALSE(present);
|
||||
EXPECT_EQ(0u, CBS_len(&contents));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_octet_string(
|
||||
&data, &contents, NULL,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
|
||||
EXPECT_EQ(0u, CBS_len(&contents));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(
|
||||
&data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, 42));
|
||||
EXPECT_EQ(42u, value);
|
||||
|
||||
CBS_init(&data, kData6, sizeof(kData6));
|
||||
// optional element.
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
|
||||
EXPECT_FALSE(present);
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa1));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1));
|
||||
EXPECT_TRUE(present);
|
||||
EXPECT_EQ(Bytes("\x04\x01\x01"),
|
||||
Bytes(CBS_data(&contents), CBS_len(&contents)));
|
||||
|
||||
CBS_init(&data, kData6, sizeof(kData6));
|
||||
// optional octet string.
|
||||
ASSERT_TRUE(
|
||||
CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_octet_string(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
|
||||
EXPECT_FALSE(present);
|
||||
EXPECT_EQ(0u, CBS_len(&contents));
|
||||
ASSERT_TRUE(
|
||||
CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_octet_string(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1));
|
||||
EXPECT_TRUE(present);
|
||||
EXPECT_EQ(Bytes("\x01"), Bytes(CBS_data(&contents), CBS_len(&contents)));
|
||||
|
||||
CBS_init(&data, kData7, sizeof(kData7));
|
||||
// invalid optional octet string.
|
||||
EXPECT_FALSE(
|
||||
CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1));
|
||||
EXPECT_FALSE(CBS_get_optional_asn1_octet_string(
|
||||
&data, &contents, &present,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1));
|
||||
|
||||
CBS_init(&data, kData8, sizeof(kData8));
|
||||
// optional integer.
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(
|
||||
&data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, 42));
|
||||
EXPECT_EQ(42u, value);
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
|
||||
ASSERT_TRUE(CBS_get_optional_asn1_uint64(
|
||||
&data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, 42));
|
||||
EXPECT_EQ(1u, value);
|
||||
|
||||
CBS_init(&data, kData9, sizeof(kData9));
|
||||
// invalid optional integer.
|
||||
EXPECT_FALSE(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
|
||||
EXPECT_FALSE(CBS_get_optional_asn1_uint64(
|
||||
&data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, 42));
|
||||
|
||||
unsigned tag;
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
@@ -217,6 +233,54 @@ TEST(CBSTest, GetASN1) {
|
||||
Bytes(CBS_data(&contents), CBS_len(&contents)));
|
||||
}
|
||||
|
||||
TEST(CBSTest, ParseASN1Tag) {
|
||||
const struct {
|
||||
bool ok;
|
||||
unsigned tag;
|
||||
std::vector<uint8_t> in;
|
||||
} kTests[] = {
|
||||
{true, CBS_ASN1_SEQUENCE, {0x30, 0}},
|
||||
{true, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4, {0xa4, 0}},
|
||||
{true, CBS_ASN1_APPLICATION | 30, {0x5e, 0}},
|
||||
{true, CBS_ASN1_APPLICATION | 31, {0x5f, 0x1f, 0}},
|
||||
{true, CBS_ASN1_APPLICATION | 32, {0x5f, 0x20, 0}},
|
||||
{true,
|
||||
CBS_ASN1_PRIVATE | CBS_ASN1_CONSTRUCTED | 0x1fffffff,
|
||||
{0xff, 0x81, 0xff, 0xff, 0xff, 0x7f, 0}},
|
||||
// Tag number fits in unsigned but not |CBS_ASN1_TAG_NUMBER_MASK|.
|
||||
{false, 0, {0xff, 0x82, 0xff, 0xff, 0xff, 0x7f, 0}},
|
||||
// Tag number does not fit in unsigned.
|
||||
{false, 0, {0xff, 0x90, 0x80, 0x80, 0x80, 0, 0}},
|
||||
// Tag number is not minimally-encoded
|
||||
{false, 0, {0x5f, 0x80, 0x1f, 0}},
|
||||
// Tag number should have used short form.
|
||||
{false, 0, {0x5f, 0x80, 0x1e, 0}},
|
||||
};
|
||||
for (const auto &t : kTests) {
|
||||
SCOPED_TRACE(Bytes(t.in));
|
||||
unsigned tag;
|
||||
CBS cbs, child;
|
||||
CBS_init(&cbs, t.in.data(), t.in.size());
|
||||
ASSERT_EQ(t.ok, !!CBS_get_any_asn1(&cbs, &child, &tag));
|
||||
if (t.ok) {
|
||||
EXPECT_EQ(t.tag, tag);
|
||||
EXPECT_EQ(0u, CBS_len(&child));
|
||||
EXPECT_EQ(0u, CBS_len(&cbs));
|
||||
|
||||
CBS_init(&cbs, t.in.data(), t.in.size());
|
||||
EXPECT_TRUE(CBS_peek_asn1_tag(&cbs, t.tag));
|
||||
EXPECT_FALSE(CBS_peek_asn1_tag(&cbs, t.tag + 1));
|
||||
|
||||
EXPECT_TRUE(CBS_get_asn1(&cbs, &child, t.tag));
|
||||
EXPECT_EQ(0u, CBS_len(&child));
|
||||
EXPECT_EQ(0u, CBS_len(&cbs));
|
||||
|
||||
CBS_init(&cbs, t.in.data(), t.in.size());
|
||||
EXPECT_FALSE(CBS_get_asn1(&cbs, &child, t.tag + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CBSTest, GetOptionalASN1Bool) {
|
||||
static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
|
||||
static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
|
||||
@@ -416,15 +480,42 @@ TEST(CBBTest, Misuse) {
|
||||
}
|
||||
|
||||
TEST(CBBTest, ASN1) {
|
||||
static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
|
||||
static const uint8_t kExpected[] = {
|
||||
// SEQUENCE { 1 2 3 }
|
||||
0x30, 3, 1, 2, 3,
|
||||
// [4 CONSTRUCTED] { 4 5 6 }
|
||||
0xa4, 3, 4, 5, 6,
|
||||
// [APPLICATION 30 PRIMITIVE] { 7 8 9 }
|
||||
0x5e, 3, 7, 8, 9,
|
||||
// [APPLICATION 31 PRIMITIVE] { 10 11 12 }
|
||||
0x5f, 0x1f, 3, 10, 11, 12,
|
||||
// [PRIVATE 2^29-1 CONSTRUCTED] { 13 14 15 }
|
||||
0xff, 0x81, 0xff, 0xff, 0xff, 0x7f, 3, 13, 14, 15,
|
||||
};
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
bssl::ScopedCBB cbb;
|
||||
CBB contents, inner_contents;
|
||||
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_SEQUENCE));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x01\x02\x03", 3));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_asn1(cbb.get(), &contents,
|
||||
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x04\x05\x06", 3));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_asn1(cbb.get(), &contents,
|
||||
CBS_ASN1_APPLICATION | 30));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x07\x08\x09", 3));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_asn1(cbb.get(), &contents,
|
||||
CBS_ASN1_APPLICATION | 31));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x0a\x0b\x0c", 3));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_asn1(cbb.get(), &contents,
|
||||
CBS_ASN1_PRIVATE | CBS_ASN1_CONSTRUCTED | 0x1fffffff));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x0d\x0e\x0f", 3));
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
|
||||
bssl::UniquePtr<uint8_t> scoper(buf);
|
||||
|
||||
@@ -432,7 +523,7 @@ TEST(CBBTest, ASN1) {
|
||||
|
||||
std::vector<uint8_t> test_data(100000, 0x42);
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_SEQUENCE));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, test_data.data(), 130));
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
|
||||
scoper.reset(buf);
|
||||
@@ -442,7 +533,7 @@ TEST(CBBTest, ASN1) {
|
||||
EXPECT_EQ(Bytes(test_data.data(), 130), Bytes(buf + 3, 130));
|
||||
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_SEQUENCE));
|
||||
ASSERT_TRUE(CBB_add_bytes(&contents, test_data.data(), 1000));
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
|
||||
scoper.reset(buf);
|
||||
@@ -452,8 +543,8 @@ TEST(CBBTest, ASN1) {
|
||||
EXPECT_EQ(Bytes(test_data.data(), 1000), Bytes(buf + 4, 1000));
|
||||
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
|
||||
ASSERT_TRUE(CBB_add_asn1(&contents, &inner_contents, 0x30));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_SEQUENCE));
|
||||
ASSERT_TRUE(CBB_add_asn1(&contents, &inner_contents, CBS_ASN1_SEQUENCE));
|
||||
ASSERT_TRUE(CBB_add_bytes(&inner_contents, test_data.data(), 100000));
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
|
||||
scoper.reset(buf);
|
||||
@@ -490,6 +581,12 @@ TEST(CBSTest, BerConvert) {
|
||||
static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
|
||||
static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
|
||||
|
||||
// kIndefBER2 contains a constructed [APPLICATION 31] with an indefinite
|
||||
// length.
|
||||
static const uint8_t kIndefBER2[] = {0x7f, 0x1f, 0x80, 0x01,
|
||||
0x01, 0x02, 0x00, 0x00};
|
||||
static const uint8_t kIndefDER2[] = {0x7f, 0x1f, 0x03, 0x01, 0x01, 0x02};
|
||||
|
||||
// kOctetStringBER contains an indefinite length OCTET STRING with two parts.
|
||||
// These parts need to be concatenated in DER form.
|
||||
static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
|
||||
@@ -534,6 +631,8 @@ TEST(CBSTest, BerConvert) {
|
||||
sizeof(kSimpleBER));
|
||||
ExpectBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
|
||||
sizeof(kIndefBER));
|
||||
ExpectBerConvert("kIndefBER2", kIndefDER2, sizeof(kIndefDER2), kIndefBER2,
|
||||
sizeof(kIndefBER2));
|
||||
ExpectBerConvert("kOctetStringBER", kOctetStringDER, sizeof(kOctetStringDER),
|
||||
kOctetStringBER, sizeof(kOctetStringBER));
|
||||
ExpectBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
|
||||
@@ -787,3 +886,168 @@ TEST(CBSTest, BitString) {
|
||||
CBS_asn1_bitstring_has_bit(&cbs, test.bit));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CBBTest, AddOIDFromText) {
|
||||
const struct {
|
||||
const char *text;
|
||||
std::vector<uint8_t> der;
|
||||
} kValidOIDs[] = {
|
||||
// Some valid values.
|
||||
{"0.0", {0x00}},
|
||||
{"0.2.3.4", {0x2, 0x3, 0x4}},
|
||||
{"1.2.3.4", {0x2a, 0x3, 0x4}},
|
||||
{"2.2.3.4", {0x52, 0x3, 0x4}},
|
||||
{"1.2.840.113554.4.1.72585",
|
||||
{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09}},
|
||||
// Test edge cases around the first component.
|
||||
{"0.39", {0x27}},
|
||||
{"1.0", {0x28}},
|
||||
{"1.39", {0x4f}},
|
||||
{"2.0", {0x50}},
|
||||
{"2.1", {0x51}},
|
||||
{"2.40", {0x78}},
|
||||
// Edge cases near an overflow.
|
||||
{"1.2.18446744073709551615",
|
||||
{0x2a, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}},
|
||||
{"2.18446744073709551535",
|
||||
{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}},
|
||||
};
|
||||
|
||||
const char *kInvalidTexts[] = {
|
||||
// Invalid second component.
|
||||
"0.40",
|
||||
"1.40",
|
||||
// Invalid first component.
|
||||
"3.1",
|
||||
// The empty string is not an OID.
|
||||
"",
|
||||
// No empty components.
|
||||
".1.2.3.4.5",
|
||||
"1..2.3.4.5",
|
||||
"1.2.3.4.5.",
|
||||
// There must be at least two components.
|
||||
"1",
|
||||
// No extra leading zeros.
|
||||
"00.1.2.3.4",
|
||||
"01.1.2.3.4",
|
||||
// Overflow for both components or 40*A + B.
|
||||
"1.2.18446744073709551616",
|
||||
"2.18446744073709551536",
|
||||
};
|
||||
|
||||
const std::vector<uint8_t> kInvalidDER[] = {
|
||||
// The empty string is not an OID.
|
||||
{},
|
||||
// Non-minimal representation.
|
||||
{0x80, 0x01},
|
||||
// Overflow. This is the DER representation of
|
||||
// 1.2.840.113554.4.1.72585.18446744073709551616. (The final value is
|
||||
// 2^64.)
|
||||
{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09,
|
||||
0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
|
||||
};
|
||||
|
||||
for (const auto &t : kValidOIDs) {
|
||||
SCOPED_TRACE(t.text);
|
||||
|
||||
bssl::ScopedCBB cbb;
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1_oid_from_text(cbb.get(), t.text, strlen(t.text)));
|
||||
uint8_t *out;
|
||||
size_t len;
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len));
|
||||
bssl::UniquePtr<uint8_t> free_out(out);
|
||||
EXPECT_EQ(Bytes(t.der), Bytes(out, len));
|
||||
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, t.der.data(), t.der.size());
|
||||
bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
|
||||
ASSERT_TRUE(text.get());
|
||||
EXPECT_STREQ(t.text, text.get());
|
||||
}
|
||||
|
||||
for (const char *t : kInvalidTexts) {
|
||||
SCOPED_TRACE(t);
|
||||
bssl::ScopedCBB cbb;
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
EXPECT_FALSE(CBB_add_asn1_oid_from_text(cbb.get(), t, strlen(t)));
|
||||
}
|
||||
|
||||
for (const auto &t : kInvalidDER) {
|
||||
SCOPED_TRACE(Bytes(t));
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, t.data(), t.size());
|
||||
bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
|
||||
EXPECT_FALSE(text);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CBBTest, FlushASN1SetOf) {
|
||||
const struct {
|
||||
std::vector<uint8_t> in, out;
|
||||
} kValidInputs[] = {
|
||||
// No elements.
|
||||
{{}, {}},
|
||||
// One element.
|
||||
{{0x30, 0x00}, {0x30, 0x00}},
|
||||
// Two identical elements.
|
||||
{{0x30, 0x00, 0x30, 0x00}, {0x30, 0x00, 0x30, 0x00}},
|
||||
// clang-format off
|
||||
{{0x30, 0x02, 0x00, 0x00,
|
||||
0x30, 0x00,
|
||||
0x01, 0x00,
|
||||
0x30, 0x02, 0x00, 0x00,
|
||||
0x30, 0x03, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00,
|
||||
0x30, 0x03, 0x00, 0x00, 0x01,
|
||||
0x30, 0x01, 0x00,
|
||||
0x01, 0x01, 0x00},
|
||||
{0x01, 0x00,
|
||||
0x01, 0x01, 0x00,
|
||||
0x30, 0x00,
|
||||
0x30, 0x00,
|
||||
0x30, 0x01, 0x00,
|
||||
0x30, 0x02, 0x00, 0x00,
|
||||
0x30, 0x02, 0x00, 0x00,
|
||||
0x30, 0x03, 0x00, 0x00, 0x00,
|
||||
0x30, 0x03, 0x00, 0x00, 0x01}},
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
for (const auto &t : kValidInputs) {
|
||||
SCOPED_TRACE(Bytes(t.in));
|
||||
|
||||
bssl::ScopedCBB cbb;
|
||||
CBB child;
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &child, CBS_ASN1_SET));
|
||||
ASSERT_TRUE(CBB_add_bytes(&child, t.in.data(), t.in.size()));
|
||||
ASSERT_TRUE(CBB_flush_asn1_set_of(&child));
|
||||
EXPECT_EQ(Bytes(t.out), Bytes(CBB_data(&child), CBB_len(&child)));
|
||||
|
||||
// Running it again should be idempotent.
|
||||
ASSERT_TRUE(CBB_flush_asn1_set_of(&child));
|
||||
EXPECT_EQ(Bytes(t.out), Bytes(CBB_data(&child), CBB_len(&child)));
|
||||
|
||||
// The ASN.1 header remain intact.
|
||||
ASSERT_TRUE(CBB_flush(cbb.get()));
|
||||
EXPECT_EQ(0x31, CBB_data(cbb.get())[0]);
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> kInvalidInputs[] = {
|
||||
{0x30},
|
||||
{0x30, 0x01},
|
||||
{0x30, 0x00, 0x30, 0x00, 0x30, 0x01},
|
||||
};
|
||||
|
||||
for (const auto &t : kInvalidInputs) {
|
||||
SCOPED_TRACE(Bytes(t));
|
||||
|
||||
bssl::ScopedCBB cbb;
|
||||
CBB child;
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &child, CBS_ASN1_SET));
|
||||
ASSERT_TRUE(CBB_add_bytes(&child, t.data(), t.size()));
|
||||
EXPECT_FALSE(CBB_flush_asn1_set_of(&child));
|
||||
}
|
||||
}
|
||||
|
||||
+201
-8
@@ -15,8 +15,10 @@
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
@@ -328,18 +330,47 @@ int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
|
||||
return cbb_add_length_prefixed(cbb, out_contents, 3);
|
||||
}
|
||||
|
||||
// add_base128_integer encodes |v| as a big-endian base-128 integer where the
|
||||
// high bit of each byte indicates where there is more data. This is the
|
||||
// encoding used in DER for both high tag number form and OID components.
|
||||
static int add_base128_integer(CBB *cbb, uint64_t v) {
|
||||
unsigned len_len = 0;
|
||||
uint64_t copy = v;
|
||||
while (copy > 0) {
|
||||
len_len++;
|
||||
copy >>= 7;
|
||||
}
|
||||
if (len_len == 0) {
|
||||
len_len = 1; // Zero is encoded with one byte.
|
||||
}
|
||||
for (unsigned i = len_len - 1; i < len_len; i--) {
|
||||
uint8_t byte = (v >> (7 * i)) & 0x7f;
|
||||
if (i != 0) {
|
||||
// The high bit denotes whether there is more data.
|
||||
byte |= 0x80;
|
||||
}
|
||||
if (!CBB_add_u8(cbb, byte)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) {
|
||||
if (tag > 0xff ||
|
||||
(tag & 0x1f) == 0x1f) {
|
||||
// Long form identifier octets are not supported. Further, all current valid
|
||||
// tag serializations are 8 bits.
|
||||
cbb->base->error = 1;
|
||||
if (!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb) ||
|
||||
// |tag|'s representation matches the DER encoding.
|
||||
!CBB_add_u8(cbb, (uint8_t)tag)) {
|
||||
// Split the tag into leading bits and tag number.
|
||||
uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0;
|
||||
unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK;
|
||||
if (tag_number >= 0x1f) {
|
||||
// Set all the bits in the tag number to signal high tag number form.
|
||||
if (!CBB_add_u8(cbb, tag_bits | 0x1f) ||
|
||||
!add_base128_integer(cbb, tag_number)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (!CBB_add_u8(cbb, tag_bits | tag_number)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -473,3 +504,165 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
|
||||
|
||||
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) ||
|
||||
!CBB_add_bytes(&child, data, data_len) ||
|
||||
!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBB_add_asn1_bool(CBB *cbb, int value) {
|
||||
CBB child;
|
||||
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) ||
|
||||
!CBB_add_u8(&child, value != 0 ? 0xff : 0) ||
|
||||
!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// parse_dotted_decimal parses one decimal component from |cbs|, where |cbs| is
|
||||
// an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the
|
||||
// component and the dot, so |cbs| may be passed into the function again for the
|
||||
// next value.
|
||||
static int parse_dotted_decimal(CBS *cbs, uint64_t *out) {
|
||||
*out = 0;
|
||||
int seen_digit = 0;
|
||||
for (;;) {
|
||||
// Valid terminators for a component are the end of the string or a
|
||||
// non-terminal dot. If the string ends with a dot, this is not a valid OID
|
||||
// string.
|
||||
uint8_t u;
|
||||
if (!CBS_get_u8(cbs, &u) ||
|
||||
(u == '.' && CBS_len(cbs) > 0)) {
|
||||
break;
|
||||
}
|
||||
if (u < '0' || u > '9' ||
|
||||
// Forbid stray leading zeros.
|
||||
(seen_digit && *out == 0) ||
|
||||
// Check for overflow.
|
||||
*out > UINT64_MAX / 10 ||
|
||||
*out * 10 > UINT64_MAX - (u - '0')) {
|
||||
return 0;
|
||||
}
|
||||
*out = *out * 10 + (u - '0');
|
||||
seen_digit = 1;
|
||||
}
|
||||
// The empty string is not a legal OID component.
|
||||
return seen_digit;
|
||||
}
|
||||
|
||||
int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) {
|
||||
if (!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, (const uint8_t *)text, len);
|
||||
|
||||
// OIDs must have at least two components.
|
||||
uint64_t a, b;
|
||||
if (!parse_dotted_decimal(&cbs, &a) ||
|
||||
!parse_dotted_decimal(&cbs, &b)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The first component is encoded as 40 * |a| + |b|. This assumes that |a| is
|
||||
// 0, 1, or 2 and that, when it is 0 or 1, |b| is at most 39.
|
||||
if (a > 2 ||
|
||||
(a < 2 && b > 39) ||
|
||||
b > UINT64_MAX - 80 ||
|
||||
!add_base128_integer(cbb, 40u * a + b)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The remaining components are encoded unmodified.
|
||||
while (CBS_len(&cbs) > 0) {
|
||||
if (!parse_dotted_decimal(&cbs, &a) ||
|
||||
!add_base128_integer(cbb, a)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int compare_set_of_element(const void *a_ptr, const void *b_ptr) {
|
||||
// See X.690, section 11.6 for the ordering. They are sorted in ascending
|
||||
// order by their DER encoding.
|
||||
const CBS *a = a_ptr, *b = b_ptr;
|
||||
size_t a_len = CBS_len(a), b_len = CBS_len(b);
|
||||
size_t min_len = a_len < b_len ? a_len : b_len;
|
||||
int ret = OPENSSL_memcmp(CBS_data(a), CBS_data(b), min_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (a_len == b_len) {
|
||||
return 0;
|
||||
}
|
||||
// If one is a prefix of the other, the shorter one sorts first. (This is not
|
||||
// actually reachable. No DER encoding is a prefix of another DER encoding.)
|
||||
return a_len < b_len ? -1 : 1;
|
||||
}
|
||||
|
||||
int CBB_flush_asn1_set_of(CBB *cbb) {
|
||||
if (!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBS cbs;
|
||||
size_t num_children = 0;
|
||||
CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb));
|
||||
while (CBS_len(&cbs) != 0) {
|
||||
if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
num_children++;
|
||||
}
|
||||
|
||||
if (num_children < 2) {
|
||||
return 1; // Nothing to do. This is the common case for X.509.
|
||||
}
|
||||
if (num_children > ((size_t)-1) / sizeof(CBS)) {
|
||||
return 0; // Overflow.
|
||||
}
|
||||
|
||||
// Parse out the children and sort. We alias them into a copy of so they
|
||||
// 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);
|
||||
CBS *children = OPENSSL_malloc(num_children * sizeof(CBS));
|
||||
if (buf == NULL || children == NULL) {
|
||||
goto err;
|
||||
}
|
||||
CBS_init(&cbs, buf, buf_len);
|
||||
for (size_t i = 0; i < num_children; i++) {
|
||||
if (!CBS_get_any_asn1_element(&cbs, &children[i], NULL, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
qsort(children, num_children, sizeof(CBS), compare_set_of_element);
|
||||
|
||||
// Rewind |cbb| and write the contents back in the new order.
|
||||
cbb->base->len = cbb->offset + cbb->pending_len_len;
|
||||
for (size_t i = 0; i < num_children; i++) {
|
||||
if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
assert(CBB_len(cbb) == buf_len);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(buf);
|
||||
OPENSSL_free(children);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+150
-20
@@ -12,11 +12,16 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#if !defined(__STDC_FORMAT_MACROS)
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
@@ -175,18 +180,36 @@ int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
|
||||
return cbs_get_length_prefixed(cbs, out, 3);
|
||||
}
|
||||
|
||||
static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
size_t *out_header_len, int ber_ok) {
|
||||
uint8_t tag, length_byte;
|
||||
CBS header = *cbs;
|
||||
CBS throwaway;
|
||||
// parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets
|
||||
// |*out| to the result. This is the encoding used in DER for both high tag
|
||||
// number form and OID components.
|
||||
static int parse_base128_integer(CBS *cbs, uint64_t *out) {
|
||||
uint64_t v = 0;
|
||||
uint8_t b;
|
||||
do {
|
||||
if (!CBS_get_u8(cbs, &b)) {
|
||||
return 0;
|
||||
}
|
||||
if ((v >> (64 - 7)) != 0) {
|
||||
// The value is too large.
|
||||
return 0;
|
||||
}
|
||||
if (v == 0 && b == 0x80) {
|
||||
// The value must be minimally encoded.
|
||||
return 0;
|
||||
}
|
||||
v = (v << 7) | (b & 0x7f);
|
||||
|
||||
if (out == NULL) {
|
||||
out = &throwaway;
|
||||
}
|
||||
// Values end at an octet with the high bit cleared.
|
||||
} while (b & 0x80);
|
||||
|
||||
if (!CBS_get_u8(&header, &tag) ||
|
||||
!CBS_get_u8(&header, &length_byte)) {
|
||||
*out = v;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_asn1_tag(CBS *cbs, unsigned *out) {
|
||||
uint8_t tag_byte;
|
||||
if (!CBS_get_u8(cbs, &tag_byte)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -197,22 +220,58 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
// allotted bits), then the tag is more than one byte long and the
|
||||
// continuation bytes contain the tag number. This parser only supports tag
|
||||
// numbers less than 31 (and thus single-byte tags).
|
||||
if ((tag & 0x1f) == 0x1f) {
|
||||
return 0;
|
||||
unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT;
|
||||
unsigned tag_number = tag_byte & 0x1f;
|
||||
if (tag_number == 0x1f) {
|
||||
uint64_t v;
|
||||
if (!parse_base128_integer(cbs, &v) ||
|
||||
// Check the tag number is within our supported bounds.
|
||||
v > CBS_ASN1_TAG_NUMBER_MASK ||
|
||||
// Small tag numbers should have used low tag number form.
|
||||
v < 0x1f) {
|
||||
return 0;
|
||||
}
|
||||
tag_number = (unsigned)v;
|
||||
}
|
||||
|
||||
tag |= tag_number;
|
||||
|
||||
*out = tag;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
size_t *out_header_len, int ber_ok) {
|
||||
CBS header = *cbs;
|
||||
CBS throwaway;
|
||||
|
||||
if (out == NULL) {
|
||||
out = &throwaway;
|
||||
}
|
||||
|
||||
unsigned tag;
|
||||
if (!parse_asn1_tag(&header, &tag)) {
|
||||
return 0;
|
||||
}
|
||||
if (out_tag != NULL) {
|
||||
*out_tag = tag;
|
||||
}
|
||||
|
||||
uint8_t length_byte;
|
||||
if (!CBS_get_u8(&header, &length_byte)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t header_len = CBS_len(cbs) - CBS_len(&header);
|
||||
|
||||
size_t len;
|
||||
// The format for the length encoding is specified in ITU-T X.690 section
|
||||
// 8.1.3.
|
||||
if ((length_byte & 0x80) == 0) {
|
||||
// Short form length.
|
||||
len = ((size_t) length_byte) + 2;
|
||||
len = ((size_t) length_byte) + header_len;
|
||||
if (out_header_len != NULL) {
|
||||
*out_header_len = 2;
|
||||
*out_header_len = header_len;
|
||||
}
|
||||
} else {
|
||||
// The high bit indicate that this is the long form, while the next 7 bits
|
||||
@@ -224,9 +283,9 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
|
||||
// indefinite length
|
||||
if (out_header_len != NULL) {
|
||||
*out_header_len = 2;
|
||||
*out_header_len = header_len;
|
||||
}
|
||||
return CBS_get_bytes(cbs, out, 2);
|
||||
return CBS_get_bytes(cbs, out, header_len);
|
||||
}
|
||||
|
||||
// ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
|
||||
@@ -249,13 +308,13 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
return 0;
|
||||
}
|
||||
len = len32;
|
||||
if (len + 2 + num_bytes < len) {
|
||||
if (len + header_len + num_bytes < len) {
|
||||
// Overflow.
|
||||
return 0;
|
||||
}
|
||||
len += 2 + num_bytes;
|
||||
len += header_len + num_bytes;
|
||||
if (out_header_len != NULL) {
|
||||
*out_header_len = 2 + num_bytes;
|
||||
*out_header_len = header_len + num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +382,10 @@ int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
|
||||
if (CBS_len(cbs) < 1) {
|
||||
return 0;
|
||||
}
|
||||
return CBS_data(cbs)[0] == tag_value;
|
||||
|
||||
CBS copy = *cbs;
|
||||
unsigned actual_tag;
|
||||
return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag;
|
||||
}
|
||||
|
||||
int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
|
||||
@@ -363,6 +425,22 @@ int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBS_get_asn1_bool(CBS *cbs, int *out) {
|
||||
CBS bytes;
|
||||
if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) ||
|
||||
CBS_len(&bytes) != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t value = *CBS_data(&bytes);
|
||||
if (value != 0 && value != 0xff) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = !!value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
|
||||
int present = 0;
|
||||
|
||||
@@ -485,3 +563,55 @@ int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
|
||||
return byte_num < CBS_len(cbs) &&
|
||||
(CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
|
||||
}
|
||||
|
||||
static int add_decimal(CBB *out, uint64_t v) {
|
||||
char buf[DECIMAL_SIZE(uint64_t) + 1];
|
||||
BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v);
|
||||
return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf));
|
||||
}
|
||||
|
||||
char *CBS_asn1_oid_to_text(const CBS *cbs) {
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, 32)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
CBS copy = *cbs;
|
||||
// The first component is 40 * value1 + value2, where value1 is 0, 1, or 2.
|
||||
uint64_t v;
|
||||
if (!parse_base128_integer(©, &v)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (v >= 80) {
|
||||
if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
|
||||
!add_decimal(&cbb, v - 80)) {
|
||||
goto err;
|
||||
}
|
||||
} else if (!add_decimal(&cbb, v / 40) ||
|
||||
!CBB_add_u8(&cbb, '.') ||
|
||||
!add_decimal(&cbb, v % 40)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (CBS_len(©) != 0) {
|
||||
if (!parse_base128_integer(©, &v) ||
|
||||
!CBB_add_u8(&cbb, '.') ||
|
||||
!add_decimal(&cbb, v)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *txt;
|
||||
size_t txt_len;
|
||||
if (!CBB_add_u8(&cbb, '\0') ||
|
||||
!CBB_finish(&cbb, &txt, &txt_len)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (char *)txt;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -171,6 +171,10 @@ my @ret;
|
||||
$code.=<<___;
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
|
||||
@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
|
||||
.arch armv7-a
|
||||
|
||||
.text
|
||||
#if defined(__thumb2__) || defined(__clang__)
|
||||
.syntax unified
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
# Denver 4.50/+82% 2.63 2.67(*)
|
||||
# X-Gene 9.50/+46% 8.82 8.89(*)
|
||||
# Mongoose 8.00/+44% 3.64 3.25
|
||||
# Kryo 8.17/+50% 4.83 4.65
|
||||
#
|
||||
# (*) it's expected that doubling interleave factor doesn't help
|
||||
# all processors, only those with higher NEON latency and
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
|
||||
@@ -22,6 +22,7 @@ add_library(
|
||||
e_rc4.c
|
||||
e_aesgcmsiv.c
|
||||
e_aesctrhmac.c
|
||||
e_aesccm.c
|
||||
e_chacha20poly1305.c
|
||||
|
||||
tls_cbc.c
|
||||
|
||||
@@ -93,6 +93,8 @@ static const struct KnownAEAD kAEADs[] = {
|
||||
"aes_128_ctr_hmac_sha256.txt", false, true, 0},
|
||||
{"AES_256_CTR_HMAC_SHA256", EVP_aead_aes_256_ctr_hmac_sha256,
|
||||
"aes_256_ctr_hmac_sha256.txt", false, true, 0},
|
||||
{"AES_128_CCM_BLUETOOTH", EVP_aead_aes_128_ccm_bluetooth,
|
||||
"aes_128_ccm_bluetooth_tests.txt", false, false, 0},
|
||||
};
|
||||
|
||||
class PerAEADTest : public testing::TestWithParam<KnownAEAD> {
|
||||
@@ -651,3 +653,39 @@ TEST(AEADTest, AESGCMEmptyNonce) {
|
||||
EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
|
||||
}
|
||||
|
||||
TEST(AEADTest, AESCCMLargeAD) {
|
||||
static const std::vector<uint8_t> kKey(16, 'A');
|
||||
static const std::vector<uint8_t> kNonce(13, 'N');
|
||||
static const std::vector<uint8_t> kAD(65536, 'D');
|
||||
static const std::vector<uint8_t> kPlaintext = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
||||
static const std::vector<uint8_t> kCiphertext = {
|
||||
0xa2, 0x12, 0x3f, 0x0b, 0x07, 0xd5, 0x02, 0xff,
|
||||
0xa9, 0xcd, 0xa0, 0xf3, 0x69, 0x1c, 0x49, 0x0c};
|
||||
static const std::vector<uint8_t> kTag = {0x4a, 0x31, 0x82, 0x96};
|
||||
|
||||
// Test AES-128-CCM-Bluetooth.
|
||||
bssl::ScopedEVP_AEAD_CTX ctx;
|
||||
ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_128_ccm_bluetooth(),
|
||||
kKey.data(), kKey.size(),
|
||||
EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
|
||||
|
||||
std::vector<uint8_t> out(kCiphertext.size() + kTag.size());
|
||||
size_t out_len;
|
||||
EXPECT_TRUE(EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(),
|
||||
kNonce.data(), kNonce.size(), kPlaintext.data(),
|
||||
kPlaintext.size(), kAD.data(), kAD.size()));
|
||||
|
||||
ASSERT_EQ(out_len, kCiphertext.size() + kTag.size());
|
||||
EXPECT_EQ(Bytes(kCiphertext), Bytes(out.data(), kCiphertext.size()));
|
||||
EXPECT_EQ(Bytes(kTag), Bytes(out.data() + kCiphertext.size(), kTag.size()));
|
||||
|
||||
EXPECT_TRUE(EVP_AEAD_CTX_open(ctx.get(), out.data(), &out_len, out.size(),
|
||||
kNonce.data(), kNonce.size(), out.data(),
|
||||
out.size(), kAD.data(), kAD.size()));
|
||||
|
||||
ASSERT_EQ(out_len, kPlaintext.size());
|
||||
EXPECT_EQ(Bytes(kPlaintext), Bytes(out.data(), kPlaintext.size()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/* Copyright (c) 2018, 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/aead.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../fipsmodule/cipher/internal.h"
|
||||
|
||||
|
||||
#define EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN 4
|
||||
#define EVP_AEAD_AES_CCM_BLUETOOTH_NONCE_LEN 13
|
||||
|
||||
#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16
|
||||
|
||||
struct aead_aes_ccm_ctx {
|
||||
union {
|
||||
double align;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
CCM128_CONTEXT ccm;
|
||||
};
|
||||
|
||||
static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
if (key_len != 16) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0; // EVP_AEAD_CTX_init should catch this.
|
||||
}
|
||||
|
||||
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
|
||||
tag_len = EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN;
|
||||
}
|
||||
|
||||
if (tag_len != EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct aead_aes_ccm_ctx *ccm_ctx =
|
||||
OPENSSL_malloc(sizeof(struct aead_aes_ccm_ctx));
|
||||
if (ccm_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
block128_f block;
|
||||
ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len);
|
||||
ctx->tag_len = tag_len;
|
||||
if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, tag_len,
|
||||
15 - EVP_AEAD_AES_CCM_BLUETOOTH_NONCE_LEN)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(ccm_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->aead_state = ccm_ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aead_aes_ccm_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
OPENSSL_free(ctx->aead_state);
|
||||
}
|
||||
|
||||
static int aead_aes_ccm_seal_scatter(
|
||||
const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag,
|
||||
size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce,
|
||||
size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in,
|
||||
size_t extra_in_len, const uint8_t *ad, size_t ad_len) {
|
||||
const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state;
|
||||
|
||||
if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_tag_len < ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, out_tag,
|
||||
ctx->tag_len, nonce, nonce_len, in, in_len, ad,
|
||||
ad_len)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_tag_len = ctx->tag_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_aes_ccm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *in_tag, size_t in_tag_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state;
|
||||
|
||||
if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_tag_len != ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t tag[EVP_AEAD_AES_CCM_MAX_TAG_LEN];
|
||||
assert(ctx->tag_len <= EVP_AEAD_AES_CCM_MAX_TAG_LEN);
|
||||
if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, tag,
|
||||
ctx->tag_len, nonce, nonce_len, in, in_len, ad,
|
||||
ad_len)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_aes_128_ccm_bluetooth = {
|
||||
16,
|
||||
EVP_AEAD_AES_CCM_BLUETOOTH_NONCE_LEN, // nonce length
|
||||
EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN, // overhead
|
||||
EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN, // max tag length
|
||||
0, // seal_scatter_supports_extra_in
|
||||
|
||||
aead_aes_ccm_bluetooth_init,
|
||||
NULL /* init_with_direction */,
|
||||
aead_aes_ccm_cleanup,
|
||||
NULL /* open */,
|
||||
aead_aes_ccm_seal_scatter,
|
||||
aead_aes_ccm_open_gather,
|
||||
NULL /* get_iv */,
|
||||
NULL /* tag_len */,
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void) {
|
||||
return &aead_aes_128_ccm_bluetooth;
|
||||
}
|
||||
@@ -102,9 +102,7 @@ static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
}
|
||||
|
||||
static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(aes_ctx, sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
|
||||
OPENSSL_free(aes_ctx);
|
||||
OPENSSL_free(ctx->aead_state);
|
||||
}
|
||||
|
||||
static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) {
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
struct aead_aes_gcm_siv_asm_ctx {
|
||||
alignas(16) uint8_t key[16*15];
|
||||
int is_128_bit;
|
||||
// ptr contains the original pointer from |OPENSSL_malloc|, which may only be
|
||||
// 8-byte aligned. When freeing this structure, actually call |OPENSSL_free|
|
||||
// on this pointer.
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to
|
||||
@@ -64,14 +68,18 @@ static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx =
|
||||
OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_asm_ctx));
|
||||
if (gcm_siv_ctx == NULL) {
|
||||
char *ptr = OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_asm_ctx) + 8);
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
assert((((uintptr_t)ptr) & 7) == 0);
|
||||
|
||||
// gcm_siv_ctx needs to be 16-byte aligned in a cross-platform way.
|
||||
struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx =
|
||||
(struct aead_aes_gcm_siv_asm_ctx *)(ptr + (((uintptr_t)ptr) & 8));
|
||||
|
||||
// malloc should return a 16-byte-aligned address.
|
||||
assert((((uintptr_t)gcm_siv_ctx) & 15) == 0);
|
||||
gcm_siv_ctx->ptr = ptr;
|
||||
|
||||
if (key_bits == 128) {
|
||||
aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]);
|
||||
@@ -87,9 +95,8 @@ static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
}
|
||||
|
||||
static void aead_aes_gcm_siv_asm_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_aes_gcm_siv_asm_ctx *gcm_siv_asm_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(gcm_siv_asm_ctx, sizeof(struct aead_aes_gcm_siv_asm_ctx));
|
||||
OPENSSL_free(gcm_siv_asm_ctx);
|
||||
const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state;
|
||||
OPENSSL_free(gcm_siv_ctx->ptr);
|
||||
}
|
||||
|
||||
// aesgcmsiv_polyval_horner updates the POLYVAL value in |in_out_poly| to
|
||||
@@ -585,9 +592,7 @@ static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
}
|
||||
|
||||
static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(gcm_siv_ctx, sizeof(struct aead_aes_gcm_siv_ctx));
|
||||
OPENSSL_free(gcm_siv_ctx);
|
||||
OPENSSL_free(ctx->aead_state);
|
||||
}
|
||||
|
||||
// gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from
|
||||
|
||||
@@ -136,9 +136,7 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
}
|
||||
|
||||
static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key));
|
||||
OPENSSL_free(c20_ctx);
|
||||
OPENSSL_free(ctx->aead_state);
|
||||
}
|
||||
|
||||
static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/nid.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#define c2l(c, l) \
|
||||
do { \
|
||||
@@ -73,18 +75,25 @@
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
(l2) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 7: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 6: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 5: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 4: \
|
||||
(l1) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 3: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 2: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 1: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))); \
|
||||
} \
|
||||
@@ -104,18 +113,25 @@
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 7: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 6: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 5: \
|
||||
*(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 4: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 3: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 2: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
|
||||
OPENSSL_FALLTHROUGH; \
|
||||
case 1: \
|
||||
*(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
} \
|
||||
|
||||
@@ -48,7 +48,6 @@ static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
|
||||
EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx);
|
||||
HMAC_CTX_cleanup(&tls_ctx->hmac_ctx);
|
||||
OPENSSL_cleanse(&tls_ctx->mac_key, sizeof(tls_ctx->mac_key));
|
||||
OPENSSL_free(tls_ctx);
|
||||
ctx->aead_state = NULL;
|
||||
}
|
||||
@@ -192,8 +191,7 @@ static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
// block from encrypting the input and split the result between |out| and
|
||||
// |out_tag|. Then feed the rest.
|
||||
|
||||
const size_t early_mac_len =
|
||||
(block_size - (in_len % block_size) % block_size);
|
||||
const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size;
|
||||
if (early_mac_len != 0) {
|
||||
assert(len + block_size - early_mac_len == in_len);
|
||||
uint8_t buf[EVP_MAX_BLOCK_LENGTH];
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
KEY: 404142434445464748494a4b4c4d4e4f
|
||||
NONCE: 101112131415161718191a1b1c
|
||||
IN: 20212223
|
||||
AD: 0001020304050607
|
||||
CT: 69915dad
|
||||
TAG: 064617ca
|
||||
|
||||
KEY: 404142434445464748494a4b4c4d4e4f
|
||||
NONCE: 101112131415161718191a1b1c
|
||||
IN: 202122232425262728292a2b2c2d2e2f
|
||||
AD: 0001020304050607
|
||||
CT: 69915dad1e84c6376a68c2967e4dab61
|
||||
TAG: 99763ebb
|
||||
|
||||
KEY: 404142434445464748494a4b4c4d4e4f
|
||||
NONCE: 101112131415161718191a1b1c
|
||||
IN: 202122232425262728292a2b2c2d2e2f
|
||||
AD:
|
||||
CT: 69915dad1e84c6376a68c2967e4dab61
|
||||
TAG: c4630026
|
||||
+2
-2
@@ -791,13 +791,13 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
|
||||
}
|
||||
}
|
||||
|
||||
int CONF_modules_load_file(CONF_MUST_BE_NULL *filename, const char *appname,
|
||||
int CONF_modules_load_file(const char *filename, const char *appname,
|
||||
unsigned long flags) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CONF_modules_free(void) {}
|
||||
|
||||
void OPENSSL_config(CONF_MUST_BE_NULL *config_name) {}
|
||||
void OPENSSL_config(const char *config_name) {}
|
||||
|
||||
void OPENSSL_no_config(void) {}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 2018, 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/cpu.h>
|
||||
|
||||
#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FUCHSIA) && \
|
||||
!defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
#include <zircon/features.h>
|
||||
#include <zircon/syscalls.h>
|
||||
#include <zircon/types.h>
|
||||
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
void OPENSSL_cpuid_setup(void) {
|
||||
uint32_t hwcap;
|
||||
zx_status_t rc = zx_system_get_features(ZX_FEATURE_KIND_CPU, &hwcap);
|
||||
if (rc != ZX_OK || (hwcap & ZX_ARM64_FEATURE_ISA_ASIMD) == 0) {
|
||||
// Matching OpenSSL, if NEON/ASIMD is missing, don't report other features
|
||||
// either.
|
||||
return;
|
||||
}
|
||||
|
||||
OPENSSL_armcap_P |= ARMV7_NEON;
|
||||
|
||||
if (hwcap & ZX_ARM64_FEATURE_ISA_AES) {
|
||||
OPENSSL_armcap_P |= ARMV8_AES;
|
||||
}
|
||||
if (hwcap & ZX_ARM64_FEATURE_ISA_PMULL) {
|
||||
OPENSSL_armcap_P |= ARMV8_PMULL;
|
||||
}
|
||||
if (hwcap & ZX_ARM64_FEATURE_ISA_SHA1) {
|
||||
OPENSSL_armcap_P |= ARMV8_SHA1;
|
||||
}
|
||||
if (hwcap & ZX_ARM64_FEATURE_ISA_SHA2) {
|
||||
OPENSSL_armcap_P |= ARMV8_SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_STATIC_ARMCAP)
|
||||
#if defined(OPENSSL_AARCH64) && defined(OPENSSL_LINUX) && \
|
||||
!defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
#include <sys/auxv.h>
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ static int has_broken_neon(const STRING_PIECE *cpuinfo) {
|
||||
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
static int g_has_broken_neon;
|
||||
static int g_has_broken_neon, g_needs_hwcap2_workaround;
|
||||
|
||||
void OPENSSL_cpuid_setup(void) {
|
||||
char *cpuinfo_data;
|
||||
@@ -336,6 +336,7 @@ void OPENSSL_cpuid_setup(void) {
|
||||
}
|
||||
if (hwcap2 == 0) {
|
||||
hwcap2 = get_hwcap2_cpuinfo(&cpuinfo);
|
||||
g_needs_hwcap2_workaround = hwcap2 != 0;
|
||||
}
|
||||
|
||||
if (hwcap2 & HWCAP2_AES) {
|
||||
@@ -357,4 +358,6 @@ void OPENSSL_cpuid_setup(void) {
|
||||
|
||||
int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; }
|
||||
|
||||
int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; }
|
||||
|
||||
#endif // OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP
|
||||
|
||||
+17
-17
@@ -164,7 +164,7 @@ void OPENSSL_cpuid_setup(void) {
|
||||
uint32_t num_extended_ids = eax;
|
||||
if (num_extended_ids >= 0x80000001) {
|
||||
OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001);
|
||||
if (ecx & (1 << 11)) {
|
||||
if (ecx & (1u << 11)) {
|
||||
has_amd_xop = 1;
|
||||
}
|
||||
}
|
||||
@@ -193,68 +193,68 @@ void OPENSSL_cpuid_setup(void) {
|
||||
OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1);
|
||||
|
||||
// Adjust the hyper-threading bit.
|
||||
if (edx & (1 << 28)) {
|
||||
if (edx & (1u << 28)) {
|
||||
uint32_t num_logical_cores = (ebx >> 16) & 0xff;
|
||||
if (cores_per_cache == 1 || num_logical_cores <= 1) {
|
||||
edx &= ~(1 << 28);
|
||||
edx &= ~(1u << 28);
|
||||
}
|
||||
}
|
||||
|
||||
// Reserved bit #20 was historically repurposed to control the in-memory
|
||||
// representation of RC4 state. Always set it to zero.
|
||||
edx &= ~(1 << 20);
|
||||
edx &= ~(1u << 20);
|
||||
|
||||
// Reserved bit #30 is repurposed to signal an Intel CPU.
|
||||
if (is_intel) {
|
||||
edx |= (1 << 30);
|
||||
edx |= (1u << 30);
|
||||
|
||||
// Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables
|
||||
// some Silvermont-specific codepaths which perform better. See OpenSSL
|
||||
// commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f.
|
||||
if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ ||
|
||||
(eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) {
|
||||
ecx &= ~(1 << 26);
|
||||
ecx &= ~(1u << 26);
|
||||
}
|
||||
} else {
|
||||
edx &= ~(1 << 30);
|
||||
edx &= ~(1u << 30);
|
||||
}
|
||||
|
||||
// The SDBG bit is repurposed to denote AMD XOP support.
|
||||
if (has_amd_xop) {
|
||||
ecx |= (1 << 11);
|
||||
ecx |= (1u << 11);
|
||||
} else {
|
||||
ecx &= ~(1 << 11);
|
||||
ecx &= ~(1u << 11);
|
||||
}
|
||||
|
||||
uint64_t xcr0 = 0;
|
||||
if (ecx & (1 << 27)) {
|
||||
if (ecx & (1u << 27)) {
|
||||
// XCR0 may only be queried if the OSXSAVE bit is set.
|
||||
xcr0 = OPENSSL_xgetbv(0);
|
||||
}
|
||||
// See Intel manual, volume 1, section 14.3.
|
||||
if ((xcr0 & 6) != 6) {
|
||||
// YMM registers cannot be used.
|
||||
ecx &= ~(1 << 28); // AVX
|
||||
ecx &= ~(1 << 12); // FMA
|
||||
ecx &= ~(1 << 11); // AMD XOP
|
||||
ecx &= ~(1u << 28); // AVX
|
||||
ecx &= ~(1u << 12); // FMA
|
||||
ecx &= ~(1u << 11); // AMD XOP
|
||||
// Clear AVX2 and AVX512* bits.
|
||||
//
|
||||
// TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream
|
||||
// doesn't clear those.
|
||||
extended_features &=
|
||||
~((1 << 5) | (1 << 16) | (1 << 21) | (1 << 30) | (1 << 31));
|
||||
~((1u << 5) | (1u << 16) | (1u << 21) | (1u << 30) | (1u << 31));
|
||||
}
|
||||
// See Intel manual, volume 1, section 15.2.
|
||||
if ((xcr0 & 0xe6) != 0xe6) {
|
||||
// Clear AVX512F. Note we don't touch other AVX512 extensions because they
|
||||
// can be used with YMM.
|
||||
extended_features &= ~(1 << 16);
|
||||
extended_features &= ~(1u << 16);
|
||||
}
|
||||
|
||||
// Disable ADX instructions on Knights Landing. See OpenSSL commit
|
||||
// 64d92d74985ebb3d0be58a9718f9e080a14a8e7f.
|
||||
if ((ecx & (1 << 26)) == 0) {
|
||||
extended_features &= ~(1 << 19);
|
||||
if ((ecx & (1u << 26)) == 0) {
|
||||
extended_features &= ~(1u << 19);
|
||||
}
|
||||
|
||||
OPENSSL_ia32cap_P[0] = edx;
|
||||
|
||||
+29
-4
@@ -40,6 +40,18 @@
|
||||
OPENSSL_ARM || OPENSSL_AARCH64) */
|
||||
|
||||
|
||||
// Our assembly does not use the GOT to reference symbols, which means
|
||||
// references to visible symbols will often require a TEXTREL. This is
|
||||
// undesirable, so all assembly-referenced symbols should be hidden. CPU
|
||||
// capabilities are the only such symbols defined in C. Explicitly hide them,
|
||||
// rather than rely on being built with -fvisibility=hidden.
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
#define HIDDEN
|
||||
#else
|
||||
#define HIDDEN __attribute__((visibility("hidden")))
|
||||
#endif
|
||||
|
||||
|
||||
// The capability variables are defined in this file in order to work around a
|
||||
// linker bug. When linking with a .a, if no symbols in a .o are referenced
|
||||
// then the .o is discarded, even if it has constructor functions.
|
||||
@@ -57,11 +69,11 @@
|
||||
// archive, linking on OS X will fail to resolve common symbols. By
|
||||
// initialising it to zero, it becomes a "data symbol", which isn't so
|
||||
// affected.
|
||||
uint32_t OPENSSL_ia32cap_P[4] = {0};
|
||||
HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0};
|
||||
|
||||
#elif defined(OPENSSL_PPC64LE)
|
||||
|
||||
unsigned long OPENSSL_ppc64le_hwcap2 = 0;
|
||||
HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0;
|
||||
|
||||
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
|
||||
@@ -69,7 +81,7 @@ unsigned long OPENSSL_ppc64le_hwcap2 = 0;
|
||||
|
||||
#if defined(OPENSSL_STATIC_ARMCAP)
|
||||
|
||||
uint32_t OPENSSL_armcap_P =
|
||||
HIDDEN uint32_t OPENSSL_armcap_P =
|
||||
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
|
||||
ARMV7_NEON |
|
||||
#endif
|
||||
@@ -88,7 +100,7 @@ uint32_t OPENSSL_armcap_P =
|
||||
0;
|
||||
|
||||
#else
|
||||
uint32_t OPENSSL_armcap_P = 0;
|
||||
HIDDEN uint32_t OPENSSL_armcap_P = 0;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -156,10 +168,18 @@ const char *SSLeay_version(int unused) {
|
||||
return "BoringSSL";
|
||||
}
|
||||
|
||||
const char *OpenSSL_version(int unused) {
|
||||
return "BoringSSL";
|
||||
}
|
||||
|
||||
unsigned long SSLeay(void) {
|
||||
return OPENSSL_VERSION_NUMBER;
|
||||
}
|
||||
|
||||
unsigned long OpenSSL_version_num(void) {
|
||||
return OPENSSL_VERSION_NUMBER;
|
||||
}
|
||||
|
||||
int CRYPTO_malloc_init(void) {
|
||||
return 1;
|
||||
}
|
||||
@@ -171,3 +191,8 @@ int ENGINE_register_all_complete(void) {
|
||||
}
|
||||
|
||||
void OPENSSL_load_builtin_modules(void) {}
|
||||
|
||||
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) {
|
||||
CRYPTO_library_init();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -8,22 +8,12 @@ if (${ARCH} STREQUAL "arm")
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
set(
|
||||
CURVE25519_ARCH_SOURCES
|
||||
|
||||
asm/x25519-asm-x86_64.S
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
curve25519
|
||||
|
||||
OBJECT
|
||||
|
||||
curve25519.c
|
||||
spake25519.c
|
||||
x25519-x86_64.c
|
||||
|
||||
${CURVE25519_ARCH_SOURCES}
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,28 @@ TEST(Ed25519Test, TestVectors) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST(Ed25519Test, Malleability) {
|
||||
// https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
|
||||
// that s be in [0, order). This prevents someone from adding a multiple of
|
||||
// order to s and obtaining a second valid signature for the same message.
|
||||
static const uint8_t kMsg[] = {0x54, 0x65, 0x73, 0x74};
|
||||
static const uint8_t kSig[] = {
|
||||
0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a,
|
||||
0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b,
|
||||
0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67,
|
||||
0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d,
|
||||
0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33,
|
||||
0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d,
|
||||
};
|
||||
static const uint8_t kPub[] = {
|
||||
0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5,
|
||||
0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34,
|
||||
0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
|
||||
};
|
||||
|
||||
EXPECT_FALSE(ED25519_verify(kMsg, sizeof(kMsg), kSig, kPub));
|
||||
}
|
||||
|
||||
TEST(Ed25519Test, KeypairFromSeed) {
|
||||
uint8_t public_key1[32], private_key1[64];
|
||||
ED25519_keypair(public_key1, private_key1);
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/* Copyright (c) 2015, 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
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_SMALL) && \
|
||||
!defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_ASM)
|
||||
#define BORINGSSL_X25519_X86_64
|
||||
|
||||
void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
|
||||
const uint8_t point[32]);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE)
|
||||
#define BORINGSSL_X25519_NEON
|
||||
|
||||
// x25519_NEON is defined in asm/x25519-arm.S.
|
||||
void x25519_NEON(uint8_t out[32], const uint8_t scalar[32],
|
||||
const uint8_t point[32]);
|
||||
#endif
|
||||
|
||||
// fe means field element. Here the field is \Z/(2^255-19). An element t,
|
||||
// entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
||||
// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
||||
// context.
|
||||
typedef int32_t fe[10];
|
||||
|
||||
/* ge means group element.
|
||||
|
||||
* Here the group is the set of pairs (x,y) of field elements (see fe.h)
|
||||
* satisfying -x^2 + y^2 = 1 + d x^2y^2
|
||||
* where d = -121665/121666.
|
||||
*
|
||||
* Representations:
|
||||
* ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
|
||||
* ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
|
||||
* ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
|
||||
* ge_precomp (Duif): (y+x,y-x,2dxy) */
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
} ge_p2;
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
} ge_p3;
|
||||
|
||||
typedef struct {
|
||||
fe X;
|
||||
fe Y;
|
||||
fe Z;
|
||||
fe T;
|
||||
} ge_p1p1;
|
||||
|
||||
typedef struct {
|
||||
fe yplusx;
|
||||
fe yminusx;
|
||||
fe xy2d;
|
||||
} ge_precomp;
|
||||
|
||||
typedef struct {
|
||||
fe YplusX;
|
||||
fe YminusX;
|
||||
fe Z;
|
||||
fe T2d;
|
||||
} ge_cached;
|
||||
|
||||
void x25519_ge_tobytes(uint8_t *s, const ge_p2 *h);
|
||||
int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s);
|
||||
void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
|
||||
void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
|
||||
void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
|
||||
void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
|
||||
void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
|
||||
void x25519_ge_scalarmult_small_precomp(
|
||||
ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]);
|
||||
void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]);
|
||||
void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A);
|
||||
void x25519_sc_reduce(uint8_t *s);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CURVE25519_INTERNAL_H
|
||||
+106
-34
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
@@ -21,8 +22,8 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
#include "../../third_party/fiat/internal.h"
|
||||
|
||||
|
||||
// The following precomputation tables are for the following
|
||||
@@ -43,14 +44,14 @@
|
||||
// see curve25519.c in this directory.
|
||||
//
|
||||
// Exact copies of the source code are kept in bug 27296743.
|
||||
//
|
||||
// import hashlib
|
||||
// import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py
|
||||
//
|
||||
// SEED_N = 'edwards25519 point generation seed (N)'
|
||||
// SEED_M = 'edwards25519 point generation seed (M)'
|
||||
|
||||
/*
|
||||
import hashlib
|
||||
import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py
|
||||
|
||||
SEED_N = 'edwards25519 point generation seed (N)'
|
||||
SEED_M = 'edwards25519 point generation seed (M)'
|
||||
|
||||
def genpoint(seed):
|
||||
v = hashlib.sha256(seed).digest()
|
||||
it = 1
|
||||
@@ -72,10 +73,10 @@ def genpoint(seed):
|
||||
def gentable(P):
|
||||
t = []
|
||||
for i in range(1,16):
|
||||
k = (i >> 3 & 1) * (1 << 192) + \
|
||||
(i >> 2 & 1) * (1 << 128) + \
|
||||
(i >> 1 & 1) * (1 << 64) + \
|
||||
(i & 1)
|
||||
k = ((i >> 3 & 1) * (1 << 192) +
|
||||
(i >> 2 & 1) * (1 << 128) +
|
||||
(i >> 1 & 1) * (1 << 64) +
|
||||
(i & 1))
|
||||
t.append(E.scalarmult(P, k))
|
||||
return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t)
|
||||
|
||||
@@ -267,25 +268,6 @@ static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = {
|
||||
0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06,
|
||||
};
|
||||
|
||||
enum spake2_state_t {
|
||||
spake2_state_init = 0,
|
||||
spake2_state_msg_generated,
|
||||
spake2_state_key_generated,
|
||||
};
|
||||
|
||||
struct spake2_ctx_st {
|
||||
uint8_t private_key[32];
|
||||
uint8_t my_msg[32];
|
||||
uint8_t password_scalar[32];
|
||||
uint8_t password_hash[SHA512_DIGEST_LENGTH];
|
||||
uint8_t *my_name;
|
||||
size_t my_name_len;
|
||||
uint8_t *their_name;
|
||||
size_t their_name_len;
|
||||
enum spake2_role_t my_role;
|
||||
enum spake2_state_t state;
|
||||
};
|
||||
|
||||
SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role,
|
||||
const uint8_t *my_name, size_t my_name_len,
|
||||
const uint8_t *their_name, size_t their_name_len) {
|
||||
@@ -332,6 +314,48 @@ static void left_shift_3(uint8_t n[32]) {
|
||||
}
|
||||
}
|
||||
|
||||
typedef union {
|
||||
uint8_t bytes[32];
|
||||
uint32_t words[8];
|
||||
} scalar;
|
||||
|
||||
// kOrder is the order of the prime-order subgroup of curve25519 in
|
||||
// little-endian order.
|
||||
static const scalar kOrder = {{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
|
||||
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}};
|
||||
|
||||
// scalar_cmov copies |src| to |dest| if |mask| is all ones.
|
||||
static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) {
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
dest->words[i] =
|
||||
constant_time_select_w(mask, src->words[i], dest->words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// scalar_double sets |s| to |2×s|.
|
||||
static void scalar_double(scalar *s) {
|
||||
uint32_t carry = 0;
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
const uint32_t carry_out = s->words[i] >> 31;
|
||||
s->words[i] = (s->words[i] << 1) | carry;
|
||||
carry = carry_out;
|
||||
}
|
||||
}
|
||||
|
||||
// scalar_add sets |dest| to |dest| plus |src|.
|
||||
static void scalar_add(scalar *dest, const scalar *src) {
|
||||
uint32_t carry = 0;
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
uint64_t tmp = ((uint64_t)dest->words[i] + src->words[i]) + carry;
|
||||
dest->words[i] = (uint32_t)tmp;
|
||||
carry = (uint32_t)(tmp >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len,
|
||||
size_t max_out_len, const uint8_t *password,
|
||||
size_t password_len) {
|
||||
@@ -359,13 +383,61 @@ int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len,
|
||||
SHA512(password, password_len, password_tmp);
|
||||
OPENSSL_memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash));
|
||||
x25519_sc_reduce(password_tmp);
|
||||
OPENSSL_memcpy(ctx->password_scalar, password_tmp, sizeof(ctx->password_scalar));
|
||||
|
||||
// Due to a copy-paste error, the call to |left_shift_3| was omitted after
|
||||
// the |x25519_sc_reduce|, just above. This meant that |ctx->password_scalar|
|
||||
// was not a multiple of eight to clear the cofactor and thus three bits of
|
||||
// the password hash would leak. In order to fix this in a unilateral way,
|
||||
// points of small order are added to the mask point such that it is in the
|
||||
// prime-order subgroup. Since the ephemeral scalar is a multiple of eight,
|
||||
// these points will cancel out when calculating the shared secret.
|
||||
//
|
||||
// Adding points of small order is the same as adding multiples of the prime
|
||||
// order to the password scalar. Since that's faster, that is what is done
|
||||
// below. The prime order (kOrder) is a large prime, thus odd, thus the LSB
|
||||
// is one. So adding it will flip the LSB. Adding twice it will flip the next
|
||||
// bit and so one for all the bottom three bits.
|
||||
|
||||
scalar password_scalar;
|
||||
OPENSSL_memcpy(&password_scalar, password_tmp, sizeof(password_scalar));
|
||||
|
||||
// |password_scalar| is the result of |x25519_sc_reduce| and thus is, at
|
||||
// most, $l-1$ (where $l$ is |kOrder|, the order of the prime-order subgroup
|
||||
// of Ed25519). In the following, we may add $l + 2×l + 4×l$ for a max value
|
||||
// of $8×l-1$. That is < 2**256, as required.
|
||||
|
||||
if (!ctx->disable_password_scalar_hack) {
|
||||
scalar order = kOrder;
|
||||
scalar tmp;
|
||||
|
||||
OPENSSL_memset(&tmp, 0, sizeof(tmp));
|
||||
scalar_cmov(&tmp, &order,
|
||||
constant_time_eq_w(password_scalar.bytes[0] & 1, 1));
|
||||
scalar_add(&password_scalar, &tmp);
|
||||
|
||||
scalar_double(&order);
|
||||
OPENSSL_memset(&tmp, 0, sizeof(tmp));
|
||||
scalar_cmov(&tmp, &order,
|
||||
constant_time_eq_w(password_scalar.bytes[0] & 2, 2));
|
||||
scalar_add(&password_scalar, &tmp);
|
||||
|
||||
scalar_double(&order);
|
||||
OPENSSL_memset(&tmp, 0, sizeof(tmp));
|
||||
scalar_cmov(&tmp, &order,
|
||||
constant_time_eq_w(password_scalar.bytes[0] & 4, 4));
|
||||
scalar_add(&password_scalar, &tmp);
|
||||
|
||||
assert((password_scalar.bytes[0] & 7) == 0);
|
||||
}
|
||||
|
||||
OPENSSL_memcpy(ctx->password_scalar, password_scalar.bytes,
|
||||
sizeof(ctx->password_scalar));
|
||||
|
||||
ge_p3 mask;
|
||||
x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar,
|
||||
ctx->my_role == spake2_role_alice
|
||||
? kSpakeMSmallPrecomp
|
||||
: kSpakeNSmallPrecomp);
|
||||
ctx->my_role == spake2_role_alice
|
||||
? kSpakeMSmallPrecomp
|
||||
: kSpakeNSmallPrecomp);
|
||||
|
||||
// P* = P + mask.
|
||||
ge_cached mask_cached;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../third_party/fiat/internal.h"
|
||||
|
||||
|
||||
// TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down.
|
||||
@@ -46,6 +47,13 @@ struct SPAKE2Run {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (alice_disable_password_scalar_hack) {
|
||||
alice->disable_password_scalar_hack = 1;
|
||||
}
|
||||
if (bob_disable_password_scalar_hack) {
|
||||
bob->disable_password_scalar_hack = 1;
|
||||
}
|
||||
|
||||
uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE];
|
||||
uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE];
|
||||
size_t alice_msg_len, bob_msg_len;
|
||||
@@ -90,6 +98,8 @@ struct SPAKE2Run {
|
||||
std::string bob_password = "password";
|
||||
std::pair<std::string, std::string> alice_names = {"alice", "bob"};
|
||||
std::pair<std::string, std::string> bob_names = {"bob", "alice"};
|
||||
bool alice_disable_password_scalar_hack = false;
|
||||
bool bob_disable_password_scalar_hack = false;
|
||||
int alice_corrupt_msg_bit = -1;
|
||||
|
||||
private:
|
||||
@@ -104,6 +114,24 @@ TEST(SPAKE25519Test, SPAKE2) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SPAKE25519Test, OldAlice) {
|
||||
for (unsigned i = 0; i < 20; i++) {
|
||||
SPAKE2Run spake2;
|
||||
spake2.alice_disable_password_scalar_hack = true;
|
||||
ASSERT_TRUE(spake2.Run());
|
||||
EXPECT_TRUE(spake2.key_matches());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SPAKE25519Test, OldBob) {
|
||||
for (unsigned i = 0; i < 20; i++) {
|
||||
SPAKE2Run spake2;
|
||||
spake2.bob_disable_password_scalar_hack = true;
|
||||
ASSERT_TRUE(spake2.Run());
|
||||
EXPECT_TRUE(spake2.key_matches());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SPAKE25519Test, WrongPassword) {
|
||||
SPAKE2Run spake2;
|
||||
spake2.bob_password = "wrong password";
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
/* Copyright (c) 2015, 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 code is mostly 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 this file has the ISC license just to keep licencing
|
||||
// simple.
|
||||
//
|
||||
// The field functions are shared by Ed25519 and X25519 where possible.
|
||||
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#if defined(BORINGSSL_X25519_X86_64)
|
||||
|
||||
typedef struct { uint64_t v[5]; } fe25519;
|
||||
|
||||
// These functions are defined in asm/x25519-x86_64.S
|
||||
void x25519_x86_64_work_cswap(fe25519 *, uint64_t);
|
||||
void x25519_x86_64_mul(fe25519 *out, const fe25519 *a, const fe25519 *b);
|
||||
void x25519_x86_64_square(fe25519 *out, const fe25519 *a);
|
||||
void x25519_x86_64_freeze(fe25519 *);
|
||||
void x25519_x86_64_ladderstep(fe25519 *work);
|
||||
|
||||
static void fe25519_setint(fe25519 *r, unsigned v) {
|
||||
r->v[0] = v;
|
||||
r->v[1] = 0;
|
||||
r->v[2] = 0;
|
||||
r->v[3] = 0;
|
||||
r->v[4] = 0;
|
||||
}
|
||||
|
||||
// Assumes input x being reduced below 2^255
|
||||
static void fe25519_pack(unsigned char r[32], const fe25519 *x) {
|
||||
fe25519 t;
|
||||
t = *x;
|
||||
x25519_x86_64_freeze(&t);
|
||||
|
||||
r[0] = (uint8_t)(t.v[0] & 0xff);
|
||||
r[1] = (uint8_t)((t.v[0] >> 8) & 0xff);
|
||||
r[2] = (uint8_t)((t.v[0] >> 16) & 0xff);
|
||||
r[3] = (uint8_t)((t.v[0] >> 24) & 0xff);
|
||||
r[4] = (uint8_t)((t.v[0] >> 32) & 0xff);
|
||||
r[5] = (uint8_t)((t.v[0] >> 40) & 0xff);
|
||||
r[6] = (uint8_t)((t.v[0] >> 48));
|
||||
|
||||
r[6] ^= (uint8_t)((t.v[1] << 3) & 0xf8);
|
||||
r[7] = (uint8_t)((t.v[1] >> 5) & 0xff);
|
||||
r[8] = (uint8_t)((t.v[1] >> 13) & 0xff);
|
||||
r[9] = (uint8_t)((t.v[1] >> 21) & 0xff);
|
||||
r[10] = (uint8_t)((t.v[1] >> 29) & 0xff);
|
||||
r[11] = (uint8_t)((t.v[1] >> 37) & 0xff);
|
||||
r[12] = (uint8_t)((t.v[1] >> 45));
|
||||
|
||||
r[12] ^= (uint8_t)((t.v[2] << 6) & 0xc0);
|
||||
r[13] = (uint8_t)((t.v[2] >> 2) & 0xff);
|
||||
r[14] = (uint8_t)((t.v[2] >> 10) & 0xff);
|
||||
r[15] = (uint8_t)((t.v[2] >> 18) & 0xff);
|
||||
r[16] = (uint8_t)((t.v[2] >> 26) & 0xff);
|
||||
r[17] = (uint8_t)((t.v[2] >> 34) & 0xff);
|
||||
r[18] = (uint8_t)((t.v[2] >> 42) & 0xff);
|
||||
r[19] = (uint8_t)((t.v[2] >> 50));
|
||||
|
||||
r[19] ^= (uint8_t)((t.v[3] << 1) & 0xfe);
|
||||
r[20] = (uint8_t)((t.v[3] >> 7) & 0xff);
|
||||
r[21] = (uint8_t)((t.v[3] >> 15) & 0xff);
|
||||
r[22] = (uint8_t)((t.v[3] >> 23) & 0xff);
|
||||
r[23] = (uint8_t)((t.v[3] >> 31) & 0xff);
|
||||
r[24] = (uint8_t)((t.v[3] >> 39) & 0xff);
|
||||
r[25] = (uint8_t)((t.v[3] >> 47));
|
||||
|
||||
r[25] ^= (uint8_t)((t.v[4] << 4) & 0xf0);
|
||||
r[26] = (uint8_t)((t.v[4] >> 4) & 0xff);
|
||||
r[27] = (uint8_t)((t.v[4] >> 12) & 0xff);
|
||||
r[28] = (uint8_t)((t.v[4] >> 20) & 0xff);
|
||||
r[29] = (uint8_t)((t.v[4] >> 28) & 0xff);
|
||||
r[30] = (uint8_t)((t.v[4] >> 36) & 0xff);
|
||||
r[31] = (uint8_t)((t.v[4] >> 44));
|
||||
}
|
||||
|
||||
static void fe25519_unpack(fe25519 *r, const uint8_t x[32]) {
|
||||
r->v[0] = x[0];
|
||||
r->v[0] += (uint64_t)x[1] << 8;
|
||||
r->v[0] += (uint64_t)x[2] << 16;
|
||||
r->v[0] += (uint64_t)x[3] << 24;
|
||||
r->v[0] += (uint64_t)x[4] << 32;
|
||||
r->v[0] += (uint64_t)x[5] << 40;
|
||||
r->v[0] += ((uint64_t)x[6] & 7) << 48;
|
||||
|
||||
r->v[1] = x[6] >> 3;
|
||||
r->v[1] += (uint64_t)x[7] << 5;
|
||||
r->v[1] += (uint64_t)x[8] << 13;
|
||||
r->v[1] += (uint64_t)x[9] << 21;
|
||||
r->v[1] += (uint64_t)x[10] << 29;
|
||||
r->v[1] += (uint64_t)x[11] << 37;
|
||||
r->v[1] += ((uint64_t)x[12] & 63) << 45;
|
||||
|
||||
r->v[2] = x[12] >> 6;
|
||||
r->v[2] += (uint64_t)x[13] << 2;
|
||||
r->v[2] += (uint64_t)x[14] << 10;
|
||||
r->v[2] += (uint64_t)x[15] << 18;
|
||||
r->v[2] += (uint64_t)x[16] << 26;
|
||||
r->v[2] += (uint64_t)x[17] << 34;
|
||||
r->v[2] += (uint64_t)x[18] << 42;
|
||||
r->v[2] += ((uint64_t)x[19] & 1) << 50;
|
||||
|
||||
r->v[3] = x[19] >> 1;
|
||||
r->v[3] += (uint64_t)x[20] << 7;
|
||||
r->v[3] += (uint64_t)x[21] << 15;
|
||||
r->v[3] += (uint64_t)x[22] << 23;
|
||||
r->v[3] += (uint64_t)x[23] << 31;
|
||||
r->v[3] += (uint64_t)x[24] << 39;
|
||||
r->v[3] += ((uint64_t)x[25] & 15) << 47;
|
||||
|
||||
r->v[4] = x[25] >> 4;
|
||||
r->v[4] += (uint64_t)x[26] << 4;
|
||||
r->v[4] += (uint64_t)x[27] << 12;
|
||||
r->v[4] += (uint64_t)x[28] << 20;
|
||||
r->v[4] += (uint64_t)x[29] << 28;
|
||||
r->v[4] += (uint64_t)x[30] << 36;
|
||||
r->v[4] += ((uint64_t)x[31] & 127) << 44;
|
||||
}
|
||||
|
||||
static void fe25519_invert(fe25519 *r, const fe25519 *x) {
|
||||
fe25519 z2;
|
||||
fe25519 z9;
|
||||
fe25519 z11;
|
||||
fe25519 z2_5_0;
|
||||
fe25519 z2_10_0;
|
||||
fe25519 z2_20_0;
|
||||
fe25519 z2_50_0;
|
||||
fe25519 z2_100_0;
|
||||
fe25519 t;
|
||||
int i;
|
||||
|
||||
/* 2 */ x25519_x86_64_square(&z2, x);
|
||||
/* 4 */ x25519_x86_64_square(&t, &z2);
|
||||
/* 8 */ x25519_x86_64_square(&t, &t);
|
||||
/* 9 */ x25519_x86_64_mul(&z9, &t, x);
|
||||
/* 11 */ x25519_x86_64_mul(&z11, &z9, &z2);
|
||||
/* 22 */ x25519_x86_64_square(&t, &z11);
|
||||
/* 2^5 - 2^0 = 31 */ x25519_x86_64_mul(&z2_5_0, &t, &z9);
|
||||
|
||||
/* 2^6 - 2^1 */ x25519_x86_64_square(&t, &z2_5_0);
|
||||
/* 2^20 - 2^10 */ for (i = 1; i < 5; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^10 - 2^0 */ x25519_x86_64_mul(&z2_10_0, &t, &z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ x25519_x86_64_square(&t, &z2_10_0);
|
||||
/* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^20 - 2^0 */ x25519_x86_64_mul(&z2_20_0, &t, &z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ x25519_x86_64_square(&t, &z2_20_0);
|
||||
/* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^40 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ x25519_x86_64_square(&t, &t);
|
||||
/* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^50 - 2^0 */ x25519_x86_64_mul(&z2_50_0, &t, &z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ x25519_x86_64_square(&t, &z2_50_0);
|
||||
/* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^100 - 2^0 */ x25519_x86_64_mul(&z2_100_0, &t, &z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ x25519_x86_64_square(&t, &z2_100_0);
|
||||
/* 2^200 - 2^100 */ for (i = 1; i < 100; i++) {
|
||||
x25519_x86_64_square(&t, &t);
|
||||
}
|
||||
/* 2^200 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ x25519_x86_64_square(&t, &t);
|
||||
/* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { x25519_x86_64_square(&t, &t); }
|
||||
/* 2^250 - 2^0 */ x25519_x86_64_mul(&t, &t, &z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ x25519_x86_64_square(&t, &t);
|
||||
/* 2^252 - 2^2 */ x25519_x86_64_square(&t, &t);
|
||||
/* 2^253 - 2^3 */ x25519_x86_64_square(&t, &t);
|
||||
|
||||
/* 2^254 - 2^4 */ x25519_x86_64_square(&t, &t);
|
||||
|
||||
/* 2^255 - 2^5 */ x25519_x86_64_square(&t, &t);
|
||||
/* 2^255 - 21 */ x25519_x86_64_mul(r, &t, &z11);
|
||||
}
|
||||
|
||||
static void mladder(fe25519 *xr, fe25519 *zr, const uint8_t s[32]) {
|
||||
fe25519 work[5];
|
||||
|
||||
work[0] = *xr;
|
||||
fe25519_setint(work + 1, 1);
|
||||
fe25519_setint(work + 2, 0);
|
||||
work[3] = *xr;
|
||||
fe25519_setint(work + 4, 1);
|
||||
|
||||
int i, j;
|
||||
uint8_t prevbit = 0;
|
||||
|
||||
j = 6;
|
||||
for (i = 31; i >= 0; i--) {
|
||||
while (j >= 0) {
|
||||
const uint8_t bit = 1 & (s[i] >> j);
|
||||
const uint64_t swap = bit ^ prevbit;
|
||||
prevbit = bit;
|
||||
x25519_x86_64_work_cswap(work + 1, swap);
|
||||
x25519_x86_64_ladderstep(work);
|
||||
j -= 1;
|
||||
}
|
||||
j = 7;
|
||||
}
|
||||
|
||||
*xr = work[1];
|
||||
*zr = work[2];
|
||||
}
|
||||
|
||||
void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
|
||||
const uint8_t point[32]) {
|
||||
uint8_t e[32];
|
||||
OPENSSL_memcpy(e, scalar, sizeof(e));
|
||||
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
e[31] |= 64;
|
||||
|
||||
fe25519 t;
|
||||
fe25519 z;
|
||||
fe25519_unpack(&t, point);
|
||||
mladder(&t, &z, e);
|
||||
fe25519_invert(&z, &z);
|
||||
x25519_x86_64_mul(&t, &t, &z);
|
||||
fe25519_pack(out, &t);
|
||||
}
|
||||
|
||||
#endif // BORINGSSL_X25519_X86_64
|
||||
@@ -105,3 +105,22 @@ TEST(X25519Test, Iterated) {
|
||||
|
||||
EXPECT_EQ(Bytes(kExpected), Bytes(scalar));
|
||||
}
|
||||
|
||||
TEST(X25519Test, DISABLED_IteratedLarge) {
|
||||
// Taken from https://tools.ietf.org/html/rfc7748#section-5.2.
|
||||
uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
|
||||
|
||||
for (unsigned i = 0; i < 1000000; i++) {
|
||||
EXPECT_TRUE(X25519(out, scalar, point));
|
||||
OPENSSL_memcpy(point, scalar, sizeof(point));
|
||||
OPENSSL_memcpy(scalar, out, sizeof(scalar));
|
||||
}
|
||||
|
||||
static const uint8_t kExpected[32] = {
|
||||
0x7c, 0x39, 0x11, 0xe0, 0xab, 0x25, 0x86, 0xfd, 0x86, 0x44, 0x97,
|
||||
0x29, 0x7e, 0x57, 0x5e, 0x6f, 0x3b, 0xc6, 0x01, 0xc0, 0x88, 0x3c,
|
||||
0x30, 0xdf, 0x5f, 0x4d, 0xd2, 0xd2, 0x4f, 0x66, 0x54, 0x24,
|
||||
};
|
||||
|
||||
EXPECT_EQ(Bytes(kExpected), Bytes(scalar));
|
||||
}
|
||||
|
||||
@@ -124,6 +124,20 @@ void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key,
|
||||
}
|
||||
}
|
||||
|
||||
int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) {
|
||||
if (pub_key != NULL) {
|
||||
BN_free(dh->pub_key);
|
||||
dh->pub_key = pub_key;
|
||||
}
|
||||
|
||||
if (priv_key != NULL) {
|
||||
BN_free(dh->priv_key);
|
||||
dh->priv_key = priv_key;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q,
|
||||
const BIGNUM **out_g) {
|
||||
if (out_p != NULL) {
|
||||
@@ -137,6 +151,30 @@ void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q,
|
||||
}
|
||||
}
|
||||
|
||||
int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
|
||||
if ((dh->p == NULL && p == NULL) ||
|
||||
(dh->g == NULL && g == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
BN_free(dh->p);
|
||||
dh->p = p;
|
||||
}
|
||||
|
||||
if (q != NULL) {
|
||||
BN_free(dh->q);
|
||||
dh->q = q;
|
||||
}
|
||||
|
||||
if (g != NULL) {
|
||||
BN_free(dh->g);
|
||||
dh->g = g;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/nid.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
@@ -120,22 +119,22 @@ const EVP_MD* EVP_get_digestbynid(int nid) {
|
||||
static const struct {
|
||||
uint8_t oid[9];
|
||||
uint8_t oid_len;
|
||||
const EVP_MD *(*md_func) (void);
|
||||
int nid;
|
||||
} kMDOIDs[] = {
|
||||
// 1.2.840.113549.2.4
|
||||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, EVP_md4 },
|
||||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 },
|
||||
// 1.2.840.113549.2.5
|
||||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, EVP_md5 },
|
||||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 },
|
||||
// 1.3.14.3.2.26
|
||||
{ {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, EVP_sha1 },
|
||||
{ {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 },
|
||||
// 2.16.840.1.101.3.4.2.1
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, EVP_sha256 },
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 },
|
||||
// 2.16.840.1.101.3.4.2.2
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, EVP_sha384 },
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 },
|
||||
// 2.16.840.1.101.3.4.2.3
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, EVP_sha512 },
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 },
|
||||
// 2.16.840.1.101.3.4.2.4
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, EVP_sha224 },
|
||||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 },
|
||||
};
|
||||
|
||||
static const EVP_MD *cbs_to_md(const CBS *cbs) {
|
||||
@@ -143,7 +142,7 @@ static const EVP_MD *cbs_to_md(const CBS *cbs) {
|
||||
if (CBS_len(cbs) == kMDOIDs[i].oid_len &&
|
||||
OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) ==
|
||||
0) {
|
||||
return kMDOIDs[i].md_func();
|
||||
return EVP_get_digestbynid(kMDOIDs[i].nid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +191,41 @@ const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) {
|
||||
CBB algorithm, oid, null;
|
||||
if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) ||
|
||||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) {
|
||||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
int nid = EVP_MD_type(md);
|
||||
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) {
|
||||
if (nid == kMDOIDs[i].nid) {
|
||||
if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) {
|
||||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
|
||||
!CBB_flush(cbb)) {
|
||||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_MD *EVP_get_digestbyname(const char *name) {
|
||||
for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) {
|
||||
const char *short_name = nid_to_digest_mapping[i].short_name;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../test/test_util.h"
|
||||
|
||||
|
||||
struct MD {
|
||||
@@ -215,3 +217,44 @@ TEST(DigestTest, Getters) {
|
||||
EXPECT_EQ(EVP_md5_sha1(), EVP_get_digestbyobj(OBJ_nid2obj(NID_md5_sha1)));
|
||||
EXPECT_EQ(EVP_sha1(), EVP_get_digestbyobj(OBJ_nid2obj(NID_sha1)));
|
||||
}
|
||||
|
||||
TEST(DigestTest, ASN1) {
|
||||
bssl::ScopedCBB cbb;
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
EXPECT_FALSE(EVP_marshal_digest_algorithm(cbb.get(), EVP_md5_sha1()));
|
||||
|
||||
static const uint8_t kSHA256[] = {0x30, 0x0d, 0x06, 0x09, 0x60,
|
||||
0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x01, 0x05, 0x00};
|
||||
static const uint8_t kSHA256NoParam[] = {0x30, 0x0b, 0x06, 0x09, 0x60,
|
||||
0x86, 0x48, 0x01, 0x65, 0x03,
|
||||
0x04, 0x02, 0x01};
|
||||
static const uint8_t kSHA256GarbageParam[] = {
|
||||
0x30, 0x0e, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
|
||||
0x65, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x2a};
|
||||
|
||||
// Serialize SHA-256.
|
||||
cbb.Reset();
|
||||
ASSERT_TRUE(CBB_init(cbb.get(), 0));
|
||||
ASSERT_TRUE(EVP_marshal_digest_algorithm(cbb.get(), EVP_sha256()));
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len));
|
||||
bssl::UniquePtr<uint8_t> free_der(der);
|
||||
EXPECT_EQ(Bytes(kSHA256), Bytes(der, der_len));
|
||||
|
||||
// Parse SHA-256.
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, kSHA256, sizeof(kSHA256));
|
||||
EXPECT_EQ(EVP_sha256(), EVP_parse_digest_algorithm(&cbs));
|
||||
EXPECT_EQ(0u, CBS_len(&cbs));
|
||||
|
||||
// Missing parameters are tolerated for compatibility.
|
||||
CBS_init(&cbs, kSHA256NoParam, sizeof(kSHA256NoParam));
|
||||
EXPECT_EQ(EVP_sha256(), EVP_parse_digest_algorithm(&cbs));
|
||||
EXPECT_EQ(0u, CBS_len(&cbs));
|
||||
|
||||
// Garbage parameters are not.
|
||||
CBS_init(&cbs, kSHA256GarbageParam, sizeof(kSHA256GarbageParam));
|
||||
EXPECT_FALSE(EVP_parse_digest_algorithm(&cbs));
|
||||
}
|
||||
|
||||
+65
-75
@@ -82,6 +82,9 @@
|
||||
// Rabin-Miller
|
||||
#define DSS_prime_checks 50
|
||||
|
||||
static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
BIGNUM **out_r);
|
||||
|
||||
static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
|
||||
|
||||
DSA *DSA_new(void) {
|
||||
@@ -117,8 +120,6 @@ void DSA_free(DSA *dsa) {
|
||||
BN_clear_free(dsa->g);
|
||||
BN_clear_free(dsa->pub_key);
|
||||
BN_clear_free(dsa->priv_key);
|
||||
BN_clear_free(dsa->kinv);
|
||||
BN_clear_free(dsa->r);
|
||||
BN_MONT_CTX_free(dsa->method_mont_p);
|
||||
BN_MONT_CTX_free(dsa->method_mont_q);
|
||||
CRYPTO_MUTEX_cleanup(&dsa->method_mont_lock);
|
||||
@@ -153,6 +154,46 @@ void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, const BIGNUM **out_q,
|
||||
}
|
||||
}
|
||||
|
||||
int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) {
|
||||
if (dsa->pub_key == NULL && pub_key == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pub_key != NULL) {
|
||||
BN_free(dsa->pub_key);
|
||||
dsa->pub_key = pub_key;
|
||||
}
|
||||
if (priv_key != NULL) {
|
||||
BN_free(dsa->priv_key);
|
||||
dsa->priv_key = priv_key;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
|
||||
if ((dsa->p == NULL && p == NULL) ||
|
||||
(dsa->q == NULL && q == NULL) ||
|
||||
(dsa->g == NULL && g == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
BN_free(dsa->p);
|
||||
dsa->p = p;
|
||||
}
|
||||
if (q != NULL) {
|
||||
BN_free(dsa->q);
|
||||
dsa->q = q;
|
||||
}
|
||||
if (g != NULL) {
|
||||
BN_free(dsa->g);
|
||||
dsa->g = g;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
|
||||
size_t seed_len, int *out_counter,
|
||||
unsigned long *out_h, BN_GENCB *cb) {
|
||||
@@ -198,11 +239,6 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
r0 = BN_CTX_get(ctx);
|
||||
g = BN_CTX_get(ctx);
|
||||
W = BN_CTX_get(ctx);
|
||||
@@ -360,8 +396,9 @@ end:
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_set_word(test, h) ||
|
||||
!BN_MONT_CTX_set(mont, p, ctx)) {
|
||||
mont = BN_MONT_CTX_new_for_modulus(p, ctx);
|
||||
if (mont == NULL ||
|
||||
!BN_set_word(test, h)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -504,14 +541,13 @@ void DSA_SIG_free(DSA_SIG *sig) {
|
||||
OPENSSL_free(sig);
|
||||
}
|
||||
|
||||
DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
|
||||
DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) {
|
||||
BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
|
||||
BIGNUM m;
|
||||
BIGNUM xr;
|
||||
BN_CTX *ctx = NULL;
|
||||
int reason = ERR_R_BN_LIB;
|
||||
DSA_SIG *ret = NULL;
|
||||
int noredo = 0;
|
||||
|
||||
BN_init(&m);
|
||||
BN_init(&xr);
|
||||
@@ -531,16 +567,8 @@ DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
|
||||
}
|
||||
|
||||
redo:
|
||||
if (dsa->kinv == NULL || dsa->r == NULL) {
|
||||
if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
kinv = dsa->kinv;
|
||||
dsa->kinv = NULL;
|
||||
r = dsa->r;
|
||||
dsa->r = NULL;
|
||||
noredo = 1;
|
||||
if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (digest_len > BN_num_bytes(dsa->q)) {
|
||||
@@ -573,10 +601,6 @@ redo:
|
||||
// Redo if r or s is zero as required by FIPS 186-3: this is
|
||||
// very unlikely.
|
||||
if (BN_is_zero(r) || BN_is_zero(s)) {
|
||||
if (noredo) {
|
||||
reason = DSA_R_NEED_NEW_SETUP_VALUES;
|
||||
goto err;
|
||||
}
|
||||
goto redo;
|
||||
}
|
||||
ret = DSA_SIG_new();
|
||||
@@ -718,7 +742,7 @@ err:
|
||||
}
|
||||
|
||||
int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
|
||||
uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa) {
|
||||
uint8_t *out_sig, unsigned int *out_siglen, const DSA *dsa) {
|
||||
DSA_SIG *s;
|
||||
|
||||
s = DSA_do_sign(digest, digest_len, dsa);
|
||||
@@ -808,10 +832,10 @@ int DSA_size(const DSA *dsa) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
BIGNUM **out_r) {
|
||||
static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
BIGNUM **out_r) {
|
||||
BN_CTX *ctx;
|
||||
BIGNUM k, kq, *kinv = NULL, *r = NULL;
|
||||
BIGNUM k, *kinv = NULL, *r = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!dsa->p || !dsa->q || !dsa->g) {
|
||||
@@ -820,7 +844,6 @@ int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
}
|
||||
|
||||
BN_init(&k);
|
||||
BN_init(&kq);
|
||||
|
||||
ctx = ctx_in;
|
||||
if (ctx == NULL) {
|
||||
@@ -831,54 +854,22 @@ int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
|
||||
}
|
||||
|
||||
r = BN_new();
|
||||
if (r == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Get random k
|
||||
if (!BN_rand_range_ex(&k, 1, dsa->q)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
|
||||
kinv = BN_new();
|
||||
if (r == NULL || kinv == NULL ||
|
||||
// Get random k
|
||||
!BN_rand_range_ex(&k, 1, dsa->q) ||
|
||||
!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
|
||||
(CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p,
|
||||
ctx) ||
|
||||
!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q,
|
||||
(CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q,
|
||||
ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Compute r = (g^k mod p) mod q
|
||||
if (!BN_copy(&kq, &k)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// We do not want timing information to leak the length of k,
|
||||
// so we compute g^k using an equivalent exponent of fixed length.
|
||||
//
|
||||
// (This is a kludge that we need because the BN_mod_exp_mont()
|
||||
// does not let us specify the desired timing behaviour.)
|
||||
|
||||
if (!BN_add(&kq, &kq, dsa->q)) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_exp_mont_consttime(r, dsa->g, &kq, dsa->p, ctx,
|
||||
dsa->method_mont_p)) {
|
||||
goto err;
|
||||
}
|
||||
if (!BN_mod(r, r, dsa->q, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little
|
||||
// Theorem.
|
||||
kinv = BN_new();
|
||||
if (kinv == NULL ||
|
||||
ctx) ||
|
||||
// Compute r = (g^k mod p) mod q
|
||||
!BN_mod_exp_mont_consttime(r, dsa->g, &k, dsa->p, ctx,
|
||||
dsa->method_mont_p) ||
|
||||
!BN_mod(r, r, dsa->q, ctx) ||
|
||||
// Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little
|
||||
// Theorem.
|
||||
!bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -902,7 +893,6 @@ err:
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
BN_clear_free(&k);
|
||||
BN_clear_free(&kq);
|
||||
BN_clear_free(kinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -67,9 +67,9 @@
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
static const uint8_t kParametersTag =
|
||||
static const unsigned kParametersTag =
|
||||
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
|
||||
static const uint8_t kPublicKeyTag =
|
||||
static const unsigned kPublicKeyTag =
|
||||
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
|
||||
|
||||
EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ec_key.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/nid.h>
|
||||
|
||||
#include "../test/file_test.h"
|
||||
@@ -112,3 +114,98 @@ TEST(ECDHTest, TestVectors) {
|
||||
Bytes(actual_z.data(), static_cast<size_t>(ret)));
|
||||
});
|
||||
}
|
||||
|
||||
// MakeCustomGroup returns an |EC_GROUP| containing a non-standard group. (P-256
|
||||
// with the wrong generator.)
|
||||
static bssl::UniquePtr<EC_GROUP> MakeCustomGroup() {
|
||||
static const uint8_t kP[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
static const uint8_t kA[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
||||
};
|
||||
static const uint8_t kB[] = {
|
||||
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
|
||||
0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
|
||||
0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
|
||||
};
|
||||
static const uint8_t kX[] = {
|
||||
0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e,
|
||||
0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d,
|
||||
0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a,
|
||||
};
|
||||
static const uint8_t kY[] = {
|
||||
0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3,
|
||||
0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5,
|
||||
0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
|
||||
};
|
||||
static const uint8_t kOrder[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
|
||||
0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
|
||||
};
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
|
||||
bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
|
||||
bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
|
||||
bssl::UniquePtr<BIGNUM> x(BN_bin2bn(kX, sizeof(kX), nullptr));
|
||||
bssl::UniquePtr<BIGNUM> y(BN_bin2bn(kY, sizeof(kY), nullptr));
|
||||
bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
|
||||
if (!ctx || !p || !a || !b || !x || !y || !order) {
|
||||
return nullptr;
|
||||
}
|
||||
bssl::UniquePtr<EC_GROUP> group(
|
||||
EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
|
||||
if (!group) {
|
||||
return nullptr;
|
||||
}
|
||||
bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
|
||||
if (!generator ||
|
||||
!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
|
||||
x.get(), y.get(), ctx.get()) ||
|
||||
!EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
|
||||
BN_value_one())) {
|
||||
return nullptr;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
TEST(ECDHTest, GroupMismatch) {
|
||||
const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
|
||||
std::vector<EC_builtin_curve> curves(num_curves);
|
||||
EC_get_builtin_curves(curves.data(), num_curves);
|
||||
|
||||
// Instantiate all the built-in curves.
|
||||
std::vector<bssl::UniquePtr<EC_GROUP>> groups;
|
||||
for (const auto &curve : curves) {
|
||||
groups.emplace_back(EC_GROUP_new_by_curve_name(curve.nid));
|
||||
ASSERT_TRUE(groups.back());
|
||||
}
|
||||
|
||||
// Also create some arbitrary group. (This is P-256 with the wrong generator.)
|
||||
groups.push_back(MakeCustomGroup());
|
||||
ASSERT_TRUE(groups.back());
|
||||
|
||||
for (const auto &a : groups) {
|
||||
for (const auto &b : groups) {
|
||||
if (a.get() == b.get()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
|
||||
ASSERT_TRUE(EC_KEY_set_group(key.get(), a.get()));
|
||||
ASSERT_TRUE(EC_KEY_generate_key(key.get()));
|
||||
|
||||
// ECDH across the groups should not work.
|
||||
char out[64];
|
||||
const EC_POINT *peer = EC_GROUP_get0_generator(b.get());
|
||||
EXPECT_EQ(-1,
|
||||
ECDH_compute_key(out, sizeof(out), peer, key.get(), nullptr));
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,6 @@ int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig,
|
||||
(EC_KEY*) eckey /* cast away const */);
|
||||
}
|
||||
|
||||
return ECDSA_sign_ex(type, digest, digest_len, sig, sig_len, NULL, NULL,
|
||||
eckey);
|
||||
}
|
||||
|
||||
int ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
|
||||
uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv,
|
||||
const BIGNUM *r, const EC_KEY *eckey) {
|
||||
int ret = 0;
|
||||
ECDSA_SIG *s = NULL;
|
||||
|
||||
@@ -89,7 +82,7 @@ int ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
|
||||
goto err;
|
||||
}
|
||||
|
||||
s = ECDSA_do_sign_ex(digest, digest_len, kinv, r, eckey);
|
||||
s = ECDSA_do_sign(digest, digest_len, eckey);
|
||||
if (s == NULL) {
|
||||
*sig_len = 0;
|
||||
goto err;
|
||||
|
||||
@@ -17,6 +17,7 @@ EC,110,INVALID_FIELD
|
||||
EC,111,INVALID_FORM
|
||||
EC,112,INVALID_GROUP_ORDER
|
||||
EC,113,INVALID_PRIVATE_KEY
|
||||
EC,133,INVALID_SCALAR
|
||||
EC,114,MISSING_PARAMETERS
|
||||
EC,115,MISSING_PRIVATE_KEY
|
||||
EC,116,NON_NAMED_CURVE
|
||||
|
||||
+119
-28
@@ -123,27 +123,59 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
#include <openssl/thread.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "./internal.h"
|
||||
|
||||
|
||||
struct err_error_st {
|
||||
// file contains the filename where the error occurred.
|
||||
const char *file;
|
||||
// data contains a NUL-terminated string with optional data. It must be freed
|
||||
// with |OPENSSL_free|.
|
||||
char *data;
|
||||
// packed contains the error library and reason, as packed by ERR_PACK.
|
||||
uint32_t packed;
|
||||
// line contains the line number where the error occurred.
|
||||
uint16_t line;
|
||||
// mark indicates a reversion point in the queue. See |ERR_pop_to_mark|.
|
||||
unsigned mark : 1;
|
||||
};
|
||||
|
||||
// ERR_STATE contains the per-thread, error queue.
|
||||
typedef struct err_state_st {
|
||||
// errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
|
||||
// buffer.
|
||||
struct err_error_st errors[ERR_NUM_ERRORS];
|
||||
// top contains the index one past the most recent error. If |top| equals
|
||||
// |bottom| then the queue is empty.
|
||||
unsigned top;
|
||||
// bottom contains the index of the last error in the queue.
|
||||
unsigned bottom;
|
||||
|
||||
// to_free, if not NULL, contains a pointer owned by this structure that was
|
||||
// previously a |data| pointer of one of the elements of |errors|.
|
||||
void *to_free;
|
||||
} ERR_STATE;
|
||||
|
||||
extern const uint32_t kOpenSSLReasonValues[];
|
||||
extern const size_t kOpenSSLReasonValuesLen;
|
||||
extern const char kOpenSSLReasonStringData[];
|
||||
|
||||
// err_clear_data frees the optional |data| member of the given error.
|
||||
static void err_clear_data(struct err_error_st *error) {
|
||||
if ((error->flags & ERR_FLAG_MALLOCED) != 0) {
|
||||
OPENSSL_free(error->data);
|
||||
}
|
||||
error->data = NULL;
|
||||
error->flags &= ~ERR_FLAG_MALLOCED;
|
||||
}
|
||||
|
||||
// err_clear clears the given queued error.
|
||||
static void err_clear(struct err_error_st *error) {
|
||||
err_clear_data(error);
|
||||
OPENSSL_free(error->data);
|
||||
OPENSSL_memset(error, 0, sizeof(struct err_error_st));
|
||||
}
|
||||
|
||||
static void err_copy(struct err_error_st *dst, const struct err_error_st *src) {
|
||||
err_clear(dst);
|
||||
dst->file = src->file;
|
||||
if (src->data != NULL) {
|
||||
dst->data = OPENSSL_strdup(src->data);
|
||||
}
|
||||
dst->packed = src->packed;
|
||||
dst->line = src->line;
|
||||
}
|
||||
|
||||
// global_next_library contains the next custom library value to return.
|
||||
static int global_next_library = ERR_NUM_LIBS;
|
||||
|
||||
@@ -159,8 +191,7 @@ static void err_state_free(void *statep) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < ERR_NUM_ERRORS; i++) {
|
||||
for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) {
|
||||
err_clear(&state->errors[i]);
|
||||
}
|
||||
OPENSSL_free(state->to_free);
|
||||
@@ -227,7 +258,7 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
|
||||
} else {
|
||||
*data = error->data;
|
||||
if (flags != NULL) {
|
||||
*flags = error->flags & ERR_FLAG_PUBLIC_MASK;
|
||||
*flags = ERR_FLAG_STRING;
|
||||
}
|
||||
// If this error is being removed, take ownership of data from
|
||||
// the error. The semantics are such that the caller doesn't
|
||||
@@ -235,12 +266,11 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
|
||||
// ownership and retains it until the next call that affects the
|
||||
// error queue.
|
||||
if (inc) {
|
||||
if (error->flags & ERR_FLAG_MALLOCED) {
|
||||
if (error->data != NULL) {
|
||||
OPENSSL_free(state->to_free);
|
||||
state->to_free = error->data;
|
||||
}
|
||||
error->data = NULL;
|
||||
error->flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,24 +615,20 @@ void ERR_print_errors_fp(FILE *file) {
|
||||
ERR_print_errors_cb(print_errors_to_file, file);
|
||||
}
|
||||
|
||||
// err_set_error_data sets the data on the most recent error. The |flags|
|
||||
// argument is a combination of the |ERR_FLAG_*| values.
|
||||
static void err_set_error_data(char *data, int flags) {
|
||||
// err_set_error_data sets the data on the most recent error.
|
||||
static void err_set_error_data(char *data) {
|
||||
ERR_STATE *const state = err_get_state();
|
||||
struct err_error_st *error;
|
||||
|
||||
if (state == NULL || state->top == state->bottom) {
|
||||
if (flags & ERR_FLAG_MALLOCED) {
|
||||
OPENSSL_free(data);
|
||||
}
|
||||
OPENSSL_free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
error = &state->errors[state->top];
|
||||
|
||||
err_clear_data(error);
|
||||
OPENSSL_free(error->data);
|
||||
error->data = data;
|
||||
error->flags = flags;
|
||||
}
|
||||
|
||||
void ERR_put_error(int library, int unused, int reason, const char *file,
|
||||
@@ -680,7 +706,7 @@ static void err_add_error_vdata(unsigned num, va_list args) {
|
||||
}
|
||||
|
||||
buf[len] = 0;
|
||||
err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING);
|
||||
err_set_error_data(buf);
|
||||
}
|
||||
|
||||
void ERR_add_error_data(unsigned count, ...) {
|
||||
@@ -708,7 +734,7 @@ void ERR_add_error_dataf(const char *format, ...) {
|
||||
buf[buf_len] = 0;
|
||||
va_end(ap);
|
||||
|
||||
err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING);
|
||||
err_set_error_data(buf);
|
||||
}
|
||||
|
||||
int ERR_set_mark(void) {
|
||||
@@ -717,7 +743,7 @@ int ERR_set_mark(void) {
|
||||
if (state == NULL || state->bottom == state->top) {
|
||||
return 0;
|
||||
}
|
||||
state->errors[state->top].flags |= ERR_FLAG_MARK;
|
||||
state->errors[state->top].mark = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -731,8 +757,8 @@ int ERR_pop_to_mark(void) {
|
||||
while (state->bottom != state->top) {
|
||||
struct err_error_st *error = &state->errors[state->top];
|
||||
|
||||
if ((error->flags & ERR_FLAG_MARK) != 0) {
|
||||
error->flags &= ~ERR_FLAG_MARK;
|
||||
if (error->mark) {
|
||||
error->mark = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -754,3 +780,68 @@ void ERR_free_strings(void) {}
|
||||
void ERR_load_BIO_strings(void) {}
|
||||
|
||||
void ERR_load_ERR_strings(void) {}
|
||||
|
||||
struct err_save_state_st {
|
||||
struct err_error_st *errors;
|
||||
size_t num_errors;
|
||||
};
|
||||
|
||||
void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) {
|
||||
if (state == NULL) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < state->num_errors; i++) {
|
||||
err_clear(&state->errors[i]);
|
||||
}
|
||||
OPENSSL_free(state->errors);
|
||||
OPENSSL_free(state);
|
||||
}
|
||||
|
||||
ERR_SAVE_STATE *ERR_save_state(void) {
|
||||
ERR_STATE *const state = err_get_state();
|
||||
if (state == NULL || state->top == state->bottom) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE));
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Errors are stored in the range (bottom, top].
|
||||
size_t num_errors = state->top >= state->bottom
|
||||
? state->top - state->bottom
|
||||
: ERR_NUM_ERRORS + state->top - state->bottom;
|
||||
assert(num_errors < ERR_NUM_ERRORS);
|
||||
ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st));
|
||||
if (ret->errors == NULL) {
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st));
|
||||
ret->num_errors = num_errors;
|
||||
|
||||
for (size_t i = 0; i < num_errors; i++) {
|
||||
size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS;
|
||||
err_copy(&ret->errors[i], &state->errors[j]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ERR_restore_state(const ERR_SAVE_STATE *state) {
|
||||
if (state == NULL || state->num_errors == 0) {
|
||||
ERR_clear_error();
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_STATE *const dst = err_get_state();
|
||||
if (dst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < state->num_errors; i++) {
|
||||
err_copy(&dst->errors[i], &state->errors[i]);
|
||||
}
|
||||
dst->top = state->num_errors - 1;
|
||||
dst->bottom = ERR_NUM_ERRORS - 1;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "./internal.h"
|
||||
|
||||
|
||||
TEST(ErrTest, Overflow) {
|
||||
for (unsigned i = 0; i < ERR_NUM_ERRORS*2; i++) {
|
||||
@@ -119,3 +121,94 @@ TEST(ErrTest, PutMacro) {
|
||||
EXPECT_EQ(ERR_LIB_USER, ERR_GET_LIB(error));
|
||||
EXPECT_EQ(ERR_R_INTERNAL_ERROR, ERR_GET_REASON(error));
|
||||
}
|
||||
|
||||
TEST(ErrTest, SaveAndRestore) {
|
||||
// Restoring no state clears the error queue, including error data.
|
||||
ERR_put_error(1, 0 /* unused */, 1, "test1.c", 1);
|
||||
ERR_put_error(2, 0 /* unused */, 2, "test2.c", 2);
|
||||
ERR_add_error_data(1, "data1");
|
||||
ERR_restore_state(nullptr);
|
||||
EXPECT_EQ(0u, ERR_get_error());
|
||||
|
||||
// Add some entries to the error queue and save it.
|
||||
ERR_put_error(1, 0 /* unused */, 1, "test1.c", 1);
|
||||
ERR_add_error_data(1, "data1");
|
||||
ERR_put_error(2, 0 /* unused */, 2, "test2.c", 2);
|
||||
ERR_put_error(3, 0 /* unused */, 3, "test3.c", 3);
|
||||
ERR_add_error_data(1, "data3");
|
||||
bssl::UniquePtr<ERR_SAVE_STATE> saved(ERR_save_state());
|
||||
ASSERT_TRUE(saved);
|
||||
|
||||
// The existing error queue entries still exist.
|
||||
int line, flags;
|
||||
const char *file, *data;
|
||||
uint32_t packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
|
||||
EXPECT_EQ(ERR_GET_LIB(packed_error), 1);
|
||||
EXPECT_EQ(ERR_GET_REASON(packed_error), 1);
|
||||
EXPECT_STREQ("test1.c", file);
|
||||
EXPECT_EQ(line, 1);
|
||||
EXPECT_STREQ(data, "data1");
|
||||
EXPECT_EQ(flags, ERR_FLAG_STRING);
|
||||
|
||||
// The state may be restored, both over an empty and non-empty state.
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
SCOPED_TRACE(i);
|
||||
ERR_restore_state(saved.get());
|
||||
|
||||
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
|
||||
EXPECT_EQ(ERR_GET_LIB(packed_error), 1);
|
||||
EXPECT_EQ(ERR_GET_REASON(packed_error), 1);
|
||||
EXPECT_STREQ("test1.c", file);
|
||||
EXPECT_EQ(line, 1);
|
||||
EXPECT_STREQ(data, "data1");
|
||||
EXPECT_EQ(flags, ERR_FLAG_STRING);
|
||||
|
||||
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
|
||||
EXPECT_EQ(ERR_GET_LIB(packed_error), 2);
|
||||
EXPECT_EQ(ERR_GET_REASON(packed_error), 2);
|
||||
EXPECT_STREQ("test2.c", file);
|
||||
EXPECT_EQ(line, 2);
|
||||
EXPECT_STREQ(data, ""); // No error data is reported as the empty string.
|
||||
EXPECT_EQ(flags, 0);
|
||||
|
||||
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
|
||||
EXPECT_EQ(ERR_GET_LIB(packed_error), 3);
|
||||
EXPECT_EQ(ERR_GET_REASON(packed_error), 3);
|
||||
EXPECT_STREQ("test3.c", file);
|
||||
EXPECT_EQ(line, 3);
|
||||
EXPECT_STREQ(data, "data3");
|
||||
EXPECT_EQ(flags, ERR_FLAG_STRING);
|
||||
|
||||
// The error queue is now empty for the next iteration.
|
||||
EXPECT_EQ(0u, ERR_get_error());
|
||||
}
|
||||
|
||||
// Test a case where the error queue wraps around. The first set of errors
|
||||
// will all be discarded, but result in wrapping the list around.
|
||||
ERR_clear_error();
|
||||
for (unsigned i = 0; i < ERR_NUM_ERRORS / 2; i++) {
|
||||
ERR_put_error(0, 0 /* unused */, 0, "invalid", 0);
|
||||
}
|
||||
for (unsigned i = 1; i < ERR_NUM_ERRORS; i++) {
|
||||
ERR_put_error(i, 0 /* unused */, i, "test", i);
|
||||
}
|
||||
saved.reset(ERR_save_state());
|
||||
|
||||
// The state may be restored, both over an empty and non-empty state. Pop one
|
||||
// error off so the first iteration is tested to not be a no-op.
|
||||
ERR_get_error();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
SCOPED_TRACE(i);
|
||||
ERR_restore_state(saved.get());
|
||||
for (int j = 1; j < ERR_NUM_ERRORS; j++) {
|
||||
SCOPED_TRACE(j);
|
||||
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
|
||||
EXPECT_EQ(ERR_GET_LIB(packed_error), j);
|
||||
EXPECT_EQ(ERR_GET_REASON(packed_error), j);
|
||||
EXPECT_STREQ("test", file);
|
||||
EXPECT_EQ(line, j);
|
||||
}
|
||||
// The error queue is now empty for the next iteration.
|
||||
EXPECT_EQ(0u, ERR_get_error());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2017, 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_CRYPTO_ERR_INTERNAL_H
|
||||
#define OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Private error queue functions.
|
||||
|
||||
// ERR_SAVE_STATE contains a saved representation of the error queue. It is
|
||||
// slightly more compact than |ERR_STATE| as the error queue will typically not
|
||||
// contain |ERR_NUM_ERRORS| entries.
|
||||
typedef struct err_save_state_st ERR_SAVE_STATE;
|
||||
|
||||
// ERR_SAVE_STATE_free releases all memory associated with |state|.
|
||||
OPENSSL_EXPORT void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state);
|
||||
|
||||
// ERR_save_state returns a newly-allocated |ERR_SAVE_STATE| structure
|
||||
// containing the current state of the error queue or NULL on allocation
|
||||
// error. It should be released with |ERR_SAVE_STATE_free|.
|
||||
OPENSSL_EXPORT ERR_SAVE_STATE *ERR_save_state(void);
|
||||
|
||||
// ERR_restore_state clears the error queue and replaces it with |state|.
|
||||
OPENSSL_EXPORT void ERR_restore_state(const ERR_SAVE_STATE *state);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
|
||||
extern "C++" {
|
||||
|
||||
namespace bssl {
|
||||
|
||||
BORINGSSL_MAKE_DELETER(ERR_SAVE_STATE, ERR_SAVE_STATE_free)
|
||||
|
||||
} // namespace bssl
|
||||
|
||||
} // extern C++
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H
|
||||
@@ -1 +1,2 @@
|
||||
OBJ,101,INVALID_OID_STRING
|
||||
OBJ,100,UNKNOWN_NID
|
||||
|
||||
@@ -52,7 +52,9 @@ SSL,254,DOWNGRADE_DETECTED
|
||||
SSL,143,DTLS_MESSAGE_TOO_BIG
|
||||
SSL,257,DUPLICATE_EXTENSION
|
||||
SSL,264,DUPLICATE_KEY_SHARE
|
||||
SSL,283,EARLY_DATA_NOT_IN_USE
|
||||
SSL,144,ECC_CERT_NOT_FOR_SIGNING
|
||||
SSL,282,EMPTY_HELLO_RETRY_REQUEST
|
||||
SSL,145,EMS_STATE_INCONSISTENT
|
||||
SSL,146,ENCRYPTED_LENGTH_TOO_LONG
|
||||
SSL,147,ERROR_ADDING_EXTENSION
|
||||
@@ -63,6 +65,7 @@ SSL,151,EXTRA_DATA_IN_MESSAGE
|
||||
SSL,152,FRAGMENT_MISMATCH
|
||||
SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
|
||||
SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
|
||||
SSL,284,HANDSHAKE_NOT_COMPLETE
|
||||
SSL,155,HTTPS_PROXY_REQUEST
|
||||
SSL,156,HTTP_REQUEST
|
||||
SSL,157,INAPPROPRIATE_FALLBACK
|
||||
@@ -83,6 +86,7 @@ SSL,167,MISSING_TMP_ECDH_KEY
|
||||
SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
|
||||
SSL,169,MTU_TOO_SMALL
|
||||
SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN
|
||||
SSL,285,NEGOTIATED_TB_WITHOUT_EMS_OR_RI
|
||||
SSL,171,NESTED_GROUP
|
||||
SSL,172,NO_CERTIFICATES_RETURNED
|
||||
SSL,173,NO_CERTIFICATE_ASSIGNED
|
||||
@@ -113,6 +117,7 @@ SSL,191,PATH_TOO_LONG
|
||||
SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
|
||||
SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
|
||||
SSL,267,PRE_SHARED_KEY_MUST_BE_LAST
|
||||
SSL,287,PRIVATE_KEY_OPERATION_FAILED
|
||||
SSL,194,PROTOCOL_IS_SHUTDOWN
|
||||
SSL,271,PSK_IDENTITY_BINDER_COUNT_MISMATCH
|
||||
SSL,195,PSK_IDENTITY_NOT_FOUND
|
||||
@@ -130,6 +135,7 @@ SSL,205,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
|
||||
SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING
|
||||
SSL,207,SERVERHELLO_TLSEXT
|
||||
SSL,273,SERVER_CERT_CHANGED
|
||||
SSL,286,SERVER_ECHOED_INVALID_SESSION_ID
|
||||
SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
|
||||
SSL,209,SESSION_MAY_NOT_BE_CREATED
|
||||
SSL,250,SHUTDOWN_WHILE_IN_INIT
|
||||
|
||||
+77
-3
@@ -70,6 +70,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/digest.h>
|
||||
@@ -206,6 +207,27 @@ static bool SetupContext(FileTest *t, EVP_PKEY_CTX *ctx) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (t->HasAttribute("OAEPDigest")) {
|
||||
const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("OAEPDigest"));
|
||||
if (digest == nullptr || !EVP_PKEY_CTX_set_rsa_oaep_md(ctx, digest)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (t->HasAttribute("OAEPLabel")) {
|
||||
std::vector<uint8_t> label;
|
||||
if (!t->GetBytes(&label, "OAEPLabel")) {
|
||||
return false;
|
||||
}
|
||||
// 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())));
|
||||
if (!buf ||
|
||||
!EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, buf.get(), label.size())) {
|
||||
return false;
|
||||
}
|
||||
buf.release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -239,6 +261,9 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
|
||||
} else if (t->GetType() == "VerifyMessage") {
|
||||
md_op_init = EVP_DigestVerifyInit;
|
||||
is_verify = true;
|
||||
} else if (t->GetType() == "Encrypt") {
|
||||
key_op_init = EVP_PKEY_encrypt_init;
|
||||
key_op = EVP_PKEY_encrypt;
|
||||
} else {
|
||||
ADD_FAILURE() << "Unknown test " << t->GetType();
|
||||
return false;
|
||||
@@ -316,8 +341,58 @@ static bool TestEVP(FileTest *t, KeyMap *key_map) {
|
||||
return false;
|
||||
}
|
||||
actual.resize(len);
|
||||
if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size()) ||
|
||||
!t->GetBytes(&output, "Output")) {
|
||||
if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Encryption is non-deterministic, so we check by decrypting.
|
||||
if (t->HasAttribute("CheckDecrypt")) {
|
||||
size_t plaintext_len;
|
||||
ctx.reset(EVP_PKEY_CTX_new(key, nullptr));
|
||||
if (!ctx ||
|
||||
!EVP_PKEY_decrypt_init(ctx.get()) ||
|
||||
(digest != nullptr &&
|
||||
!EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
|
||||
!SetupContext(t, ctx.get()) ||
|
||||
!EVP_PKEY_decrypt(ctx.get(), nullptr, &plaintext_len, actual.data(),
|
||||
actual.size())) {
|
||||
return false;
|
||||
}
|
||||
output.resize(plaintext_len);
|
||||
if (!EVP_PKEY_decrypt(ctx.get(), output.data(), &plaintext_len,
|
||||
actual.data(), actual.size())) {
|
||||
ADD_FAILURE() << "Could not decrypt result.";
|
||||
return false;
|
||||
}
|
||||
output.resize(plaintext_len);
|
||||
EXPECT_EQ(Bytes(input), Bytes(output)) << "Decrypted result mismatch.";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Some signature schemes are non-deterministic, so we check by verifying.
|
||||
if (t->HasAttribute("CheckVerify")) {
|
||||
ctx.reset(EVP_PKEY_CTX_new(key, nullptr));
|
||||
if (!ctx ||
|
||||
!EVP_PKEY_verify_init(ctx.get()) ||
|
||||
(digest != nullptr &&
|
||||
!EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) ||
|
||||
!SetupContext(t, ctx.get())) {
|
||||
return false;
|
||||
}
|
||||
if (t->HasAttribute("VerifyPSSSaltLength") &&
|
||||
!EVP_PKEY_CTX_set_rsa_pss_saltlen(
|
||||
ctx.get(),
|
||||
atoi(t->GetAttributeOrDie("VerifyPSSSaltLength").c_str()))) {
|
||||
return false;
|
||||
}
|
||||
EXPECT_TRUE(EVP_PKEY_verify(ctx.get(), actual.data(), actual.size(),
|
||||
input.data(), input.size()))
|
||||
<< "Could not verify result.";
|
||||
return true;
|
||||
}
|
||||
|
||||
// By default, check by comparing the result against Output.
|
||||
if (!t->GetBytes(&output, "Output")) {
|
||||
return false;
|
||||
}
|
||||
actual.resize(len);
|
||||
@@ -335,7 +410,6 @@ TEST(EVPTest, TestVectors) {
|
||||
EXPECT_EQ(t->GetAttributeOrDie("Error"), ERR_reason_error_string(err));
|
||||
} else if (!result) {
|
||||
ADD_FAILURE() << "Operation unexpectedly failed.";
|
||||
ERR_print_errors_fp(stdout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ PublicKey = RSA-2048-SPKI
|
||||
Type = RSA
|
||||
Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
|
||||
|
||||
# The same key but with a negative RSA modulus.
|
||||
PublicKey = RSA-2048-SPKI-Negative
|
||||
Input = 30820121300d06092a864886f70d01010105000382010e003082010902820100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
|
||||
Error = NEGATIVE_NUMBER
|
||||
|
||||
# The same key but with missing parameters rather than a NULL.
|
||||
PublicKey = RSA-2048-SPKI-Invalid
|
||||
Input = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
|
||||
@@ -261,6 +266,14 @@ Digest = SHA256
|
||||
Input = "0123456789ABCDEF0123456789ABCDEF"
|
||||
Output = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a
|
||||
|
||||
# A non-zero salt length must be checked by round-tripping.
|
||||
Sign = RSA-2048
|
||||
RSAPadding = PSS
|
||||
PSSSaltLength = 32
|
||||
Digest = SHA256
|
||||
Input = "0123456789ABCDEF0123456789ABCDEF"
|
||||
CheckVerify
|
||||
|
||||
# Auto-detected salt length
|
||||
Verify = RSA-2048-SPKI
|
||||
RSAPadding = PSS
|
||||
@@ -269,6 +282,24 @@ Digest = SHA256
|
||||
Input = "0123456789ABCDEF0123456789ABCDEF"
|
||||
Output = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a
|
||||
|
||||
# Signing with salt length -1 means to match the digest length.
|
||||
Sign = RSA-2048
|
||||
RSAPadding = PSS
|
||||
PSSSaltLength = -1
|
||||
VerifyPSSSaltLength = 32
|
||||
Digest = SHA256
|
||||
Input = "0123456789ABCDEF0123456789ABCDEF"
|
||||
CheckVerify
|
||||
|
||||
# Signing with salt length -2 means to maximize the salt length.
|
||||
Sign = RSA-2048
|
||||
RSAPadding = PSS
|
||||
PSSSaltLength = -2
|
||||
VerifyPSSSaltLength = 222 # 256 - 32 - 2
|
||||
Digest = SHA256
|
||||
Input = "0123456789ABCDEF0123456789ABCDEF"
|
||||
CheckVerify
|
||||
|
||||
# Wrong digest
|
||||
Verify = RSA-2048-SPKI
|
||||
RSAPadding = PSS
|
||||
@@ -482,12 +513,60 @@ RSAPadding = OAEP
|
||||
Input = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5af
|
||||
Output = "Hello World"
|
||||
|
||||
# OAEP padding with label and custom hash.
|
||||
Decrypt = RSA-2048
|
||||
RSAPadding = OAEP
|
||||
OAEPDigest = SHA512
|
||||
OAEPLabel = 00112233445566778899aabbccddeeff
|
||||
Input = 48b956c22b8e40cc38f0893672ddf488fc806cf1fcc6239c66dd8345eb543d6b5cac589e6c7ae86dac1c2436c4d72c48009a737b2c649e6000dbab17203e4d9c078bd70b649700a0830d4ddc396af0c48973177a229e48259d93247f04f76474c7611b530c66f020c4da2cc861c2e4104831ecc0336e0cb10d6520fdefd0b33606f5cdd736dd439583b9b6011cce99623c93caf5f76e21e9fefab414795dd5ac12cba551be74ebf266834fcffab182c5e7c9b6c064df154cb26ddfd4fe2fd87590005f4bf45e776a0082803e9f68995b8eeb4c6802c67b5ef349e5b2dc0cf7a12fc097030f2bd28f0253f17129b04c82993a12957728b35880fdd2f8d0cc469f
|
||||
Output = "Hello World"
|
||||
|
||||
# OAEP padding, corrupted ciphertext
|
||||
Decrypt = RSA-2048
|
||||
RSAPadding = OAEP
|
||||
Input = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5ac
|
||||
Error = OAEP_DECODING_ERROR
|
||||
|
||||
# Test that RSA encryption successfully round-trips through decryption
|
||||
# with various parameters.
|
||||
Encrypt = RSA-2048
|
||||
Input = "Hello World"
|
||||
CheckDecrypt
|
||||
|
||||
Encrypt = RSA-2048
|
||||
RSAPadding = OAEP
|
||||
Input = "Hello World"
|
||||
CheckDecrypt
|
||||
|
||||
Encrypt = RSA-2048
|
||||
RSAPadding = OAEP
|
||||
OAEPDigest = SHA512
|
||||
OAEPLabel = 00112233445566778899aabbccddeeff
|
||||
Input = "Hello World"
|
||||
CheckDecrypt
|
||||
|
||||
# Though we will never generate such a key, test that RSA keys where p < q work
|
||||
# properly.
|
||||
PrivateKey = RSA-Swapped
|
||||
Type = RSA
|
||||
Input = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429
|
||||
|
||||
Sign = RSA-Swapped
|
||||
Digest = SHA256
|
||||
Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
Output = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f
|
||||
|
||||
# Though we will never generate such a key, test that RSA keys where p and q are
|
||||
# different sizes work properly.
|
||||
PrivateKey = RSA-PrimeMismatch
|
||||
Type = RSA
|
||||
Input = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d24401052b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c
|
||||
|
||||
Sign = RSA-PrimeMismatch
|
||||
Digest = SHA256
|
||||
Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
Output = 6192b1ce630c87d02e8245fd74d4f6ecac37eef979d188c8fa48c4d355fbe814e7dd3152f42bb020d769b540d11867af5b947387b8c99158d56901ff3708e423931178213916ae1002f162c9d497aacacdcb20e6ffe7ed40138a253fc943ddf3587433df5831a3ce46aeefce358a009bf6bad12d82d77424c2755d984d7da196
|
||||
|
||||
|
||||
# EC tests
|
||||
|
||||
|
||||
@@ -151,8 +151,8 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
|
||||
// Calculate the public key.
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL ||
|
||||
!BN_mod_exp_mont(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx,
|
||||
NULL)) {
|
||||
!BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
|
||||
ctx, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,8 @@
|
||||
|
||||
|
||||
static void ed25519_free(EVP_PKEY *pkey) {
|
||||
if (pkey->pkey.ptr != NULL) {
|
||||
ED25519_KEY *key = pkey->pkey.ptr;
|
||||
OPENSSL_cleanse(key, sizeof(ED25519_KEY));
|
||||
OPENSSL_free(key);
|
||||
pkey->pkey.ptr = NULL;
|
||||
}
|
||||
OPENSSL_free(pkey->pkey.ptr);
|
||||
pkey->pkey.ptr = NULL;
|
||||
}
|
||||
|
||||
static int set_pubkey(EVP_PKEY *pkey, const uint8_t pubkey[32]) {
|
||||
|
||||
+12
-14
@@ -92,6 +92,11 @@ typedef struct {
|
||||
size_t oaep_labellen;
|
||||
} RSA_PKEY_CTX;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
} RSA_OAEP_LABEL_PARAMS;
|
||||
|
||||
static int pkey_rsa_init(EVP_PKEY_CTX *ctx) {
|
||||
RSA_PKEY_CTX *rctx;
|
||||
rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
|
||||
@@ -485,20 +490,17 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
|
||||
}
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL: {
|
||||
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
|
||||
return 0;
|
||||
}
|
||||
OPENSSL_free(rctx->oaep_label);
|
||||
if (p2 && p1 > 0) {
|
||||
rctx->oaep_label = p2;
|
||||
rctx->oaep_labellen = p1;
|
||||
} else {
|
||||
rctx->oaep_label = NULL;
|
||||
rctx->oaep_labellen = 0;
|
||||
}
|
||||
RSA_OAEP_LABEL_PARAMS *params = p2;
|
||||
rctx->oaep_label = params->data;
|
||||
rctx->oaep_labellen = params->len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
||||
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
|
||||
@@ -611,13 +613,9 @@ int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
|
||||
|
||||
int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label,
|
||||
size_t label_len) {
|
||||
if (label_len > INT_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
RSA_OAEP_LABEL_PARAMS params = {label, label_len};
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
|
||||
EVP_PKEY_CTRL_RSA_OAEP_LABEL, (int)label_len,
|
||||
(void *)label);
|
||||
EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
|
||||
|
||||
+2
-23
@@ -63,19 +63,9 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "../fipsmodule/rsa/internal.h"
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static struct CRYPTO_STATIC_MUTEX g_buggy_lock = CRYPTO_STATIC_MUTEX_INIT;
|
||||
static int g_buggy = 1;
|
||||
|
||||
void EVP_set_buggy_rsa_parser(int buggy) {
|
||||
CRYPTO_STATIC_MUTEX_lock_write(&g_buggy_lock);
|
||||
g_buggy = buggy;
|
||||
CRYPTO_STATIC_MUTEX_unlock_write(&g_buggy_lock);
|
||||
}
|
||||
|
||||
static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
|
||||
// See RFC 3279, section 2.3.1.
|
||||
CBB spki, algorithm, oid, null, key_bitstring;
|
||||
@@ -96,11 +86,6 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
|
||||
}
|
||||
|
||||
static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
|
||||
int buggy;
|
||||
CRYPTO_STATIC_MUTEX_lock_read(&g_buggy_lock);
|
||||
buggy = g_buggy;
|
||||
CRYPTO_STATIC_MUTEX_unlock_read(&g_buggy_lock);
|
||||
|
||||
// See RFC 3279, section 2.3.1.
|
||||
|
||||
// The parameters must be NULL.
|
||||
@@ -112,13 +97,7 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Estonian IDs issued between September 2014 to September 2015 are
|
||||
// broken. See https://crbug.com/532048 and https://crbug.com/534766.
|
||||
//
|
||||
// TODO(davidben): Switch this to the strict version in March 2016 or when
|
||||
// Chromium can force client certificates down a different codepath, whichever
|
||||
// comes first.
|
||||
RSA *rsa = buggy ? RSA_parse_public_key_buggy(key) : RSA_parse_public_key(key);
|
||||
RSA *rsa = RSA_parse_public_key(key);
|
||||
if (rsa == NULL || CBS_len(key) != 0) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
|
||||
RSA_free(rsa);
|
||||
@@ -182,7 +161,7 @@ static int int_rsa_size(const EVP_PKEY *pkey) {
|
||||
}
|
||||
|
||||
static int rsa_bits(const EVP_PKEY *pkey) {
|
||||
return BN_num_bits(pkey->pkey.rsa->n);
|
||||
return RSA_bits(pkey->pkey.rsa);
|
||||
}
|
||||
|
||||
static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); }
|
||||
|
||||
@@ -113,7 +113,6 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/stack.h>
|
||||
#include <openssl/thread.h>
|
||||
|
||||
@@ -8,7 +8,7 @@ Please note that we cannot answer questions about FIPS, nor about using BoringSS
|
||||
|
||||
BoringCrypto has undergone the following validations:
|
||||
|
||||
1. 2017-06-15: certificate [#2964](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/1401val2017.htm#2964), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx) (in docx format).
|
||||
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).
|
||||
|
||||
## Running CAVP tests
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
@@ -32,7 +39,7 @@
|
||||
# for scaling too, I [try to] avoid the latter by favoring off-by-2
|
||||
# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF.
|
||||
#
|
||||
# As was shown by Dean Gaudet <dean@arctic.org>, the above note turned
|
||||
# As was shown by Dean Gaudet, the above note turned out to be
|
||||
# void. Performance improvement with off-by-2 shifts was observed on
|
||||
# intermediate implementation, which was spilling yet another register
|
||||
# to stack... Final offset*4 code below runs just a tad faster on P4,
|
||||
@@ -48,8 +55,8 @@
|
||||
# better performance on most recent µ-archs...
|
||||
#
|
||||
# Third version adds AES_cbc_encrypt implementation, which resulted in
|
||||
# up to 40% performance imrovement of CBC benchmark results. 40% was
|
||||
# observed on P4 core, where "overall" imrovement coefficient, i.e. if
|
||||
# up to 40% performance improvement of CBC benchmark results. 40% was
|
||||
# observed on P4 core, where "overall" improvement coefficient, i.e. if
|
||||
# compared to PIC generated by GCC and in CBC mode, was observed to be
|
||||
# as large as 4x:-) CBC performance is virtually identical to ECB now
|
||||
# and on some platforms even better, e.g. 17.6 "small" cycles/byte on
|
||||
@@ -152,7 +159,7 @@
|
||||
# combinations then attack becomes infeasible. This is why revised
|
||||
# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
|
||||
# of data is to be processed in one stroke. The current size limit of
|
||||
# 512 bytes is chosen to provide same [diminishigly low] probability
|
||||
# 512 bytes is chosen to provide same [diminishingly low] probability
|
||||
# for cache-line to remain untouched in large chunk operation with
|
||||
# large S-box as for single block operation with compact S-box and
|
||||
# surely needs more careful consideration...
|
||||
@@ -164,12 +171,12 @@
|
||||
# yield execution to process performing AES just before timer fires
|
||||
# off the scheduler, immediately regain control of CPU and analyze the
|
||||
# cache state. For this attack to be efficient attacker would have to
|
||||
# effectively slow down the operation by several *orders* of magnitute,
|
||||
# effectively slow down the operation by several *orders* of magnitude,
|
||||
# by ratio of time slice to duration of handful of AES rounds, which
|
||||
# unlikely to remain unnoticed. Not to mention that this also means
|
||||
# that he would spend correspondigly more time to collect enough
|
||||
# that he would spend correspondingly more time to collect enough
|
||||
# statistical data to mount the attack. It's probably appropriate to
|
||||
# say that if adeversary reckons that this attack is beneficial and
|
||||
# say that if adversary reckons that this attack is beneficial and
|
||||
# risks to be noticed, you probably have larger problems having him
|
||||
# mere opportunity. In other words suggested code design expects you
|
||||
# to preclude/mitigate this attack by overall system security design.
|
||||
@@ -233,7 +240,7 @@ $small_footprint=1; # $small_footprint=1 code is ~5% slower [on
|
||||
# contention and in hope to "collect" 5% back
|
||||
# in real-life applications...
|
||||
|
||||
$vertical_spin=0; # shift "verticaly" defaults to 0, because of
|
||||
$vertical_spin=0; # shift "vertically" defaults to 0, because of
|
||||
# its proof-of-concept status...
|
||||
# Note that there is no decvert(), as well as last encryption round is
|
||||
# performed with "horizontal" shifts. This is because this "vertical"
|
||||
@@ -1599,7 +1606,7 @@ sub decstep()
|
||||
# no instructions are reordered, as performance appears
|
||||
# optimal... or rather that all attempts to reorder didn't
|
||||
# result in better performance [which by the way is not a
|
||||
# bit lower than ecryption].
|
||||
# bit lower than encryption].
|
||||
if($i==3) { &mov ($key,$__key); }
|
||||
else { &mov ($out,$s[0]); }
|
||||
&and ($out,0xFF);
|
||||
|
||||
@@ -76,6 +76,11 @@ $code=<<___;
|
||||
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
|
||||
#endif
|
||||
|
||||
@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
|
||||
@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 AES
|
||||
@ instructions are in aesv8-armx.pl.)
|
||||
.arch armv7-a
|
||||
|
||||
.text
|
||||
#if defined(__thumb2__) && !defined(__APPLE__)
|
||||
.syntax unified
|
||||
@@ -200,10 +205,10 @@ asm_AES_encrypt:
|
||||
#ifndef __thumb2__
|
||||
sub r3,pc,#8 @ asm_AES_encrypt
|
||||
#else
|
||||
adr r3,asm_AES_encrypt
|
||||
adr r3,.
|
||||
#endif
|
||||
stmdb sp!,{r1,r4-r12,lr}
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $tbl,AES_Te
|
||||
#else
|
||||
sub $tbl,r3,#asm_AES_encrypt-AES_Te @ Te
|
||||
@@ -450,7 +455,7 @@ _armv4_AES_set_encrypt_key:
|
||||
#ifndef __thumb2__
|
||||
sub r3,pc,#8 @ asm_AES_set_encrypt_key
|
||||
#else
|
||||
adr r3,asm_AES_set_encrypt_key
|
||||
adr r3,.
|
||||
#endif
|
||||
teq r0,#0
|
||||
#ifdef __thumb2__
|
||||
@@ -481,7 +486,7 @@ _armv4_AES_set_encrypt_key:
|
||||
mov lr,r1 @ bits
|
||||
mov $key,r2 @ key
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $tbl,AES_Te+1024 @ Te4
|
||||
#else
|
||||
sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
|
||||
@@ -976,10 +981,10 @@ asm_AES_decrypt:
|
||||
#ifndef __thumb2__
|
||||
sub r3,pc,#8 @ asm_AES_decrypt
|
||||
#else
|
||||
adr r3,asm_AES_decrypt
|
||||
adr r3,.
|
||||
#endif
|
||||
stmdb sp!,{r1,r4-r12,lr}
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $tbl,AES_Td
|
||||
#else
|
||||
sub $tbl,r3,#asm_AES_decrypt-AES_Td @ Td
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
@@ -590,13 +597,21 @@ $code.=<<___;
|
||||
.type asm_AES_encrypt,\@function,3
|
||||
.hidden asm_AES_encrypt
|
||||
asm_AES_encrypt:
|
||||
.cfi_startproc
|
||||
mov %rsp,%rax
|
||||
.cfi_def_cfa_register %rax
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
|
||||
# allocate frame "above" key schedule
|
||||
lea -63(%rdx),%rcx # %rdx is key argument
|
||||
@@ -609,6 +624,7 @@ asm_AES_encrypt:
|
||||
|
||||
mov %rsi,16(%rsp) # save out
|
||||
mov %rax,24(%rsp) # save original stack pointer
|
||||
.cfi_cfa_expression %rsp+24,deref,+8
|
||||
.Lenc_prologue:
|
||||
|
||||
mov %rdx,$key
|
||||
@@ -635,20 +651,29 @@ asm_AES_encrypt:
|
||||
|
||||
mov 16(%rsp),$out # restore out
|
||||
mov 24(%rsp),%rsi # restore saved stack pointer
|
||||
.cfi_def_cfa %rsi,8
|
||||
mov $s0,0($out) # write output vector
|
||||
mov $s1,4($out)
|
||||
mov $s2,8($out)
|
||||
mov $s3,12($out)
|
||||
|
||||
mov -48(%rsi),%r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rsi),%r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rsi),%r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rsi),%r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rsi),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov -8(%rsi),%rbx
|
||||
.cfi_restore %rbx
|
||||
lea (%rsi),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lenc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size asm_AES_encrypt,.-asm_AES_encrypt
|
||||
___
|
||||
|
||||
@@ -1186,13 +1211,21 @@ $code.=<<___;
|
||||
.type asm_AES_decrypt,\@function,3
|
||||
.hidden asm_AES_decrypt
|
||||
asm_AES_decrypt:
|
||||
.cfi_startproc
|
||||
mov %rsp,%rax
|
||||
.cfi_def_cfa_register %rax
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
|
||||
# allocate frame "above" key schedule
|
||||
lea -63(%rdx),%rcx # %rdx is key argument
|
||||
@@ -1205,6 +1238,7 @@ asm_AES_decrypt:
|
||||
|
||||
mov %rsi,16(%rsp) # save out
|
||||
mov %rax,24(%rsp) # save original stack pointer
|
||||
.cfi_cfa_expression %rsp+24,deref,+8
|
||||
.Ldec_prologue:
|
||||
|
||||
mov %rdx,$key
|
||||
@@ -1233,20 +1267,29 @@ asm_AES_decrypt:
|
||||
|
||||
mov 16(%rsp),$out # restore out
|
||||
mov 24(%rsp),%rsi # restore saved stack pointer
|
||||
.cfi_def_cfa %rsi,8
|
||||
mov $s0,0($out) # write output vector
|
||||
mov $s1,4($out)
|
||||
mov $s2,8($out)
|
||||
mov $s3,12($out)
|
||||
|
||||
mov -48(%rsi),%r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rsi),%r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rsi),%r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rsi),%r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rsi),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov -8(%rsi),%rbx
|
||||
.cfi_restore %rbx
|
||||
lea (%rsi),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Ldec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size asm_AES_decrypt,.-asm_AES_decrypt
|
||||
___
|
||||
#------------------------------------------------------------------#
|
||||
@@ -1284,22 +1327,34 @@ $code.=<<___;
|
||||
.globl asm_AES_set_encrypt_key
|
||||
.type asm_AES_set_encrypt_key,\@function,3
|
||||
asm_AES_set_encrypt_key:
|
||||
.cfi_startproc
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12 # redundant, but allows to share
|
||||
.cfi_push %r12
|
||||
push %r13 # exception handler...
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
sub \$8,%rsp
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.Lenc_key_prologue:
|
||||
|
||||
call _x86_64_AES_set_encrypt_key
|
||||
|
||||
mov 40(%rsp),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov 48(%rsp),%rbx
|
||||
.cfi_restore %rbx
|
||||
add \$56,%rsp
|
||||
.cfi_adjust_cfa_offset -56
|
||||
.Lenc_key_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
|
||||
|
||||
.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
|
||||
@@ -1549,13 +1604,21 @@ $code.=<<___;
|
||||
.globl asm_AES_set_decrypt_key
|
||||
.type asm_AES_set_decrypt_key,\@function,3
|
||||
asm_AES_set_decrypt_key:
|
||||
.cfi_startproc
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
push %rdx # save key schedule
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.Ldec_key_prologue:
|
||||
|
||||
call _x86_64_AES_set_encrypt_key
|
||||
@@ -1609,14 +1672,22 @@ $code.=<<___;
|
||||
xor %rax,%rax
|
||||
.Labort:
|
||||
mov 8(%rsp),%r15
|
||||
.cfi_restore %r15
|
||||
mov 16(%rsp),%r14
|
||||
.cfi_restore %r14
|
||||
mov 24(%rsp),%r13
|
||||
.cfi_restore %r13
|
||||
mov 32(%rsp),%r12
|
||||
.cfi_restore %r12
|
||||
mov 40(%rsp),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov 48(%rsp),%rbx
|
||||
.cfi_restore %rbx
|
||||
add \$56,%rsp
|
||||
.cfi_adjust_cfa_offset -56
|
||||
.Ldec_key_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size asm_AES_set_decrypt_key,.-asm_AES_set_decrypt_key
|
||||
___
|
||||
|
||||
@@ -1645,15 +1716,23 @@ $code.=<<___;
|
||||
.extern OPENSSL_ia32cap_P
|
||||
.hidden asm_AES_cbc_encrypt
|
||||
asm_AES_cbc_encrypt:
|
||||
.cfi_startproc
|
||||
cmp \$0,%rdx # check length
|
||||
je .Lcbc_epilogue
|
||||
pushfq
|
||||
.cfi_push 49 # %rflags
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
.Lcbc_prologue:
|
||||
|
||||
cld
|
||||
@@ -1699,8 +1778,10 @@ asm_AES_cbc_encrypt:
|
||||
.Lcbc_te_ok:
|
||||
|
||||
xchg %rsp,$key
|
||||
.cfi_def_cfa_register $key
|
||||
#add \$8,%rsp # reserve for return address!
|
||||
mov $key,$_rsp # save %rsp
|
||||
.cfi_cfa_expression $_rsp,deref,+64
|
||||
.Lcbc_fast_body:
|
||||
mov %rdi,$_inp # save copy of inp
|
||||
mov %rsi,$_out # save copy of out
|
||||
@@ -1930,7 +2011,7 @@ asm_AES_cbc_encrypt:
|
||||
lea ($key,%rax),%rax
|
||||
mov %rax,$keyend
|
||||
|
||||
# pick Te4 copy which can't "overlap" with stack frame or key scdedule
|
||||
# pick Te4 copy which can't "overlap" with stack frame or key schedule
|
||||
lea 2048($sbox),$sbox
|
||||
lea 768-8(%rsp),%rax
|
||||
sub $sbox,%rax
|
||||
@@ -2082,17 +2163,27 @@ asm_AES_cbc_encrypt:
|
||||
.align 16
|
||||
.Lcbc_exit:
|
||||
mov $_rsp,%rsi
|
||||
.cfi_def_cfa %rsi,64
|
||||
mov (%rsi),%r15
|
||||
.cfi_restore %r15
|
||||
mov 8(%rsi),%r14
|
||||
.cfi_restore %r14
|
||||
mov 16(%rsi),%r13
|
||||
.cfi_restore %r13
|
||||
mov 24(%rsi),%r12
|
||||
.cfi_restore %r12
|
||||
mov 32(%rsi),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov 40(%rsi),%rbx
|
||||
.cfi_restore %rbx
|
||||
lea 48(%rsi),%rsp
|
||||
.cfi_def_cfa %rsp,16
|
||||
.Lcbc_popfq:
|
||||
popfq
|
||||
.cfi_pop 49 # %rflags
|
||||
.Lcbc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size asm_AES_cbc_encrypt,.-asm_AES_cbc_encrypt
|
||||
___
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
@@ -43,18 +50,22 @@
|
||||
# Add aesni_xts_[en|de]crypt. Westmere spends 1.50 cycles processing
|
||||
# one byte out of 8KB with 128-bit key, Sandy Bridge - 1.09.
|
||||
|
||||
# November 2015
|
||||
#
|
||||
# Add aesni_ocb_[en|de]crypt. [Removed in BoringSSL]
|
||||
|
||||
######################################################################
|
||||
# Current large-block performance in cycles per byte processed with
|
||||
# 128-bit key (less is better).
|
||||
#
|
||||
# CBC en-/decrypt CTR XTS ECB
|
||||
# CBC en-/decrypt CTR XTS ECB OCB
|
||||
# Westmere 3.77/1.37 1.37 1.52 1.27
|
||||
# * Bridge 5.07/0.98 0.99 1.09 0.91
|
||||
# Haswell 4.44/0.80 0.97 1.03 0.72
|
||||
# Skylake 2.68/0.65 0.65 0.66 0.64
|
||||
# Silvermont 5.77/3.56 3.67 4.03 3.46
|
||||
# Goldmont 3.84/1.39 1.39 1.63 1.31
|
||||
# Bulldozer 5.80/0.98 1.05 1.24 0.93
|
||||
# * Bridge 5.07/0.98 0.99 1.09 0.91 1.10
|
||||
# Haswell 4.44/0.80 0.97 1.03 0.72 0.76
|
||||
# Skylake 2.68/0.65 0.65 0.66 0.64 0.66
|
||||
# Silvermont 5.77/3.56 3.67 4.03 3.46 4.03
|
||||
# Goldmont 3.84/1.39 1.39 1.63 1.31 1.70
|
||||
# Bulldozer 5.80/0.98 1.05 1.24 0.93 1.23
|
||||
|
||||
$PREFIX="aesni"; # if $PREFIX is set to "AES", the script
|
||||
# generates drop-in replacement for
|
||||
@@ -228,7 +239,7 @@ sub aesni_generate1 # fully unrolled loop
|
||||
# can schedule aes[enc|dec] every cycle optimal interleave factor
|
||||
# equals to corresponding instructions latency. 8x is optimal for
|
||||
# * Bridge, but it's unfeasible to accommodate such implementation
|
||||
# in XMM registers addreassable in 32-bit mode and therefore maximum
|
||||
# in XMM registers addressable in 32-bit mode and therefore maximum
|
||||
# of 6x is used instead...
|
||||
|
||||
sub aesni_generate2
|
||||
@@ -2425,7 +2436,7 @@ if ($PREFIX eq "aesni") {
|
||||
&pxor ("xmm3","xmm3");
|
||||
&aesenclast ("xmm2","xmm3");
|
||||
|
||||
&movdqa ("xmm3","xmm1")
|
||||
&movdqa ("xmm3","xmm1");
|
||||
&pslldq ("xmm1",4);
|
||||
&pxor ("xmm3","xmm1");
|
||||
&pslldq ("xmm1",4);
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
# identical to CBC, because CBC-MAC is essentially CBC encrypt without
|
||||
# saving output. CCM CTR "stays invisible," because it's neatly
|
||||
# interleaved wih CBC-MAC. This provides ~30% improvement over
|
||||
# "straghtforward" CCM implementation with CTR and CBC-MAC performed
|
||||
# "straightforward" CCM implementation with CTR and CBC-MAC performed
|
||||
# disjointly. Parallelizable modes practically achieve the theoretical
|
||||
# limit.
|
||||
#
|
||||
@@ -143,14 +143,14 @@
|
||||
# asymptotic, if it can be surpassed, isn't it? What happens there?
|
||||
# Rewind to CBC paragraph for the answer. Yes, out-of-order execution
|
||||
# magic is responsible for this. Processor overlaps not only the
|
||||
# additional instructions with AES ones, but even AES instuctions
|
||||
# additional instructions with AES ones, but even AES instructions
|
||||
# processing adjacent triplets of independent blocks. In the 6x case
|
||||
# additional instructions still claim disproportionally small amount
|
||||
# of additional cycles, but in 8x case number of instructions must be
|
||||
# a tad too high for out-of-order logic to cope with, and AES unit
|
||||
# remains underutilized... As you can see 8x interleave is hardly
|
||||
# justifiable, so there no need to feel bad that 32-bit aesni-x86.pl
|
||||
# utilizies 6x interleave because of limited register bank capacity.
|
||||
# utilizes 6x interleave because of limited register bank capacity.
|
||||
#
|
||||
# Higher interleave factors do have negative impact on Westmere
|
||||
# performance. While for ECB mode it's negligible ~1.5%, other
|
||||
@@ -1182,6 +1182,7 @@ $code.=<<___;
|
||||
.type aesni_ctr32_encrypt_blocks,\@function,5
|
||||
.align 16
|
||||
aesni_ctr32_encrypt_blocks:
|
||||
.cfi_startproc
|
||||
cmp \$1,$len
|
||||
jne .Lctr32_bulk
|
||||
|
||||
@@ -1204,7 +1205,9 @@ $code.=<<___;
|
||||
.align 16
|
||||
.Lctr32_bulk:
|
||||
lea (%rsp),$key_ # use $key_ as frame pointer
|
||||
.cfi_def_cfa_register $key_
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
sub \$$frame_size,%rsp
|
||||
and \$-16,%rsp # Linux kernel stack can be incorrectly seeded
|
||||
___
|
||||
@@ -1548,7 +1551,7 @@ $code.=<<___;
|
||||
sub \$8,$len
|
||||
jnc .Lctr32_loop8 # loop if $len-=8 didn't borrow
|
||||
|
||||
add \$8,$len # restore real remainig $len
|
||||
add \$8,$len # restore real remaining $len
|
||||
jz .Lctr32_done # done if ($len==0)
|
||||
lea -0x80($key),$key
|
||||
|
||||
@@ -1665,7 +1668,7 @@ $code.=<<___;
|
||||
movups $inout2,0x20($out) # $len was 3, stop store
|
||||
|
||||
.Lctr32_done:
|
||||
xorps %xmm0,%xmm0 # clear regiser bank
|
||||
xorps %xmm0,%xmm0 # clear register bank
|
||||
xor $key0,$key0
|
||||
pxor %xmm1,%xmm1
|
||||
pxor %xmm2,%xmm2
|
||||
@@ -1725,9 +1728,12 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -8($key_),%rbp
|
||||
.cfi_restore %rbp
|
||||
lea ($key_),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lctr32_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
|
||||
___
|
||||
}
|
||||
@@ -1749,8 +1755,11 @@ $code.=<<___;
|
||||
.type aesni_xts_encrypt,\@function,6
|
||||
.align 16
|
||||
aesni_xts_encrypt:
|
||||
.cfi_startproc
|
||||
lea (%rsp),%r11 # frame pointer
|
||||
.cfi_def_cfa_register %r11
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
sub \$$frame_size,%rsp
|
||||
and \$-16,%rsp # Linux kernel stack can be incorrectly seeded
|
||||
___
|
||||
@@ -1848,7 +1857,7 @@ $code.=<<___;
|
||||
lea `16*6`($inp),$inp
|
||||
pxor $twmask,$inout5
|
||||
|
||||
pxor $twres,@tweak[0] # calclulate tweaks^round[last]
|
||||
pxor $twres,@tweak[0] # calculate tweaks^round[last]
|
||||
aesenc $rndkey1,$inout4
|
||||
pxor $twres,@tweak[1]
|
||||
movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks^round[last]
|
||||
@@ -2215,9 +2224,12 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -8(%r11),%rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%r11),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lxts_enc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size aesni_xts_encrypt,.-aesni_xts_encrypt
|
||||
___
|
||||
|
||||
@@ -2226,8 +2238,11 @@ $code.=<<___;
|
||||
.type aesni_xts_decrypt,\@function,6
|
||||
.align 16
|
||||
aesni_xts_decrypt:
|
||||
.cfi_startproc
|
||||
lea (%rsp),%r11 # frame pointer
|
||||
.cfi_def_cfa_register %r11
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
sub \$$frame_size,%rsp
|
||||
and \$-16,%rsp # Linux kernel stack can be incorrectly seeded
|
||||
___
|
||||
@@ -2328,7 +2343,7 @@ $code.=<<___;
|
||||
lea `16*6`($inp),$inp
|
||||
pxor $twmask,$inout5
|
||||
|
||||
pxor $twres,@tweak[0] # calclulate tweaks^round[last]
|
||||
pxor $twres,@tweak[0] # calculate tweaks^round[last]
|
||||
aesdec $rndkey1,$inout4
|
||||
pxor $twres,@tweak[1]
|
||||
movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks^last round key
|
||||
@@ -2718,9 +2733,12 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -8(%r11),%rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%r11),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lxts_dec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size aesni_xts_decrypt,.-aesni_xts_decrypt
|
||||
___
|
||||
}
|
||||
@@ -2745,12 +2763,18 @@ $code.=<<___;
|
||||
.type aesni_ocb_encrypt,\@function,6
|
||||
.align 32
|
||||
aesni_ocb_encrypt:
|
||||
.cfi_startproc
|
||||
lea (%rsp),%rax
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0xa0(%rsp),%rsp
|
||||
@@ -2945,6 +2969,7 @@ $code.=<<___ if (!$win64);
|
||||
pxor %xmm14,%xmm14
|
||||
pxor %xmm15,%xmm15
|
||||
lea 0x28(%rsp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x00(%rsp),%xmm6
|
||||
@@ -2972,13 +2997,20 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -40(%rax),%r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax),%r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax),%r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov -8(%rax),%rbx
|
||||
.cfi_restore %rbx
|
||||
lea (%rax),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Locb_enc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size aesni_ocb_encrypt,.-aesni_ocb_encrypt
|
||||
|
||||
.type __ocb_encrypt6,\@abi-omnipotent
|
||||
@@ -3191,12 +3223,18 @@ __ocb_encrypt1:
|
||||
.type aesni_ocb_decrypt,\@function,6
|
||||
.align 32
|
||||
aesni_ocb_decrypt:
|
||||
.cfi_startproc
|
||||
lea (%rsp),%rax
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0xa0(%rsp),%rsp
|
||||
@@ -3413,6 +3451,7 @@ $code.=<<___ if (!$win64);
|
||||
pxor %xmm14,%xmm14
|
||||
pxor %xmm15,%xmm15
|
||||
lea 0x28(%rsp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x00(%rsp),%xmm6
|
||||
@@ -3440,13 +3479,20 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -40(%rax),%r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax),%r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax),%r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax),%rbp
|
||||
.cfi_restore %rbp
|
||||
mov -8(%rax),%rbx
|
||||
.cfi_restore %rbx
|
||||
lea (%rax),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Locb_dec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size aesni_ocb_decrypt,.-aesni_ocb_decrypt
|
||||
|
||||
.type __ocb_decrypt6,\@abi-omnipotent
|
||||
@@ -3659,6 +3705,7 @@ $code.=<<___;
|
||||
.type ${PREFIX}_cbc_encrypt,\@function,6
|
||||
.align 16
|
||||
${PREFIX}_cbc_encrypt:
|
||||
.cfi_startproc
|
||||
test $len,$len # check length
|
||||
jz .Lcbc_ret
|
||||
|
||||
@@ -3735,7 +3782,9 @@ $code.=<<___;
|
||||
.align 16
|
||||
.Lcbc_decrypt_bulk:
|
||||
lea (%rsp),%r11 # frame pointer
|
||||
.cfi_def_cfa_register %r11
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
sub \$$frame_size,%rsp
|
||||
and \$-16,%rsp # Linux kernel stack can be incorrectly seeded
|
||||
___
|
||||
@@ -4179,9 +4228,12 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -8(%r11),%rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%r11),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lcbc_ret:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
|
||||
___
|
||||
}
|
||||
@@ -4202,7 +4254,9 @@ $code.=<<___;
|
||||
.type ${PREFIX}_set_decrypt_key,\@abi-omnipotent
|
||||
.align 16
|
||||
${PREFIX}_set_decrypt_key:
|
||||
.cfi_startproc
|
||||
.byte 0x48,0x83,0xEC,0x08 # sub rsp,8
|
||||
.cfi_adjust_cfa_offset 8
|
||||
call __aesni_set_encrypt_key
|
||||
shl \$4,$bits # rounds-1 after _aesni_set_encrypt_key
|
||||
test %eax,%eax
|
||||
@@ -4235,15 +4289,16 @@ ${PREFIX}_set_decrypt_key:
|
||||
pxor %xmm0,%xmm0
|
||||
.Ldec_key_ret:
|
||||
add \$8,%rsp
|
||||
.cfi_adjust_cfa_offset -8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LSEH_end_set_decrypt_key:
|
||||
.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
|
||||
___
|
||||
|
||||
# This is based on submission by
|
||||
#
|
||||
# Huang Ying <ying.huang@intel.com>
|
||||
# Vinodh Gopal <vinodh.gopal@intel.com>
|
||||
# This is based on submission from Intel by
|
||||
# Huang Ying
|
||||
# Vinodh Gopal
|
||||
# Kahraman Akdemir
|
||||
#
|
||||
# Aggressively optimized in respect to aeskeygenassist's critical path
|
||||
@@ -4271,7 +4326,9 @@ $code.=<<___;
|
||||
.align 16
|
||||
${PREFIX}_set_encrypt_key:
|
||||
__aesni_set_encrypt_key:
|
||||
.cfi_startproc
|
||||
.byte 0x48,0x83,0xEC,0x08 # sub rsp,8
|
||||
.cfi_adjust_cfa_offset 8
|
||||
mov \$-1,%rax
|
||||
test $inp,$inp
|
||||
jz .Lenc_key_ret
|
||||
@@ -4461,7 +4518,7 @@ __aesni_set_encrypt_key:
|
||||
|
||||
.align 16
|
||||
.L14rounds:
|
||||
movups 16($inp),%xmm2 # remaning half of *userKey
|
||||
movups 16($inp),%xmm2 # remaining half of *userKey
|
||||
mov \$13,$bits # 14 rounds for 256
|
||||
lea 16(%rax),%rax
|
||||
cmp \$`1<<28`,%r10d # AVX, but no XOP
|
||||
@@ -4565,7 +4622,9 @@ __aesni_set_encrypt_key:
|
||||
pxor %xmm4,%xmm4
|
||||
pxor %xmm5,%xmm5
|
||||
add \$8,%rsp
|
||||
.cfi_adjust_cfa_offset -8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LSEH_end_set_encrypt_key:
|
||||
|
||||
.align 16
|
||||
|
||||
@@ -58,11 +58,7 @@ $code=<<___;
|
||||
#if __ARM_MAX_ARCH__>=7
|
||||
.text
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
|
||||
.arch armv8-a+crypto
|
||||
#endif
|
||||
___
|
||||
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
.arch armv7-a // don't confuse not-so-latest binutils with argv8 :-)
|
||||
.fpu neon
|
||||
@@ -933,7 +929,7 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
||||
s/^(\s+)v/$1/o or # strip off v prefix
|
||||
s/\bbx\s+lr\b/ret/o;
|
||||
|
||||
# fix up remainig legacy suffixes
|
||||
# fix up remaining legacy suffixes
|
||||
s/\.[ui]?8//o;
|
||||
m/\],#8/o and s/\.16b/\.8b/go;
|
||||
s/\.[ui]?32//o and s/\.16b/\.4s/go;
|
||||
@@ -992,7 +988,7 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
||||
s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go; # new->old registers
|
||||
s/\/\/\s?/@ /o; # new->old style commentary
|
||||
|
||||
# fix up remainig new-style suffixes
|
||||
# fix up remaining new-style suffixes
|
||||
s/\{q([0-9]+)\},\s*\[(.+)\],#8/sprintf "{d%d},[$2]!",2*$1/eo or
|
||||
s/\],#[0-9]+/]!/o;
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
#
|
||||
# Specific modes and adaptation for Linux kernel by Ard Biesheuvel
|
||||
# <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
|
||||
# granted.
|
||||
# of Linaro. Permission to use under GPL terms is granted.
|
||||
# ====================================================================
|
||||
|
||||
# Bit-sliced AES for ARM NEON
|
||||
@@ -49,10 +48,7 @@
|
||||
# <appro@openssl.org>
|
||||
|
||||
# April-August 2013
|
||||
#
|
||||
# Add CBC, CTR and XTS subroutines, adapt for kernel use.
|
||||
#
|
||||
# <ard.biesheuvel@linaro.org>
|
||||
# Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard.
|
||||
|
||||
$flavour = shift;
|
||||
if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
|
||||
@@ -744,9 +740,9 @@ $code.=<<___;
|
||||
.type _bsaes_decrypt8,%function
|
||||
.align 4
|
||||
_bsaes_decrypt8:
|
||||
adr $const,_bsaes_decrypt8
|
||||
adr $const,.
|
||||
vldmia $key!, {@XMM[9]} @ round 0 key
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $const,.LM0ISR
|
||||
#else
|
||||
add $const,$const,#.LM0ISR-_bsaes_decrypt8
|
||||
@@ -843,9 +839,9 @@ _bsaes_const:
|
||||
.type _bsaes_encrypt8,%function
|
||||
.align 4
|
||||
_bsaes_encrypt8:
|
||||
adr $const,_bsaes_encrypt8
|
||||
adr $const,.
|
||||
vldmia $key!, {@XMM[9]} @ round 0 key
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $const,.LM0SR
|
||||
#else
|
||||
sub $const,$const,#_bsaes_encrypt8-.LM0SR
|
||||
@@ -951,9 +947,9 @@ $code.=<<___;
|
||||
.type _bsaes_key_convert,%function
|
||||
.align 4
|
||||
_bsaes_key_convert:
|
||||
adr $const,_bsaes_key_convert
|
||||
adr $const,.
|
||||
vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key
|
||||
#ifdef __APPLE__
|
||||
#if defined(__thumb2__) || defined(__APPLE__)
|
||||
adr $const,.LM0
|
||||
#else
|
||||
sub $const,$const,#_bsaes_key_convert-.LM0
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
###################################################################
|
||||
### AES-128 [originally in CTR mode] ###
|
||||
@@ -1158,15 +1165,23 @@ $code.=<<___;
|
||||
.type bsaes_ecb_encrypt_blocks,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_ecb_encrypt_blocks:
|
||||
.cfi_startproc
|
||||
mov %rsp, %rax
|
||||
.Lecb_enc_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp),%rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0xa0(%rsp), %rsp
|
||||
@@ -1184,6 +1199,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rsp,%rbp # backup %rsp
|
||||
.cfi_def_cfa_register %rbp
|
||||
mov 240($arg4),%eax # rounds
|
||||
mov $arg1,$inp # backup arguments
|
||||
mov $arg2,$out
|
||||
@@ -1328,6 +1344,7 @@ $code.=<<___;
|
||||
jb .Lecb_enc_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -1345,29 +1362,45 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lecb_enc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
|
||||
|
||||
.globl bsaes_ecb_decrypt_blocks
|
||||
.type bsaes_ecb_decrypt_blocks,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_ecb_decrypt_blocks:
|
||||
.cfi_startproc
|
||||
mov %rsp, %rax
|
||||
.Lecb_dec_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp),%rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0xa0(%rsp), %rsp
|
||||
@@ -1385,6 +1418,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rsp,%rbp # backup %rsp
|
||||
.cfi_def_cfa_register %rbp
|
||||
mov 240($arg4),%eax # rounds
|
||||
mov $arg1,$inp # backup arguments
|
||||
mov $arg2,$out
|
||||
@@ -1530,6 +1564,7 @@ $code.=<<___;
|
||||
jb .Lecb_dec_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -1547,14 +1582,22 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lecb_dec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
|
||||
___
|
||||
}
|
||||
@@ -1564,6 +1607,7 @@ $code.=<<___;
|
||||
.type bsaes_cbc_encrypt,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_cbc_encrypt:
|
||||
.cfi_startproc
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
mov 48(%rsp),$arg6 # pull direction flag
|
||||
@@ -1577,12 +1621,19 @@ $code.=<<___;
|
||||
mov %rsp, %rax
|
||||
.Lcbc_dec_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp), %rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
mov 0xa0(%rsp),$arg5 # pull ivp
|
||||
@@ -1601,6 +1652,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rsp, %rbp # backup %rsp
|
||||
.cfi_def_cfa_register %rbp
|
||||
mov 240($arg4), %eax # rounds
|
||||
mov $arg1, $inp # backup arguments
|
||||
mov $arg2, $out
|
||||
@@ -1820,6 +1872,7 @@ $code.=<<___;
|
||||
ja .Lcbc_dec_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -1837,29 +1890,45 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lcbc_dec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
|
||||
|
||||
.globl bsaes_ctr32_encrypt_blocks
|
||||
.type bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_ctr32_encrypt_blocks:
|
||||
.cfi_startproc
|
||||
mov %rsp, %rax
|
||||
.Lctr_enc_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp), %rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
mov 0xa0(%rsp),$arg5 # pull ivp
|
||||
@@ -1878,6 +1947,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rsp, %rbp # backup %rsp
|
||||
.cfi_def_cfa_register %rbp
|
||||
movdqu ($arg5), %xmm0 # load counter
|
||||
mov 240($arg4), %eax # rounds
|
||||
mov $arg1, $inp # backup arguments
|
||||
@@ -2052,6 +2122,7 @@ $code.=<<___;
|
||||
ja .Lctr_enc_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -2069,14 +2140,22 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lctr_enc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
|
||||
___
|
||||
######################################################################
|
||||
@@ -2092,15 +2171,23 @@ $code.=<<___;
|
||||
.type bsaes_xts_encrypt,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_xts_encrypt:
|
||||
.cfi_startproc
|
||||
mov %rsp, %rax
|
||||
.Lxts_enc_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp), %rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
mov 0xa0(%rsp),$arg5 # pull key2
|
||||
@@ -2120,6 +2207,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rsp, %rbp # backup %rsp
|
||||
.cfi_def_cfa_register %rbp
|
||||
mov $arg1, $inp # backup arguments
|
||||
mov $arg2, $out
|
||||
mov $arg3, $len
|
||||
@@ -2442,6 +2530,7 @@ $code.=<<___;
|
||||
ja .Lxts_enc_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -2459,29 +2548,45 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lxts_enc_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
|
||||
|
||||
.globl bsaes_xts_decrypt
|
||||
.type bsaes_xts_decrypt,\@abi-omnipotent
|
||||
.align 16
|
||||
bsaes_xts_decrypt:
|
||||
.cfi_startproc
|
||||
mov %rsp, %rax
|
||||
.Lxts_dec_prologue:
|
||||
push %rbp
|
||||
.cfi_push %rbp
|
||||
push %rbx
|
||||
.cfi_push %rbx
|
||||
push %r12
|
||||
.cfi_push %r12
|
||||
push %r13
|
||||
.cfi_push %r13
|
||||
push %r14
|
||||
.cfi_push %r14
|
||||
push %r15
|
||||
.cfi_push %r15
|
||||
lea -0x48(%rsp), %rsp
|
||||
.cfi_adjust_cfa_offset 0x48
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
mov 0xa0(%rsp),$arg5 # pull key2
|
||||
@@ -2849,6 +2954,7 @@ $code.=<<___;
|
||||
ja .Lxts_dec_bzero
|
||||
|
||||
lea 0x78(%rbp),%rax
|
||||
.cfi_def_cfa %rax,8
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 0x40(%rbp), %xmm6
|
||||
@@ -2866,14 +2972,22 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
mov -48(%rax), %r15
|
||||
.cfi_restore %r15
|
||||
mov -40(%rax), %r14
|
||||
.cfi_restore %r14
|
||||
mov -32(%rax), %r13
|
||||
.cfi_restore %r13
|
||||
mov -24(%rax), %r12
|
||||
.cfi_restore %r12
|
||||
mov -16(%rax), %rbx
|
||||
.cfi_restore %rbx
|
||||
mov -8(%rax), %rbp
|
||||
.cfi_restore %rbp
|
||||
lea (%rax), %rsp # restore %rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.Lxts_dec_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
|
||||
___
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
######################################################################
|
||||
## Constant-time SSSE3 AES core implementation.
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
######################################################################
|
||||
## Constant-time SSSE3 AES core implementation.
|
||||
|
||||
+11
-542
@@ -16,21 +16,15 @@
|
||||
#define _GNU_SOURCE // needed for syscall() on Linux.
|
||||
#endif
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/base.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/ec_key.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/nid.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "rand/internal.h"
|
||||
|
||||
#include "aes/aes.c"
|
||||
#include "aes/key_wrap.c"
|
||||
@@ -67,15 +61,16 @@
|
||||
#include "ec/ec_montgomery.c"
|
||||
#include "ec/oct.c"
|
||||
#include "ec/p224-64.c"
|
||||
#include "ec/p256-64.c"
|
||||
#include "../../third_party/fiat/p256.c"
|
||||
#include "ec/p256-x86_64.c"
|
||||
#include "ec/simple.c"
|
||||
#include "ec/util-64.c"
|
||||
#include "ec/util.c"
|
||||
#include "ec/wnaf.c"
|
||||
#include "hmac/hmac.c"
|
||||
#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"
|
||||
@@ -88,205 +83,16 @@
|
||||
#include "rsa/padding.c"
|
||||
#include "rsa/rsa.c"
|
||||
#include "rsa/rsa_impl.c"
|
||||
#include "self_check/self_check.c"
|
||||
#include "sha/sha1-altivec.c"
|
||||
#include "sha/sha1.c"
|
||||
#include "sha/sha256.c"
|
||||
#include "sha/sha512.c"
|
||||
#include "tls/kdf.c"
|
||||
|
||||
|
||||
#if defined(BORINGSSL_FIPS)
|
||||
|
||||
static void hexdump(const uint8_t *in, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
printf("%02x", in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int check_test(const void *expected, const void *actual,
|
||||
size_t expected_len, const char *name) {
|
||||
if (OPENSSL_memcmp(actual, expected, expected_len) != 0) {
|
||||
printf("%s failed.\nExpected: ", name);
|
||||
hexdump(expected, expected_len);
|
||||
printf("\nCalculated: ");
|
||||
hexdump(actual, expected_len);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) {
|
||||
*out = BN_bin2bn(in, len, NULL);
|
||||
return *out != NULL;
|
||||
}
|
||||
|
||||
static RSA *self_test_rsa_key(void) {
|
||||
static const uint8_t kN[] = {
|
||||
0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc,
|
||||
0xc9, 0xa2, 0xc2, 0x3a, 0xa6, 0x1d, 0xd8, 0xf0, 0x26, 0x5b, 0x38, 0x90,
|
||||
0x17, 0x48, 0x15, 0xce, 0x21, 0xcd, 0xd6, 0x62, 0x99, 0xe2, 0xd7, 0xda,
|
||||
0x40, 0x80, 0x3c, 0xad, 0x18, 0xb7, 0x26, 0xe9, 0x30, 0x8a, 0x23, 0x3f,
|
||||
0x68, 0x9a, 0x9c, 0x31, 0x34, 0x91, 0x99, 0x06, 0x11, 0x36, 0xb2, 0x9e,
|
||||
0x3a, 0xd0, 0xbc, 0xb9, 0x93, 0x4e, 0xb8, 0x72, 0xa1, 0x9f, 0xb6, 0x8c,
|
||||
0xd5, 0x17, 0x1f, 0x7e, 0xaa, 0x75, 0xbb, 0xdf, 0xa1, 0x70, 0x48, 0xc4,
|
||||
0xec, 0x9a, 0x51, 0xed, 0x41, 0xc9, 0x74, 0xc0, 0x3e, 0x1e, 0x85, 0x2f,
|
||||
0xbe, 0x34, 0xc7, 0x65, 0x34, 0x8b, 0x4d, 0x55, 0x4b, 0xe1, 0x45, 0x54,
|
||||
0x0d, 0x75, 0x7e, 0x89, 0x4d, 0x0c, 0xf6, 0x33, 0xe5, 0xfc, 0xfb, 0x56,
|
||||
0x1b, 0xf2, 0x39, 0x9d, 0xe0, 0xff, 0x55, 0xcf, 0x02, 0x05, 0xb9, 0x74,
|
||||
0xd2, 0x91, 0xfc, 0x87, 0xe1, 0xbb, 0x97, 0x2a, 0xe4, 0xdd, 0x20, 0xc0,
|
||||
0x38, 0x47, 0xc0, 0x76, 0x3f, 0xa1, 0x9b, 0x5c, 0x20, 0xff, 0xff, 0xc7,
|
||||
0x49, 0x3b, 0x4c, 0xaf, 0x99, 0xa6, 0x3e, 0x82, 0x5c, 0x58, 0x27, 0xce,
|
||||
0x01, 0x03, 0xc3, 0x16, 0x35, 0x20, 0xe9, 0xf0, 0x15, 0x7a, 0x41, 0xd5,
|
||||
0x1f, 0x52, 0xea, 0xdf, 0xad, 0x4c, 0xbb, 0x0d, 0xcb, 0x04, 0x91, 0xb0,
|
||||
0x95, 0xa8, 0xce, 0x25, 0xfd, 0xd2, 0x62, 0x47, 0x77, 0xee, 0x13, 0xf1,
|
||||
0x48, 0x72, 0x9e, 0xd9, 0x2d, 0xe6, 0x5f, 0xa4, 0xc6, 0x9e, 0x5a, 0xb2,
|
||||
0xc6, 0xa2, 0xf7, 0x0a, 0x16, 0x17, 0xae, 0x6b, 0x1c, 0x30, 0x7c, 0x63,
|
||||
0x08, 0x83, 0xe7, 0x43, 0xec, 0x54, 0x5e, 0x2c, 0x08, 0x0b, 0x5e, 0x46,
|
||||
0xa7, 0x10, 0x93, 0x43, 0x53, 0x4e, 0xe3, 0x16, 0x73, 0x55, 0xce, 0xf2,
|
||||
0x94, 0xc0, 0xbe, 0xb3,
|
||||
};
|
||||
static const uint8_t kE[] = {0x01, 0x00, 0x01}; // 65537
|
||||
static const uint8_t kD[] = {
|
||||
0x2f, 0x2c, 0x1e, 0xd2, 0x3d, 0x2c, 0xb1, 0x9b, 0x21, 0x02, 0xce, 0xb8,
|
||||
0x95, 0x5f, 0x4f, 0xd9, 0x21, 0x38, 0x11, 0x36, 0xb0, 0x9a, 0x36, 0xab,
|
||||
0x97, 0x47, 0x75, 0xf7, 0x2e, 0xfd, 0x75, 0x1f, 0x58, 0x16, 0x9c, 0xf6,
|
||||
0x14, 0xe9, 0x8e, 0xa3, 0x69, 0x9d, 0x9d, 0x86, 0xfe, 0x5c, 0x1b, 0x3b,
|
||||
0x11, 0xf5, 0x55, 0x64, 0x77, 0xc4, 0xfc, 0x53, 0xaa, 0x8c, 0x78, 0x9f,
|
||||
0x75, 0xab, 0x20, 0x3a, 0xa1, 0x77, 0x37, 0x22, 0x02, 0x8e, 0x54, 0x8a,
|
||||
0x67, 0x1c, 0x5e, 0xe0, 0x3e, 0xd9, 0x44, 0x37, 0xd1, 0x29, 0xee, 0x56,
|
||||
0x6c, 0x30, 0x9a, 0x93, 0x4d, 0xd9, 0xdb, 0xc5, 0x03, 0x1a, 0x75, 0xcc,
|
||||
0x0f, 0xc2, 0x61, 0xb5, 0x6c, 0x62, 0x9f, 0xc6, 0xa8, 0xc7, 0x8a, 0x60,
|
||||
0x17, 0x11, 0x62, 0x4c, 0xef, 0x74, 0x31, 0x97, 0xad, 0x89, 0x2d, 0xe8,
|
||||
0x31, 0x1d, 0x8b, 0x58, 0x82, 0xe3, 0x03, 0x1a, 0x6b, 0xdf, 0x3f, 0x3e,
|
||||
0xa4, 0x27, 0x19, 0xef, 0x46, 0x7a, 0x90, 0xdf, 0xa7, 0xe7, 0xc9, 0x66,
|
||||
0xab, 0x41, 0x1d, 0x65, 0x78, 0x1c, 0x18, 0x40, 0x5c, 0xd6, 0x87, 0xb5,
|
||||
0xea, 0x29, 0x44, 0xb3, 0xf5, 0xb3, 0xd2, 0x4f, 0xce, 0x88, 0x78, 0x49,
|
||||
0x27, 0x4e, 0x0b, 0x30, 0x85, 0xfb, 0x73, 0xfd, 0x8b, 0x32, 0x15, 0xee,
|
||||
0x1f, 0xc9, 0x0e, 0x89, 0xb9, 0x43, 0x2f, 0xe9, 0x60, 0x8d, 0xda, 0xae,
|
||||
0x2b, 0x30, 0x99, 0xee, 0x88, 0x81, 0x20, 0x7b, 0x4a, 0xc3, 0x18, 0xf2,
|
||||
0x94, 0x02, 0x79, 0x94, 0xaa, 0x65, 0xd9, 0x1b, 0x45, 0x2a, 0xac, 0x6e,
|
||||
0x30, 0x48, 0x57, 0xea, 0xbe, 0x79, 0x7d, 0xfc, 0x67, 0xaa, 0x47, 0xc0,
|
||||
0xf7, 0x52, 0xfd, 0x0b, 0x63, 0x4e, 0x3d, 0x2e, 0xcc, 0x36, 0xa0, 0xdb,
|
||||
0x92, 0x0b, 0xa9, 0x1b, 0xeb, 0xc2, 0xd5, 0x08, 0xd3, 0x85, 0x87, 0xf8,
|
||||
0x5d, 0x1a, 0xf6, 0xc1,
|
||||
};
|
||||
static const uint8_t kP[] = {
|
||||
0xf7, 0x06, 0xa3, 0x98, 0x8a, 0x52, 0xf8, 0x63, 0x68, 0x27, 0x4f, 0x68,
|
||||
0x7f, 0x34, 0xec, 0x8e, 0x5d, 0xf8, 0x30, 0x92, 0xb3, 0x62, 0x4c, 0xeb,
|
||||
0xdb, 0x19, 0x6b, 0x09, 0xc5, 0xa3, 0xf0, 0xbb, 0xff, 0x0f, 0xc2, 0xd4,
|
||||
0x9b, 0xc9, 0x54, 0x4f, 0xb9, 0xf9, 0xe1, 0x4c, 0xf0, 0xe3, 0x4c, 0x90,
|
||||
0xda, 0x7a, 0x01, 0xc2, 0x9f, 0xc4, 0xc8, 0x8e, 0xb1, 0x1e, 0x93, 0x75,
|
||||
0x75, 0xc6, 0x13, 0x25, 0xc3, 0xee, 0x3b, 0xcc, 0xb8, 0x72, 0x6c, 0x49,
|
||||
0xb0, 0x09, 0xfb, 0xab, 0x44, 0xeb, 0x4d, 0x40, 0xf0, 0x61, 0x6b, 0xe5,
|
||||
0xe6, 0xfe, 0x3e, 0x0a, 0x77, 0x26, 0x39, 0x76, 0x3d, 0x4c, 0x3e, 0x9b,
|
||||
0x5b, 0xc0, 0xaf, 0xa2, 0x58, 0x76, 0xb0, 0xe9, 0xda, 0x7f, 0x0e, 0x78,
|
||||
0xc9, 0x76, 0x49, 0x5c, 0xfa, 0xb3, 0xb0, 0x15, 0x4b, 0x41, 0xc7, 0x27,
|
||||
0xa4, 0x75, 0x28, 0x5c, 0x30, 0x69, 0x50, 0x29,
|
||||
};
|
||||
static const uint8_t kQ[] = {
|
||||
0xda, 0xe6, 0xd2, 0xbb, 0x44, 0xff, 0x4f, 0xdf, 0x57, 0xc1, 0x11, 0xa3,
|
||||
0x51, 0xba, 0x17, 0x89, 0x4c, 0x01, 0xc0, 0x0c, 0x97, 0x34, 0x50, 0xcf,
|
||||
0x32, 0x1e, 0xc0, 0xbd, 0x7b, 0x35, 0xb5, 0x6a, 0x26, 0xcc, 0xea, 0x4c,
|
||||
0x8e, 0x87, 0x4a, 0x67, 0x8b, 0xd3, 0xe5, 0x4f, 0x3a, 0x60, 0x48, 0x59,
|
||||
0x04, 0x93, 0x39, 0xd7, 0x7c, 0xfb, 0x19, 0x1a, 0x34, 0xd5, 0xe8, 0xaf,
|
||||
0xe7, 0x22, 0x2c, 0x0d, 0xc2, 0x91, 0x69, 0xb6, 0xe9, 0x2a, 0xe9, 0x1c,
|
||||
0x4c, 0x6e, 0x8f, 0x40, 0xf5, 0xa8, 0x3e, 0x82, 0x69, 0x69, 0xbe, 0x9f,
|
||||
0x7d, 0x5c, 0x7f, 0x92, 0x78, 0x17, 0xa3, 0x6d, 0x41, 0x2d, 0x72, 0xed,
|
||||
0x3f, 0x71, 0xfa, 0x97, 0xb4, 0x63, 0xe4, 0x4f, 0xd9, 0x46, 0x03, 0xfb,
|
||||
0x00, 0xeb, 0x30, 0x70, 0xb9, 0x51, 0xd9, 0x0a, 0xd2, 0xf8, 0x50, 0xd4,
|
||||
0xfb, 0x43, 0x84, 0xf8, 0xac, 0x58, 0xc3, 0x7b,
|
||||
};
|
||||
static const uint8_t kDModPMinusOne[] = {
|
||||
0xf5, 0x50, 0x8f, 0x88, 0x7d, 0xdd, 0xb5, 0xb4, 0x2a, 0x8b, 0xd7, 0x4d,
|
||||
0x23, 0xfe, 0xaf, 0xe9, 0x16, 0x22, 0xd2, 0x41, 0xed, 0x88, 0xf2, 0x70,
|
||||
0xcb, 0x4d, 0xeb, 0xc1, 0x71, 0x97, 0xc4, 0x0b, 0x3e, 0x5a, 0x2d, 0x96,
|
||||
0xab, 0xfa, 0xfd, 0x12, 0x8b, 0xd3, 0x3e, 0x4e, 0x05, 0x6f, 0x04, 0xeb,
|
||||
0x59, 0x3c, 0x0e, 0xa1, 0x73, 0xbe, 0x9d, 0x99, 0x2f, 0x05, 0xf9, 0x54,
|
||||
0x8d, 0x98, 0x1e, 0x0d, 0xc4, 0x0c, 0xc3, 0x30, 0x23, 0xff, 0xe5, 0xd0,
|
||||
0x2b, 0xd5, 0x4e, 0x2b, 0xa0, 0xae, 0xb8, 0x32, 0x84, 0x45, 0x8b, 0x3c,
|
||||
0x6d, 0xf0, 0x10, 0x36, 0x9e, 0x6a, 0xc4, 0x67, 0xca, 0xa9, 0xfc, 0x06,
|
||||
0x96, 0xd0, 0xbc, 0xda, 0xd1, 0x55, 0x55, 0x8d, 0x77, 0x21, 0xf4, 0x82,
|
||||
0x39, 0x37, 0x91, 0xd5, 0x97, 0x56, 0x78, 0xc8, 0x3c, 0xcb, 0x5e, 0xf6,
|
||||
0xdc, 0x58, 0x48, 0xb3, 0x7c, 0x94, 0x29, 0x39,
|
||||
};
|
||||
static const uint8_t kDModQMinusOne[] = {
|
||||
0x64, 0x65, 0xbd, 0x7d, 0x1a, 0x96, 0x26, 0xa1, 0xfe, 0xf3, 0x94, 0x0d,
|
||||
0x5d, 0xec, 0x85, 0xe2, 0xf8, 0xb3, 0x4c, 0xcb, 0xf9, 0x85, 0x8b, 0x12,
|
||||
0x9c, 0xa0, 0x32, 0x32, 0x35, 0x92, 0x5a, 0x94, 0x47, 0x1b, 0x70, 0xd2,
|
||||
0x90, 0x04, 0x49, 0x01, 0xd8, 0xc5, 0xe4, 0xc4, 0x43, 0xb7, 0xe9, 0x36,
|
||||
0xba, 0xbc, 0x73, 0xa8, 0xfb, 0xaf, 0x86, 0xc1, 0xd8, 0x3d, 0xcb, 0xac,
|
||||
0xf1, 0xcb, 0x60, 0x7d, 0x27, 0x21, 0xde, 0x64, 0x7f, 0xe8, 0xa8, 0x65,
|
||||
0xcc, 0x40, 0x60, 0xff, 0xa0, 0x2b, 0xfc, 0x0f, 0x80, 0x1d, 0x79, 0xca,
|
||||
0x58, 0x8a, 0xd6, 0x0f, 0xed, 0x78, 0x9a, 0x02, 0x00, 0x04, 0xc2, 0x53,
|
||||
0x41, 0xe8, 0x1a, 0xd0, 0xfd, 0x71, 0x5b, 0x43, 0xac, 0x19, 0x4a, 0xb6,
|
||||
0x12, 0xa3, 0xcb, 0xe1, 0xc7, 0x7d, 0x5c, 0x98, 0x74, 0x4e, 0x63, 0x74,
|
||||
0x6b, 0x91, 0x7a, 0x29, 0x3b, 0x92, 0xb2, 0x85,
|
||||
};
|
||||
static const uint8_t kQInverseModP[] = {
|
||||
0xd0, 0xde, 0x19, 0xda, 0x1e, 0xa2, 0xd8, 0x8f, 0x1c, 0x92, 0x73, 0xb0,
|
||||
0xc9, 0x90, 0xc7, 0xf5, 0xec, 0xc5, 0x89, 0x01, 0x05, 0x78, 0x11, 0x2d,
|
||||
0x74, 0x34, 0x44, 0xad, 0xd5, 0xf7, 0xa4, 0xfe, 0x9f, 0x25, 0x4d, 0x0b,
|
||||
0x92, 0xe3, 0xb8, 0x7d, 0xd3, 0xfd, 0xa5, 0xca, 0x95, 0x60, 0xa3, 0xf9,
|
||||
0x55, 0x42, 0x14, 0xb2, 0x45, 0x51, 0x9f, 0x73, 0x88, 0x43, 0x8a, 0xd1,
|
||||
0x65, 0x9e, 0xd1, 0xf7, 0x82, 0x2a, 0x2a, 0x8d, 0x70, 0x56, 0xe3, 0xef,
|
||||
0xc9, 0x0e, 0x2a, 0x2c, 0x15, 0xaf, 0x7f, 0x97, 0x81, 0x66, 0xf3, 0xb5,
|
||||
0x00, 0xa9, 0x26, 0xcc, 0x1e, 0xc2, 0x98, 0xdd, 0xd3, 0x37, 0x06, 0x79,
|
||||
0xb3, 0x60, 0x58, 0x79, 0x99, 0x3f, 0xa3, 0x15, 0x1f, 0x31, 0xe3, 0x11,
|
||||
0x88, 0x4c, 0x35, 0x57, 0xfa, 0x79, 0xd7, 0xd8, 0x72, 0xee, 0x73, 0x95,
|
||||
0x89, 0x29, 0xc7, 0x05, 0x27, 0x68, 0x90, 0x15,
|
||||
};
|
||||
|
||||
RSA *rsa = RSA_new();
|
||||
if (rsa == NULL ||
|
||||
!set_bignum(&rsa->n, kN, sizeof(kN)) ||
|
||||
!set_bignum(&rsa->e, kE, sizeof(kE)) ||
|
||||
!set_bignum(&rsa->d, kD, sizeof(kD)) ||
|
||||
!set_bignum(&rsa->p, kP, sizeof(kP)) ||
|
||||
!set_bignum(&rsa->q, kQ, sizeof(kQ)) ||
|
||||
!set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) ||
|
||||
!set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) ||
|
||||
!set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) {
|
||||
RSA_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rsa;
|
||||
}
|
||||
|
||||
static EC_KEY *self_test_ecdsa_key(void) {
|
||||
static const uint8_t kQx[] = {
|
||||
0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17,
|
||||
0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2,
|
||||
0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81,
|
||||
};
|
||||
static const uint8_t kQy[] = {
|
||||
0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef,
|
||||
0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac,
|
||||
0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88,
|
||||
};
|
||||
static const uint8_t kD[] = {
|
||||
0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c,
|
||||
0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0,
|
||||
0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
|
||||
};
|
||||
|
||||
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL);
|
||||
BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL);
|
||||
BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL);
|
||||
if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL ||
|
||||
!EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) ||
|
||||
!EC_KEY_set_private_key(ec_key, d)) {
|
||||
EC_KEY_free(ec_key);
|
||||
ec_key = NULL;
|
||||
}
|
||||
|
||||
BN_free(qx);
|
||||
BN_free(qy);
|
||||
BN_free(d);
|
||||
return ec_key;
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_ASAN)
|
||||
// These symbols are filled in by delocate.go. They point to the start and end
|
||||
// of the module, and the location of the integrity hash, respectively.
|
||||
@@ -322,345 +128,7 @@ BORINGSSL_bcm_power_on_self_test(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static const uint8_t kAESKey[16] = "BoringCrypto Key";
|
||||
static const uint8_t kAESIV[16] = {0};
|
||||
static const uint8_t kPlaintext[64] =
|
||||
"BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!";
|
||||
static const uint8_t kAESCBCCiphertext[64] = {
|
||||
0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b,
|
||||
0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c,
|
||||
0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45,
|
||||
0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad,
|
||||
0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55,
|
||||
0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_AES_CBC)
|
||||
0x35
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const uint8_t kAESGCMCiphertext[80] = {
|
||||
0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9,
|
||||
0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82,
|
||||
0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa,
|
||||
0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4,
|
||||
0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33,
|
||||
0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61,
|
||||
0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_AES_GCM)
|
||||
0x0d
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const DES_cblock kDESKey1 = {"BCMDESK1"};
|
||||
static const DES_cblock kDESKey2 = {"BCMDESK2"};
|
||||
static const DES_cblock kDESKey3 = {"BCMDESK3"};
|
||||
static const DES_cblock kDESIV = {"BCMDESIV"};
|
||||
static const uint8_t kDESCiphertext[64] = {
|
||||
0xa4, 0x30, 0x7a, 0x4c, 0x1f, 0x60, 0x16, 0xd7, 0x4f, 0x41, 0xe1,
|
||||
0xbb, 0x27, 0xc4, 0x27, 0x37, 0xd4, 0x7f, 0xb9, 0x10, 0xf8, 0xbc,
|
||||
0xaf, 0x93, 0x91, 0xb8, 0x88, 0x24, 0xb1, 0xf6, 0xf8, 0xbd, 0x31,
|
||||
0x96, 0x06, 0x76, 0xde, 0x32, 0xcd, 0x29, 0x29, 0xba, 0x70, 0x5f,
|
||||
0xea, 0xc0, 0xcb, 0xde, 0xc7, 0x75, 0x90, 0xe0, 0x0f, 0x5e, 0x2c,
|
||||
0x0d, 0x49, 0x20, 0xd5, 0x30, 0x83, 0xf8, 0x08,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_DES)
|
||||
0x5a
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const uint8_t kPlaintextSHA1[20] = {
|
||||
0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd,
|
||||
0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_SHA_1)
|
||||
0x28
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const uint8_t kPlaintextSHA256[32] = {
|
||||
0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb,
|
||||
0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb,
|
||||
0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_SHA_256)
|
||||
0x0f
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const uint8_t kPlaintextSHA512[64] = {
|
||||
0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e,
|
||||
0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74,
|
||||
0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c,
|
||||
0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c,
|
||||
0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b,
|
||||
0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_SHA_512)
|
||||
0x14
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
static const uint8_t kRSASignature[256] = {
|
||||
0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33,
|
||||
0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d,
|
||||
0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5,
|
||||
0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6,
|
||||
0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9,
|
||||
0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63,
|
||||
0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29,
|
||||
0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff,
|
||||
0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68,
|
||||
0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8,
|
||||
0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14,
|
||||
0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9,
|
||||
0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3,
|
||||
0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a,
|
||||
0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4,
|
||||
0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5,
|
||||
0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae,
|
||||
0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e,
|
||||
0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b,
|
||||
0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf,
|
||||
0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d,
|
||||
0xd2, 0x0c, 0xb1,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG)
|
||||
0x64
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
const uint8_t kDRBGEntropy[48] =
|
||||
"BCM Known Answer Test DBRG Initial Entropy ";
|
||||
const uint8_t kDRBGPersonalization[18] = "BCMPersonalization";
|
||||
const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD ";
|
||||
const uint8_t kDRBGOutput[64] = {
|
||||
0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5,
|
||||
0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1,
|
||||
0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9,
|
||||
0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32,
|
||||
0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d,
|
||||
0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_DRBG)
|
||||
0x95
|
||||
#else
|
||||
0x00
|
||||
#endif
|
||||
};
|
||||
const uint8_t kDRBGEntropy2[48] =
|
||||
"BCM Known Answer Test DBRG Reseed Entropy ";
|
||||
const uint8_t kDRBGReseedOutput[64] = {
|
||||
0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8,
|
||||
0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2,
|
||||
0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6,
|
||||
0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e,
|
||||
0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b,
|
||||
0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4,
|
||||
};
|
||||
const uint8_t kECDSASigR[32] = {
|
||||
0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0,
|
||||
0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02,
|
||||
0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5,
|
||||
#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG)
|
||||
0x0c,
|
||||
#else
|
||||
0x00,
|
||||
#endif
|
||||
};
|
||||
const uint8_t kECDSASigS[32] = {
|
||||
0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6,
|
||||
0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a,
|
||||
0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8,
|
||||
};
|
||||
|
||||
AES_KEY aes_key;
|
||||
uint8_t aes_iv[16];
|
||||
uint8_t output[256];
|
||||
|
||||
// AES-CBC Encryption KAT
|
||||
memcpy(aes_iv, kAESIV, sizeof(kAESIV));
|
||||
if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
|
||||
goto err;
|
||||
}
|
||||
AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv,
|
||||
AES_ENCRYPT);
|
||||
if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext),
|
||||
"AES-CBC Encryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// AES-CBC Decryption KAT
|
||||
memcpy(aes_iv, kAESIV, sizeof(kAESIV));
|
||||
if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
|
||||
goto err;
|
||||
}
|
||||
AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext),
|
||||
&aes_key, aes_iv, AES_DECRYPT);
|
||||
if (!check_test(kPlaintext, output, sizeof(kPlaintext),
|
||||
"AES-CBC Decryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
size_t out_len;
|
||||
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
|
||||
OPENSSL_memset(nonce, 0, sizeof(nonce));
|
||||
EVP_AEAD_CTX aead_ctx;
|
||||
if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey,
|
||||
sizeof(kAESKey), 0, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// AES-GCM Encryption KAT
|
||||
if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce,
|
||||
EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
|
||||
kPlaintext, sizeof(kPlaintext), NULL, 0) ||
|
||||
!check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext),
|
||||
"AES-GCM Encryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// AES-GCM Decryption KAT
|
||||
if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce,
|
||||
EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
|
||||
kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL,
|
||||
0) ||
|
||||
!check_test(kPlaintext, output, sizeof(kPlaintext),
|
||||
"AES-GCM Decryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_AEAD_CTX_cleanup(&aead_ctx);
|
||||
|
||||
DES_key_schedule des1, des2, des3;
|
||||
DES_cblock des_iv;
|
||||
DES_set_key(&kDESKey1, &des1);
|
||||
DES_set_key(&kDESKey2, &des2);
|
||||
DES_set_key(&kDESKey3, &des3);
|
||||
|
||||
// 3DES Encryption KAT
|
||||
memcpy(&des_iv, &kDESIV, sizeof(des_iv));
|
||||
DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2,
|
||||
&des3, &des_iv, DES_ENCRYPT);
|
||||
if (!check_test(kDESCiphertext, output, sizeof(kDESCiphertext),
|
||||
"3DES Encryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// 3DES Decryption KAT
|
||||
memcpy(&des_iv, &kDESIV, sizeof(des_iv));
|
||||
DES_ede3_cbc_encrypt(kDESCiphertext, output, sizeof(kDESCiphertext), &des1,
|
||||
&des2, &des3, &des_iv, DES_DECRYPT);
|
||||
if (!check_test(kPlaintext, output, sizeof(kPlaintext),
|
||||
"3DES Decryption KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// SHA-1 KAT
|
||||
SHA1(kPlaintext, sizeof(kPlaintext), output);
|
||||
if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1),
|
||||
"SHA-1 KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// SHA-256 KAT
|
||||
SHA256(kPlaintext, sizeof(kPlaintext), output);
|
||||
if (!check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256),
|
||||
"SHA-256 KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// SHA-512 KAT
|
||||
SHA512(kPlaintext, sizeof(kPlaintext), output);
|
||||
if (!check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512),
|
||||
"SHA-512 KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
RSA *rsa_key = self_test_rsa_key();
|
||||
if (rsa_key == NULL) {
|
||||
printf("RSA KeyGen failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// RSA Sign KAT
|
||||
unsigned sig_len;
|
||||
|
||||
// Disable blinding for the power-on tests because it's not needed and
|
||||
// triggers an entropy draw.
|
||||
rsa_key->flags |= RSA_FLAG_NO_BLINDING;
|
||||
|
||||
if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output,
|
||||
&sig_len, rsa_key) ||
|
||||
!check_test(kRSASignature, output, sizeof(kRSASignature),
|
||||
"RSA Sign KAT")) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// RSA Verify KAT
|
||||
if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256),
|
||||
kRSASignature, sizeof(kRSASignature), rsa_key)) {
|
||||
printf("RSA Verify KAT failed.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
RSA_free(rsa_key);
|
||||
|
||||
EC_KEY *ec_key = self_test_ecdsa_key();
|
||||
if (ec_key == NULL) {
|
||||
printf("ECDSA KeyGen failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// ECDSA Sign/Verify PWCT
|
||||
|
||||
// The 'k' value for ECDSA is fixed to avoid an entropy draw.
|
||||
ec_key->fixed_k = BN_new();
|
||||
if (ec_key->fixed_k == NULL ||
|
||||
!BN_set_word(ec_key->fixed_k, 42)) {
|
||||
printf("Out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ECDSA_SIG *sig =
|
||||
ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key);
|
||||
|
||||
uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)];
|
||||
uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)];
|
||||
if (sig == NULL ||
|
||||
BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) ||
|
||||
!BN_bn2bin(sig->r, ecdsa_r_bytes) ||
|
||||
BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) ||
|
||||
!BN_bn2bin(sig->s, ecdsa_s_bytes) ||
|
||||
!check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") ||
|
||||
!check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) {
|
||||
printf("ECDSA KAT failed.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ECDSA_SIG_free(sig);
|
||||
EC_KEY_free(ec_key);
|
||||
|
||||
// DBRG KAT
|
||||
CTR_DRBG_STATE drbg;
|
||||
if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization,
|
||||
sizeof(kDRBGPersonalization)) ||
|
||||
!CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD,
|
||||
sizeof(kDRBGAD)) ||
|
||||
!check_test(kDRBGOutput, output, sizeof(kDRBGOutput),
|
||||
"DBRG Generate KAT") ||
|
||||
!CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) ||
|
||||
!CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD,
|
||||
sizeof(kDRBGAD)) ||
|
||||
!check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput),
|
||||
"DRBG Reseed KAT")) {
|
||||
goto err;
|
||||
}
|
||||
CTR_DRBG_clear(&drbg);
|
||||
|
||||
CTR_DRBG_STATE kZeroDRBG;
|
||||
memset(&kZeroDRBG, 0, sizeof(kZeroDRBG));
|
||||
if (!check_test(&kZeroDRBG, &drbg, sizeof(drbg), "DRBG Clear KAT")) {
|
||||
if (!BORINGSSL_self_test()) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -676,4 +144,5 @@ void BORINGSSL_FIPS_abort(void) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BORINGSSL_FIPS
|
||||
|
||||
+38
-73
@@ -100,61 +100,38 @@ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
int max, min, dif;
|
||||
BN_ULONG *ap, *bp, *rp, carry, t1, t2;
|
||||
const BIGNUM *tmp;
|
||||
|
||||
if (a->top < b->top) {
|
||||
tmp = a;
|
||||
int bn_uadd_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
// Widths are public, so we normalize to make |a| the larger one.
|
||||
if (a->width < b->width) {
|
||||
const BIGNUM *tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
max = a->top;
|
||||
min = b->top;
|
||||
dif = max - min;
|
||||
|
||||
int max = a->width;
|
||||
int min = b->width;
|
||||
if (!bn_wexpand(r, max + 1)) {
|
||||
return 0;
|
||||
}
|
||||
r->width = max + 1;
|
||||
|
||||
r->top = max;
|
||||
|
||||
ap = a->d;
|
||||
bp = b->d;
|
||||
rp = r->d;
|
||||
|
||||
carry = bn_add_words(rp, ap, bp, min);
|
||||
rp += min;
|
||||
ap += min;
|
||||
bp += min;
|
||||
|
||||
if (carry) {
|
||||
while (dif) {
|
||||
dif--;
|
||||
t1 = *(ap++);
|
||||
t2 = (t1 + 1) & BN_MASK2;
|
||||
*(rp++) = t2;
|
||||
if (t2) {
|
||||
carry = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (carry) {
|
||||
// carry != 0 => dif == 0
|
||||
*rp = 1;
|
||||
r->top++;
|
||||
}
|
||||
BN_ULONG carry = bn_add_words(r->d, a->d, b->d, min);
|
||||
for (int i = min; i < max; i++) {
|
||||
// |r| and |a| may alias, so use a temporary.
|
||||
BN_ULONG tmp = carry + a->d[i];
|
||||
carry = tmp < a->d[i];
|
||||
r->d[i] = tmp;
|
||||
}
|
||||
|
||||
if (dif && rp != ap) {
|
||||
while (dif--) {
|
||||
// copy remaining words if ap != rp
|
||||
*(rp++) = *(ap++);
|
||||
}
|
||||
}
|
||||
r->d[max] = carry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
r->neg = 0;
|
||||
int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
if (!bn_uadd_fixed(r, a, b)) {
|
||||
return 0;
|
||||
}
|
||||
bn_set_minimal_width(r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -162,8 +139,6 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) {
|
||||
BN_ULONG l;
|
||||
int i;
|
||||
|
||||
w &= BN_MASK2;
|
||||
|
||||
// degenerate case: w is zero
|
||||
if (!w) {
|
||||
return 1;
|
||||
@@ -184,16 +159,16 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) {
|
||||
return i;
|
||||
}
|
||||
|
||||
for (i = 0; w != 0 && i < a->top; i++) {
|
||||
a->d[i] = l = (a->d[i] + w) & BN_MASK2;
|
||||
for (i = 0; w != 0 && i < a->width; i++) {
|
||||
a->d[i] = l = a->d[i] + w;
|
||||
w = (w > l) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (w && i == a->top) {
|
||||
if (!bn_wexpand(a, a->top + 1)) {
|
||||
if (w && i == a->width) {
|
||||
if (!bn_wexpand(a, a->width + 1)) {
|
||||
return 0;
|
||||
}
|
||||
a->top++;
|
||||
a->width++;
|
||||
a->d[i] = w;
|
||||
}
|
||||
|
||||
@@ -201,7 +176,6 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) {
|
||||
}
|
||||
|
||||
int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
int max;
|
||||
int add = 0, neg = 0;
|
||||
const BIGNUM *tmp;
|
||||
|
||||
@@ -234,13 +208,6 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We are actually doing a - b :-)
|
||||
|
||||
max = (a->top > b->top) ? a->top : b->top;
|
||||
if (!bn_wexpand(r, max)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_ucmp(a, b) < 0) {
|
||||
if (!BN_usub(r, b, a)) {
|
||||
return 0;
|
||||
@@ -261,8 +228,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
register BN_ULONG t1, t2, *ap, *bp, *rp;
|
||||
int i, carry;
|
||||
|
||||
max = a->top;
|
||||
min = b->top;
|
||||
max = bn_minimal_width(a);
|
||||
min = bn_minimal_width(b);
|
||||
dif = max - min;
|
||||
|
||||
if (dif < 0) // hmm... should not be happening
|
||||
@@ -285,12 +252,12 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
t2 = *(bp++);
|
||||
if (carry) {
|
||||
carry = (t1 <= t2);
|
||||
t1 = (t1 - t2 - 1) & BN_MASK2;
|
||||
t1 -= t2 + 1;
|
||||
} else {
|
||||
carry = (t1 < t2);
|
||||
t1 = (t1 - t2) & BN_MASK2;
|
||||
t1 -= t2;
|
||||
}
|
||||
*(rp++) = t1 & BN_MASK2;
|
||||
*(rp++) = t1;
|
||||
}
|
||||
|
||||
if (carry) // subtracted
|
||||
@@ -303,7 +270,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
while (dif) {
|
||||
dif--;
|
||||
t1 = *(ap++);
|
||||
t2 = (t1 - 1) & BN_MASK2;
|
||||
t2 = t1 - 1;
|
||||
*(rp++) = t2;
|
||||
if (t1) {
|
||||
break;
|
||||
@@ -315,9 +282,9 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
|
||||
}
|
||||
|
||||
r->top = max;
|
||||
r->width = max;
|
||||
r->neg = 0;
|
||||
bn_correct_top(r);
|
||||
bn_set_minimal_width(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -325,8 +292,6 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
int BN_sub_word(BIGNUM *a, BN_ULONG w) {
|
||||
int i;
|
||||
|
||||
w &= BN_MASK2;
|
||||
|
||||
// degenerate case: w is zero
|
||||
if (!w) {
|
||||
return 1;
|
||||
@@ -349,7 +314,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) {
|
||||
return i;
|
||||
}
|
||||
|
||||
if ((a->top == 1) && (a->d[0] < w)) {
|
||||
if ((bn_minimal_width(a) == 1) && (a->d[0] < w)) {
|
||||
a->d[0] = w - a->d[0];
|
||||
a->neg = 1;
|
||||
return 1;
|
||||
@@ -361,14 +326,14 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) {
|
||||
a->d[i] -= w;
|
||||
break;
|
||||
} else {
|
||||
a->d[i] = (a->d[i] - w) & BN_MASK2;
|
||||
a->d[i] -= w;
|
||||
i++;
|
||||
w = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((a->d[i] == 0) && (i == (a->top - 1))) {
|
||||
a->top--;
|
||||
if ((a->d[i] == 0) && (i == (a->width - 1))) {
|
||||
a->width--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -97,6 +97,10 @@ $_num="$num,#15*4"; $_bpend=$_num;
|
||||
$code=<<___;
|
||||
#include <openssl/arm_arch.h>
|
||||
|
||||
@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
|
||||
@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
|
||||
.arch armv7-a
|
||||
|
||||
.text
|
||||
#if defined(__thumb2__)
|
||||
.syntax unified
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
push(@INC,"${dir}","${dir}../../../perlasm");
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
#!/usr/local/bin/perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
push(@INC,"${dir}","${dir}../../../perlasm");
|
||||
|
||||
@@ -1,61 +1,30 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# Copyright (c) 2012, Intel Corporation #
|
||||
# #
|
||||
# All rights reserved. #
|
||||
# #
|
||||
# Redistribution and use in source and binary forms, with or without #
|
||||
# modification, are permitted provided that the following conditions are #
|
||||
# met: #
|
||||
# #
|
||||
# * Redistributions of source code must retain the above copyright #
|
||||
# notice, this list of conditions and the following disclaimer. #
|
||||
# #
|
||||
# * 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. #
|
||||
# #
|
||||
# * Neither the name of the Intel Corporation nor the names of its #
|
||||
# contributors may be used to endorse or promote products derived from #
|
||||
# this software without specific prior written permission. #
|
||||
# #
|
||||
# #
|
||||
# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY #
|
||||
# EXPRESS 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 INTEL CORPORATION OR #
|
||||
# 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. #
|
||||
# #
|
||||
##############################################################################
|
||||
# Developers and authors: #
|
||||
# Shay Gueron (1, 2), and Vlad Krasnov (1) #
|
||||
# (1) Intel Corporation, Israel Development Center, Haifa, Israel #
|
||||
# (2) University of Haifa, Israel #
|
||||
##############################################################################
|
||||
# Reference: #
|
||||
# [1] S. Gueron, V. Krasnov: "Software Implementation of Modular #
|
||||
# Exponentiation, Using Advanced Vector Instructions Architectures", #
|
||||
# F. Ozbudak and F. Rodriguez-Henriquez (Eds.): WAIFI 2012, LNCS 7369, #
|
||||
# pp. 119?135, 2012. Springer-Verlag Berlin Heidelberg 2012 #
|
||||
# [2] S. Gueron: "Efficient Software Implementations of Modular #
|
||||
# Exponentiation", Journal of Cryptographic Engineering 2:31-43 (2012). #
|
||||
# [3] S. Gueron, V. Krasnov: "Speeding up Big-numbers Squaring",IEEE #
|
||||
# Proceedings of 9th International Conference on Information Technology: #
|
||||
# New Generations (ITNG 2012), pp.821-823 (2012) #
|
||||
# [4] S. Gueron, V. Krasnov: "[PATCH] Efficient and side channel analysis #
|
||||
# resistant 1024-bit modular exponentiation, for optimizing RSA2048 #
|
||||
# on AVX2 capable x86_64 platforms", #
|
||||
# http://rt.openssl.org/Ticket/Display.html?id=2850&user=guest&pass=guest#
|
||||
##############################################################################
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright (c) 2012, Intel Corporation. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
#
|
||||
# Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
|
||||
# (1) Intel Corporation, Israel Development Center, Haifa, Israel
|
||||
# (2) University of Haifa, Israel
|
||||
#
|
||||
# References:
|
||||
# [1] S. Gueron, V. Krasnov: "Software Implementation of Modular
|
||||
# Exponentiation, Using Advanced Vector Instructions Architectures",
|
||||
# F. Ozbudak and F. Rodriguez-Henriquez (Eds.): WAIFI 2012, LNCS 7369,
|
||||
# pp. 119?135, 2012. Springer-Verlag Berlin Heidelberg 2012
|
||||
# [2] S. Gueron: "Efficient Software Implementations of Modular
|
||||
# Exponentiation", Journal of Cryptographic Engineering 2:31-43 (2012).
|
||||
# [3] S. Gueron, V. Krasnov: "Speeding up Big-numbers Squaring",IEEE
|
||||
# Proceedings of 9th International Conference on Information Technology:
|
||||
# New Generations (ITNG 2012), pp.821-823 (2012)
|
||||
# [4] S. Gueron, V. Krasnov: "[PATCH] Efficient and side channel analysis
|
||||
# resistant 1024-bit modular exponentiation, for optimizing RSA2048
|
||||
# on AVX2 capable x86_64 platforms",
|
||||
# http://rt.openssl.org/Ticket/Display.html?id=2850&user=guest&pass=guest
|
||||
#
|
||||
# +13% improvement over original submission by <appro@openssl.org>
|
||||
#
|
||||
@@ -232,7 +201,7 @@ $code.=<<___;
|
||||
vmovdqu 32*8-128($ap), $ACC8
|
||||
|
||||
lea 192(%rsp), $tp0 # 64+128=192
|
||||
vpbroadcastq .Land_mask(%rip), $AND_MASK
|
||||
vmovdqu .Land_mask(%rip), $AND_MASK
|
||||
jmp .LOOP_GRANDE_SQR_1024
|
||||
|
||||
.align 32
|
||||
@@ -1082,10 +1051,10 @@ $code.=<<___;
|
||||
vpmuludq 32*6-128($np),$Yi,$TEMP1
|
||||
vpaddq $TEMP1,$ACC6,$ACC6
|
||||
vpmuludq 32*7-128($np),$Yi,$TEMP2
|
||||
vpblendd \$3, $ZERO, $ACC9, $ACC9 # correct $ACC3
|
||||
vpblendd \$3, $ZERO, $ACC9, $TEMP1 # correct $ACC3
|
||||
vpaddq $TEMP2,$ACC7,$ACC7
|
||||
vpmuludq 32*8-128($np),$Yi,$TEMP0
|
||||
vpaddq $ACC9, $ACC3, $ACC3 # correct $ACC3
|
||||
vpaddq $TEMP1, $ACC3, $ACC3 # correct $ACC3
|
||||
vpaddq $TEMP0,$ACC8,$ACC8
|
||||
|
||||
mov %rbx, %rax
|
||||
@@ -1098,7 +1067,9 @@ $code.=<<___;
|
||||
vmovdqu -8+32*2-128($ap),$TEMP2
|
||||
|
||||
mov $r1, %rax
|
||||
vpblendd \$0xfc, $ZERO, $ACC9, $ACC9 # correct $ACC3
|
||||
imull $n0, %eax
|
||||
vpaddq $ACC9,$ACC4,$ACC4 # correct $ACC3
|
||||
and \$0x1fffffff, %eax
|
||||
|
||||
imulq 16-128($ap),%rbx
|
||||
@@ -1334,15 +1305,12 @@ ___
|
||||
# But as we underutilize resources, it's possible to correct in
|
||||
# each iteration with marginal performance loss. But then, as
|
||||
# we do it in each iteration, we can correct less digits, and
|
||||
# avoid performance penalties completely. Also note that we
|
||||
# correct only three digits out of four. This works because
|
||||
# most significant digit is subjected to less additions.
|
||||
# avoid performance penalties completely.
|
||||
|
||||
$TEMP0 = $ACC9;
|
||||
$TEMP3 = $Bi;
|
||||
$TEMP4 = $Yi;
|
||||
$code.=<<___;
|
||||
vpermq \$0, $AND_MASK, $AND_MASK
|
||||
vpaddq (%rsp), $TEMP1, $ACC0
|
||||
|
||||
vpsrlq \$29, $ACC0, $TEMP1
|
||||
@@ -1790,7 +1758,7 @@ $code.=<<___;
|
||||
|
||||
.align 64
|
||||
.Land_mask:
|
||||
.quad 0x1fffffff,0x1fffffff,0x1fffffff,-1
|
||||
.quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff
|
||||
.Lscatter_permd:
|
||||
.long 0,2,4,6,7,7,7,7
|
||||
.Lgather_permd:
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
@@ -71,7 +78,7 @@ $frame=32; # size of above frame rounded up to 16n
|
||||
&lea ("ebp",&DWP(-$frame,"esp","edi",4)); # future alloca($frame+4*(num+2))
|
||||
&neg ("edi");
|
||||
|
||||
# minimize cache contention by arraning 2K window between stack
|
||||
# minimize cache contention by arranging 2K window between stack
|
||||
# pointer and ap argument [np is also position sensitive vector,
|
||||
# but it's assumed to be near ap, as it's allocated at ~same
|
||||
# time].
|
||||
|
||||
@@ -52,8 +52,9 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
// TODO(davidben): Get this file working on Windows x64.
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
|
||||
// TODO(davidben): Get this file working on MSVC x64.
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
(defined(__GNUC__) || defined(__clang__))
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
@@ -93,11 +94,11 @@
|
||||
#undef sqr
|
||||
#define sqr(r0, r1, a) __asm__("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc");
|
||||
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
|
||||
if (num <= 0) {
|
||||
if (num == 0) {
|
||||
return (c1);
|
||||
}
|
||||
|
||||
@@ -126,10 +127,11 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
return c1;
|
||||
}
|
||||
|
||||
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
|
||||
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num,
|
||||
BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
|
||||
if (num <= 0) {
|
||||
if (num == 0) {
|
||||
return c1;
|
||||
}
|
||||
|
||||
@@ -156,8 +158,8 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
|
||||
return c1;
|
||||
}
|
||||
|
||||
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
if (n <= 0) {
|
||||
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) {
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -184,11 +186,11 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
}
|
||||
|
||||
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
int n) {
|
||||
size_t n) {
|
||||
BN_ULONG ret;
|
||||
size_t i = 0;
|
||||
|
||||
if (n <= 0) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -201,7 +203,8 @@ BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
" adcq (%5,%2,8),%0 \n"
|
||||
" movq %0,(%3,%2,8) \n"
|
||||
" lea 1(%2),%2 \n"
|
||||
" loop 1b \n"
|
||||
" dec %1 \n"
|
||||
" jnz 1b \n"
|
||||
" sbbq %0,%0 \n"
|
||||
: "=&r"(ret), "+c"(n), "+r"(i)
|
||||
: "r"(rp), "r"(ap), "r"(bp)
|
||||
@@ -211,11 +214,11 @@ BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
}
|
||||
|
||||
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
int n) {
|
||||
size_t n) {
|
||||
BN_ULONG ret;
|
||||
size_t i = 0;
|
||||
|
||||
if (n <= 0) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -228,7 +231,8 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
" sbbq (%5,%2,8),%0 \n"
|
||||
" movq %0,(%3,%2,8) \n"
|
||||
" lea 1(%2),%2 \n"
|
||||
" loop 1b \n"
|
||||
" dec %1 \n"
|
||||
" jnz 1b \n"
|
||||
" sbbq %0,%0 \n"
|
||||
: "=&r"(ret), "+c"(n), "+r"(i)
|
||||
: "r"(rp), "r"(ap), "r"(bp)
|
||||
@@ -280,7 +284,7 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) {
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -382,7 +386,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
r[15] = c1;
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) {
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -420,7 +424,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
r[7] = c2;
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) {
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -494,7 +498,7 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
r[15] = c1;
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) {
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -534,4 +538,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#undef mul_add_c2
|
||||
#undef sqr_add_c2
|
||||
|
||||
#endif // !NO_ASM && X86_64 && __GNUC__
|
||||
#endif // !NO_ASM && X86_64 && (__GNUC__ || __clang__)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user