Compare commits
379 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8cbbec76b | |||
| 367545d0b4 | |||
| 938e03ed17 | |||
| b180ee98a6 | |||
| 195dc78c6e | |||
| 5f237bc843 | |||
| 1b5cfb5ba3 | |||
| e079927ceb | |||
| dd1ca99da4 | |||
| 310db06b79 | |||
| fbdfefb76e | |||
| 9d0847ae6d | |||
| ed7c475154 | |||
| a54e2e85ee | |||
| 26c2b929ba | |||
| d306f165a4 | |||
| c64ccb51b0 | |||
| 6899b19464 | |||
| 6f8c366989 | |||
| d0f5df2d71 | |||
| 82fc3bd333 | |||
| 589963f79e | |||
| a1048a772f | |||
| 2d96a67218 | |||
| c68f3e02b0 | |||
| fcd34624a1 | |||
| c35fb014d9 | |||
| 776597dac7 | |||
| 3bb4178206 | |||
| 491b9219a9 | |||
| 6eb000dbee | |||
| 9ab14e00d5 | |||
| 3673be7cb6 | |||
| 689be0f4b7 | |||
| 96396b3aaa | |||
| c9a202fee3 | |||
| efec193d27 | |||
| 32f1650658 | |||
| fc233962db | |||
| e8fe46adf0 | |||
| cf310a6197 | |||
| 29b186736c | |||
| 65226257c1 | |||
| 722696b39e | |||
| ed3d302190 | |||
| 9e128b06a1 | |||
| 2d445c0921 | |||
| c273d2c537 | |||
| 1b8b691458 | |||
| 2fff5bf4a8 | |||
| 23a8ca1f10 | |||
| 3363984d0d | |||
| 41fdbcdc72 | |||
| d9e070193f | |||
| a7f333d103 | |||
| 95695c8d88 | |||
| ccf74f8085 | |||
| 931ab3484f | |||
| e0e7d0da68 | |||
| b80168e1b8 | |||
| e820df9371 | |||
| 68070620e7 | |||
| 1eed2c0e40 | |||
| 42ca3a4623 | |||
| 4e04ee8786 | |||
| 3fd1fbd1c8 | |||
| ddb9f15e18 | |||
| afbc63fc2f | |||
| 8f5e2ebcee | |||
| 0ea8dda93e | |||
| f95ef93c62 | |||
| 2cdace913e | |||
| d4f924c4b1 | |||
| ac6900b0d3 | |||
| c39be857a8 | |||
| b3774b9619 | |||
| 5ba305643f | |||
| 2683af70e7 | |||
| a84f06fc1e | |||
| d660b57208 | |||
| 79ae85e4f7 | |||
| e33b9b0a87 | |||
| 83f9040339 | |||
| d9b091b5e2 | |||
| 377fc3160c | |||
| 868c7ef1f4 | |||
| 64b17ccf15 | |||
| 23343e4b12 | |||
| d062c8afba | |||
| 2b2d66d409 | |||
| efed2210e8 | |||
| 0bb81fcd66 | |||
| ab21891e34 | |||
| be629e0e92 | |||
| 9115755006 | |||
| ba90d7c56e | |||
| d5c0980e33 | |||
| 8de7597af3 | |||
| 267253470a | |||
| a87de9b39b | |||
| 4a0f0c4910 | |||
| 2e38008558 | |||
| bcc4fa87af | |||
| 507c1eec51 | |||
| f4600adb0e | |||
| f058dae8fc | |||
| dc94b54708 | |||
| 33970e6ce0 | |||
| 9a9a193388 | |||
| afdaeee7ed | |||
| 2fe7f2d0d9 | |||
| 1d75c8be73 | |||
| ed30c0d6cf | |||
| b7f3144a20 | |||
| 69ad27fdd8 | |||
| 36eb7d5fbc | |||
| 53cbd6c8a0 | |||
| bed8f7307e | |||
| cca4d5991f | |||
| cd5c892a87 | |||
| fd4eb60497 | |||
| b4a494cc32 | |||
| 347f025d75 | |||
| 6ae7f072e3 | |||
| 4189bd943c | |||
| 78e6978ab9 | |||
| 33e799fe19 | |||
| c898ce752f | |||
| 2a0e72f08a | |||
| df1cda345f | |||
| e3b24674ef | |||
| 8604eda634 | |||
| c5cc15b4f5 | |||
| 5fa3eba03d | |||
| 9a38e924aa | |||
| 1e52ecac4d | |||
| 66850ddec1 | |||
| 384673ceb7 | |||
| cb878e20f3 | |||
| 07100c6e69 | |||
| 4dcb05729f | |||
| 25bde4c1f9 | |||
| e49da742cb | |||
| e7624340ee | |||
| 6a3c288cdf | |||
| 543d00692a | |||
| 7f1d5d5932 | |||
| f0eb169829 | |||
| d749af7ab1 | |||
| b1116a4a3b | |||
| 3e6526575a | |||
| bc44c089fb | |||
| 7ce1c0ca75 | |||
| e9fc3e547e | |||
| 4de5f54e54 | |||
| aa3f6daa86 | |||
| 1681d79ddf | |||
| c61517cb5a | |||
| 70bd80a236 | |||
| 52e5bacf7c | |||
| 0cb3f5bc27 | |||
| 6095de8da2 | |||
| 5b082e880d | |||
| d1d7d3d26a | |||
| 39507745e3 | |||
| d83c1884fd | |||
| 1716b3d172 | |||
| e3b2eebd04 | |||
| 710d227daa | |||
| 2adb7ec286 | |||
| af19de3101 | |||
| 17a5f85cbb | |||
| 80cee912de | |||
| a18b671c94 | |||
| 5a3cc0381b | |||
| 7f18b139cc | |||
| d9778fb418 | |||
| c67a3ae6ba | |||
| f3a8b12ac3 | |||
| 0ebfac554e | |||
| e9e38375a6 | |||
| b8a56f112f | |||
| e95d20dcb8 | |||
| 044abb0aaa | |||
| 41ac979211 | |||
| 31b1d81354 | |||
| 1f5e115ea9 | |||
| 238510a679 | |||
| bbd8444d92 | |||
| ea72bd0b60 | |||
| df109ab3d4 | |||
| af032d68b3 | |||
| 2bca0988a4 | |||
| a307dfd29f | |||
| f9a40b2ce5 | |||
| 13be1de469 | |||
| dc4b197f0f | |||
| 62fd16283a | |||
| 02ddbfdf46 | |||
| 95e18c52f2 | |||
| ca9a538aa0 | |||
| 44e2709cd6 | |||
| a83cc803b1 | |||
| 7cc3f992ae | |||
| aac2f6a6a0 | |||
| 0ed0cf6f38 | |||
| 46a7ca0fa3 | |||
| 780d6dd0fe | |||
| 2be62c304c | |||
| 4dd053e059 | |||
| 517073cd4b | |||
| b9e0ccc650 | |||
| a7f6d3c1dc | |||
| 93efb7228b | |||
| d3bcf13165 | |||
| fcf25833bc | |||
| 4685e87746 | |||
| be2900a6a3 | |||
| cf70188d53 | |||
| 1bea173fd4 | |||
| 6e73d62dcc | |||
| f49196052c | |||
| a6d81018f8 | |||
| 263eac02f5 | |||
| 9cf708807c | |||
| 2481975857 | |||
| 4841ce49a0 | |||
| ef5885e410 | |||
| e4824e8af0 | |||
| 44f2d1a9bf | |||
| bf42f82ad9 | |||
| 07046a0946 | |||
| 16d031a493 | |||
| 71d8a085d0 | |||
| 139ed19580 | |||
| 87909c0445 | |||
| 82c9e90a58 | |||
| 4b755cb0da | |||
| 63c55a8e35 | |||
| 1f48fba861 | |||
| accb454e44 | |||
| 1eb367c03e | |||
| 9ec6bcaebe | |||
| e99e912bea | |||
| ceb6f2880f | |||
| 69b9e597ae | |||
| 7e23746dd4 | |||
| 138c2ac627 | |||
| 28014cb4f2 | |||
| 338fcafe76 | |||
| f080ecd86d | |||
| 226a872d2f | |||
| d14c6ee234 | |||
| b8a824d70d | |||
| e3594df7f1 | |||
| 1e29a6b7c5 | |||
| af7e74ba9f | |||
| 3547688ee0 | |||
| 306e520cda | |||
| 8c37cb60d4 | |||
| 0ac86b0220 | |||
| 129992360a | |||
| 8278184631 | |||
| 83abdd6e58 | |||
| e518f65d2c | |||
| 41aa325c6a | |||
| 74c68e5e37 | |||
| a6689b0488 | |||
| 687759db79 | |||
| 7baab87798 | |||
| f1eba30292 | |||
| 61f1085ee9 | |||
| d8a3e78223 | |||
| 90eeb11652 | |||
| edb03cf31f | |||
| 00505ec2e1 | |||
| af9d9419a6 | |||
| 0105ece171 | |||
| 94d701b7e8 | |||
| d0f257dc2c | |||
| 128dbc30f6 | |||
| beb47022b0 | |||
| 8c6fe45c2f | |||
| cde8abae14 | |||
| f34a009834 | |||
| 63246e8a99 | |||
| e319a2f73a | |||
| 533ef7304d | |||
| 8c88153465 | |||
| ff42cc1eac | |||
| e58a71b9b3 | |||
| 0b145c29a3 | |||
| 8c6a295c39 | |||
| 9cbd4a809e | |||
| 502a909bd6 | |||
| 95eeb191c0 | |||
| c44b1df459 | |||
| 81ea0bf538 | |||
| 8b8c006564 | |||
| 65ea8ff84c | |||
| 95f9cfcde0 | |||
| bafc58dfa4 | |||
| 0f1e64bf7f | |||
| 61f95277d4 | |||
| bb15e3ddb5 | |||
| 52d699f668 | |||
| 192f34b175 | |||
| 4e0a7e5a1d | |||
| d1681e614f | |||
| fe8eb9a603 | |||
| ae3e487d51 | |||
| 69a01608f3 | |||
| deb5284138 | |||
| 000800a306 | |||
| ec2f27dee1 | |||
| 033e5f47d1 | |||
| f31e681acf | |||
| 81257cb2e0 | |||
| 6a8d70c528 | |||
| 253b3e76dc | |||
| 1ad868176d | |||
| b398d16c1d | |||
| 675227e0d2 | |||
| 248f350ed8 | |||
| c20febe177 | |||
| ca6c82643a | |||
| ce5be4bd5c | |||
| 5e4f6e9247 | |||
| 3087f6e594 | |||
| 4cd8c43e73 | |||
| bdf5e72f50 | |||
| 2f3ba910a2 | |||
| e18d821dfc | |||
| d0297db108 | |||
| ca6554b133 | |||
| 9114fae39e | |||
| 688d8dfe48 | |||
| e1b20a0136 | |||
| 5e961c1ff1 | |||
| 0d82482e47 | |||
| f2f3cfedb7 | |||
| b145c8140b | |||
| 1f10d9c8e1 | |||
| 1df112448b | |||
| 525a0fe315 | |||
| b4188f0c9d | |||
| 6867f4854e | |||
| d8138e91d0 | |||
| 60e7992764 | |||
| b044020f84 | |||
| 9ed9dae18e | |||
| a0b74eb241 | |||
| af6e45bde5 | |||
| a952d96656 | |||
| 7530e3031d | |||
| fba236fa88 | |||
| 920e69658e | |||
| 0e7f89f96c | |||
| 08d6fe2fdb | |||
| e1cf3f1579 | |||
| 3dfbcc1f25 | |||
| b15d8132c7 | |||
| 655038e7db | |||
| 9398f168f9 | |||
| 9f5a314d35 | |||
| 1a8b549098 | |||
| 9da9035b50 | |||
| 23586e1e0e | |||
| a85093f5bb | |||
| ab2815eaff | |||
| 4aa86f1cdf | |||
| e2793a7189 | |||
| 9ecafa5c78 | |||
| f2b32a2de2 | |||
| 626fb8b75c | |||
| 74072ac84c | |||
| 3f383908e2 | |||
| 25cb99c149 | |||
| 404e6e64d0 |
@@ -2,3 +2,4 @@ build/
|
||||
ssl/test/runner/runner
|
||||
*.swp
|
||||
*.swo
|
||||
doc/*.html
|
||||
|
||||
@@ -1,33 +1,79 @@
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
Build Prerequisites:
|
||||
|
||||
Note that the default build flags in the top-leve CMakeLists.txt are for
|
||||
* CMake[1] 2.8.8 or later is required.
|
||||
|
||||
* Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
|
||||
have both been reported to work.
|
||||
|
||||
* On Windows you currently must use Ninja[2] to build; on other platforms,
|
||||
it is not required, but recommended, because it makes builds faster.
|
||||
|
||||
* If you need to build Ninja from source, then a recent version of
|
||||
Python[3] is required (Python 2.7.5 works).
|
||||
|
||||
* On Windows only, Yasm[4] is required.
|
||||
|
||||
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
|
||||
with Platform SDK 8.1 or later are supported. Recent versions of GCC and
|
||||
Clang should work on non-Windows platforms, and maybe on Windows too.
|
||||
|
||||
* Go[5] is required for running tests, but not for building. Note that the
|
||||
runner.go tests do not work on Windows.
|
||||
|
||||
Using Ninja (note the 'N' is capitalized in the cmake invocation):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja ..
|
||||
ninja
|
||||
|
||||
Using makefiles (does not work on Windows):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
You usually don't need to run cmake again after changing CMakeLists.txt files
|
||||
because the build scripts will detect changes to them and rebuild themselves
|
||||
automatically.
|
||||
|
||||
Note that the default build flags in the top-level CMakeLists.txt are for
|
||||
debugging - optimisation isn't enabled.
|
||||
|
||||
If you'll be building a lot, then installing Ninja[1] is highly recommended.
|
||||
Wipe out the build directory and recreate it, but using:
|
||||
|
||||
cmake -GNinja ..
|
||||
ninja
|
||||
|
||||
If you want to cross-compile then there are example toolchain files for 32-bit
|
||||
Intel and ARM in util/. Wipe out the build directory, recreate it and run cmake
|
||||
like this:
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../util/arm-toolchain.cmake -GNinja ..
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../util/arm-toolchain.cmake -GNinja ..
|
||||
|
||||
If you want to build as a shared library you need to tweak the STATIC tags in
|
||||
the CMakeLists.txts and also define BORINGSSL_SHARED_LIBRARY and
|
||||
BORINGSSL_IMPLEMENTATION. On Windows, where functions need to be tagged with
|
||||
"dllimport" when coming from a shared library, you need just
|
||||
BORINGSSL_SHARED_LIBRARY defined in the code which #includes the BoringSSL
|
||||
headers.
|
||||
If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On
|
||||
Windows, where functions need to be tagged with "dllimport" when coming from a
|
||||
shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the
|
||||
BoringSSL headers.
|
||||
|
||||
To build on Windows, Yasm[2] is required for assembly. Either ensure yasm.exe
|
||||
is in %PATH% or configure CMAKE_ASM_NASM_COMPILER appropriately. Note that
|
||||
full Windows support is still in progress.
|
||||
Known Limitations on Windows:
|
||||
|
||||
[1] http://martine.github.io/ninja/
|
||||
[2] http://yasm.tortall.net/
|
||||
* Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes
|
||||
yasm to output warnings "yasm: warning: can open only one input file, only
|
||||
the last file will be processed". These warnings can be safely ignored.
|
||||
The cmake bug is http://www.cmake.org/Bug/view.php?id=15253.
|
||||
|
||||
* cmake can generate Visual Studio projects, but the generated project files
|
||||
don't have steps for assembling the assembly language source files, so they
|
||||
currently cannot be used to build BoringSSL.
|
||||
|
||||
* The tests written in Go do not work.
|
||||
|
||||
[1] http://www.cmake.org/download/
|
||||
|
||||
[2] https://martine.github.io/ninja/
|
||||
|
||||
[3] https://www.python.org/downloads/
|
||||
|
||||
[4] http://yasm.tortall.net/
|
||||
|
||||
Either ensure yasm.exe is in %PATH% or configure CMAKE_ASM_NASM_COMPILER
|
||||
appropriately.
|
||||
|
||||
[5] https://golang.org/dl/
|
||||
|
||||
+89
-20
@@ -1,39 +1,108 @@
|
||||
cmake_minimum_required (VERSION 2.8.8)
|
||||
cmake_minimum_required (VERSION 2.8.10)
|
||||
|
||||
project (BoringSSL)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -std=c89")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x")
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x -fvisibility=hidden")
|
||||
elseif(MSVC)
|
||||
# Disable warnings for implicit integer narrowing.
|
||||
set(CMAKE_C_FLAGS "/wd4267")
|
||||
set(CMAKE_CXX_FLAGS "/wd4267")
|
||||
set(MSVC_DISABLED_WARNINGS_LIST
|
||||
"C4100" # 'exarg' : unreferenced formal parameter
|
||||
"C4127" # conditional expression is constant
|
||||
"C4200" # nonstandard extension used : zero-sized array in
|
||||
# struct/union.
|
||||
"C4210" # nonstandard extension used : function given file scope
|
||||
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
# 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
|
||||
"C4311" # 'type cast' : pointer truncation from 'uint8_t *' to 'long'
|
||||
# TODO(davidben): Fix the s3_pkt.c's alignment code to avoid this.
|
||||
"C4371" # layout of class may have changed from a previous version of the
|
||||
# compiler due to better packing of member '...'
|
||||
"C4388" # signed/unsigned mismatch
|
||||
"C4296" # '>=' : expression is always true
|
||||
"C4350" # behavior change: 'std::_Wrap_alloc...'
|
||||
"C4365" # '=' : conversion from 'size_t' to 'int',
|
||||
# signed/unsigned mismatch
|
||||
"C4389" # '!=' : signed/unsigned mismatch
|
||||
"C4510" # 'argument' : default constructor could not be generated
|
||||
"C4512" # 'argument' : assignment operator could not be generated
|
||||
"C4514" # 'function': unreferenced inline function has been removed
|
||||
"C4548" # expression before comma has no effect; expected expression with
|
||||
# side-effect" caused by FD_* macros.
|
||||
"C4610" # struct 'argument' can never be instantiated - user defined
|
||||
# constructor required.
|
||||
"C4625" # copy constructor could not be generated because a base class
|
||||
# copy constructor is inaccessible or deleted
|
||||
"C4626" # assignment operator could not be generated because a base class
|
||||
# assignment operator is inaccessible or deleted
|
||||
"C4701" # potentially uninitialized local variable 'mdlen' used
|
||||
"C4706" # assignment within conditional expression
|
||||
"C4710" # 'function': function not inlined
|
||||
"C4711" # function 'function' selected for inline expansion
|
||||
"C4800" # 'int' : forcing value to bool 'true' or 'false'
|
||||
# (performance warning)
|
||||
"C4820" # 'bytes' bytes padding added after construct 'member_name'
|
||||
"C4996" # 'read': The POSIX name for this item is deprecated. Instead,
|
||||
# use the ISO C++ conformant name: _read.
|
||||
)
|
||||
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
|
||||
${MSVC_DISABLED_WARNINGS_LIST})
|
||||
set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
|
||||
set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
|
||||
add_definitions(-D_HAS_EXCEPTIONS=0)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
endif()
|
||||
|
||||
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.5.99") OR
|
||||
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
|
||||
endif()
|
||||
|
||||
add_definitions(-DBORINGSSL_IMPLEMENTATION)
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_definitions(-DBORINGSSL_SHARED_LIBRARY)
|
||||
# Enable position-independent code globally. This is needed because
|
||||
# some library targets are OBJECT libraries.
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
|
||||
set(ARCH "x86_64")
|
||||
set(ARCH "x86_64")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
|
||||
set(ARCH "x86_64")
|
||||
set(ARCH "x86_64")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
|
||||
# cmake reports AMD64 on Windows, but we might be building for 32-bit.
|
||||
if (CMAKE_CL_64)
|
||||
set(ARCH "x86_64")
|
||||
else()
|
||||
set(ARCH "x86")
|
||||
endif()
|
||||
# cmake reports AMD64 on Windows, but we might be building for 32-bit.
|
||||
if (CMAKE_CL_64)
|
||||
set(ARCH "x86_64")
|
||||
else()
|
||||
set(ARCH "x86")
|
||||
endif()
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86")
|
||||
set(ARCH "x86")
|
||||
set(ARCH "x86")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
|
||||
set(ARCH "x86")
|
||||
set(ARCH "x86")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
|
||||
set(ARCH "x86")
|
||||
set(ARCH "x86")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
|
||||
set(ARCH "arm")
|
||||
set(ARCH "arm")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
set(ARCH "aarch64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
|
||||
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86" AND APPLE)
|
||||
# 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.
|
||||
set(ARCH "x86_64")
|
||||
endif()
|
||||
|
||||
add_subdirectory(crypto)
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
BoringSSL Style Guide.
|
||||
|
||||
BoringSSL usually follows the Google C++ style guide, found below. The
|
||||
rest of this document describes differences and clarifications on top
|
||||
of the base guide.
|
||||
|
||||
https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
|
||||
|
||||
|
||||
Legacy code.
|
||||
|
||||
As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
|
||||
that does not follow this style guide. Particularly where public API
|
||||
is concerned, balance consistency within a module with the benefits of
|
||||
a given rule. Module-wide deviations on naming should be respected
|
||||
while integer and return value conventions take precedence over
|
||||
consistency.
|
||||
|
||||
Some modules have seen few changes, so they still retain the original
|
||||
indentation style for now. When editing these, try to retain the
|
||||
original style. For Emacs, doc/c-indentation.el from OpenSSL may be
|
||||
helpful in this.
|
||||
|
||||
|
||||
Language.
|
||||
|
||||
The majority of the project is in C, so C++-specific rules in the
|
||||
Google style guide do not apply. Support for C99 features depends on
|
||||
our target platforms. Typically, Chromium's target MSVC is the most
|
||||
restrictive.
|
||||
|
||||
Variable declarations in the middle of a function are allowed.
|
||||
|
||||
Comments should be /* C-style */ for consistency.
|
||||
|
||||
When declaration pointer types, * should be placed next to the variable
|
||||
name, not the type. So
|
||||
|
||||
uint8_t *ptr;
|
||||
|
||||
not
|
||||
|
||||
uint8_t* ptr;
|
||||
|
||||
Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
|
||||
OPENSSL_free(). Use the standard C assert() function freely.
|
||||
|
||||
For new constants, prefer enums when the values are sequential and typed
|
||||
constants for flags. If adding values to an existing set of #defines, continue
|
||||
with #define.
|
||||
|
||||
|
||||
Formatting.
|
||||
|
||||
Single-statement blocks are not allowed. All conditions and loops must
|
||||
use braces:
|
||||
|
||||
if (foo) {
|
||||
do_something();
|
||||
}
|
||||
|
||||
not
|
||||
|
||||
if (foo)
|
||||
do_something();
|
||||
|
||||
|
||||
Integers.
|
||||
|
||||
Prefer using explicitly-sized integers where appropriate rather than
|
||||
generic C ones. For instance, to represent a byte, use uint8_t, not
|
||||
unsigned char. Likewise, represent a two-byte field as uint16_t, not
|
||||
unsigned short.
|
||||
|
||||
Sizes are represented as size_t.
|
||||
|
||||
Within a struct that is retained across the lifetime of an SSL
|
||||
connection, if bounds of a size are known and it's easy, use a smaller
|
||||
integer type like uint8_t. This is a "free" connection footprint
|
||||
optimization for servers. Don't make code significantly more complex
|
||||
for it, and do still check the bounds when passing in and out of the
|
||||
struct. This narrowing should not propagate to local variables and
|
||||
function parameters.
|
||||
|
||||
When doing arithmetic, account for overflow conditions.
|
||||
|
||||
Except with platform APIs, do not use ssize_t. MSVC lacks it, and
|
||||
prefer out-of-band error signaling for size_t (see Return values).
|
||||
|
||||
|
||||
Naming.
|
||||
|
||||
Follow Google naming conventions in C++ files. In C files, use the
|
||||
following naming conventions for consistency with existing OpenSSL and C
|
||||
styles:
|
||||
|
||||
Define structs with typedef named TYPE_NAME. The corresponding struct
|
||||
should be named struct type_name_st.
|
||||
|
||||
Name public functions as MODULE_function_name, unless the module
|
||||
already uses a different naming scheme for legacy reasons. The module
|
||||
name should be a type name if the function is a method of a particular
|
||||
type.
|
||||
|
||||
Some types are allocated within the library while others are
|
||||
initialized into a struct allocated by the caller, often on the
|
||||
stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
|
||||
TYPE_NAME_init/TYPE_NAME_cleanup, respectively.
|
||||
|
||||
If a variable is the length of a pointer value, it has the suffix
|
||||
_len. An output parameter is named out or has an out_ prefix. For
|
||||
instance, For instance:
|
||||
|
||||
uint8_t *out,
|
||||
size_t *out_len,
|
||||
const uint8_t *in,
|
||||
size_t in_len,
|
||||
|
||||
Name public headers like include/openssl/evp.h with header guards like
|
||||
OPENSSL_HEADER_EVP_H. Name internal headers like crypto/ec/internal.h
|
||||
with header guards like OPENSSL_HEADER_EC_INTERNAL_H.
|
||||
|
||||
Name enums like unix_hacker_t. For instance:
|
||||
|
||||
enum should_free_handshake_buffer_t {
|
||||
free_handshake_buffer,
|
||||
dont_free_handshake_buffer,
|
||||
};
|
||||
|
||||
|
||||
Return values.
|
||||
|
||||
As even malloc may fail in BoringSSL, the vast majority of functions
|
||||
will have a failure case. Functions should return int with one on
|
||||
success and zero on error. Do not overload the return value to both
|
||||
signal success/failure and output an integer. For example:
|
||||
|
||||
OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
|
||||
|
||||
If a function needs more than a true/false result code, define an enum
|
||||
rather than arbitrarily assigning meaning to int values.
|
||||
|
||||
If a function outputs a pointer to an object on success and there are no
|
||||
other outputs, return the pointer directly and NULL on error.
|
||||
|
||||
|
||||
Parameters.
|
||||
|
||||
Where not constrained by legacy code, parameter order should be:
|
||||
|
||||
1. context parameters
|
||||
2. output parameters
|
||||
3. input parameters
|
||||
|
||||
For example,
|
||||
|
||||
/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
|
||||
* ASN.1 object can be written. The |tag| argument will be used as the tag for
|
||||
* the object. It returns one on success or zero on error. */
|
||||
OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
|
||||
|
||||
|
||||
Documentation.
|
||||
|
||||
All public symbols must have a documentation comment in their header
|
||||
file. The style is based on that of Go. The first sentence begins with
|
||||
the symbol name, optionally prefixed with "A" or "An". Apart from the
|
||||
initial mention of symbol, references to other symbols or parameter
|
||||
names should be surrounded by |pipes|.
|
||||
|
||||
Documentation should be concise but completely describe the exposed
|
||||
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. */
|
||||
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. */
|
||||
OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
|
||||
uint8_t *to, RSA *rsa, int padding);
|
||||
|
||||
Document private functions in their internal.h header or, if static,
|
||||
where defined.
|
||||
@@ -0,0 +1,4 @@
|
||||
# This file is used by gcl to get repository specific information.
|
||||
GERRIT_HOST: True
|
||||
GERRIT_PORT: True
|
||||
CODE_REVIEW_SERVER: https://boringssl-review.googlesource.com
|
||||
+119
-91
@@ -1,67 +1,87 @@
|
||||
include_directories(. ../include)
|
||||
|
||||
if(APPLE)
|
||||
set(PERLASM_STYLE macosx)
|
||||
set(ASM_EXT S)
|
||||
enable_language(ASM)
|
||||
if (${ARCH} STREQUAL "x86")
|
||||
set(PERLASM_FLAGS "-fPIC")
|
||||
endif()
|
||||
set(PERLASM_STYLE macosx)
|
||||
set(ASM_EXT S)
|
||||
enable_language(ASM)
|
||||
elseif(UNIX)
|
||||
set(PERLASM_STYLE elf)
|
||||
set(ASM_EXT S)
|
||||
enable_language(ASM)
|
||||
if (${ARCH} STREQUAL "aarch64")
|
||||
# The "armx" Perl scripts look for "64" in the style argument
|
||||
# in order to decide whether to generate 32- or 64-bit asm.
|
||||
set(PERLASM_STYLE linux64)
|
||||
elseif (${ARCH} STREQUAL "x86")
|
||||
set(PERLASM_FLAGS "-fPIC")
|
||||
set(PERLASM_STYLE elf)
|
||||
else()
|
||||
set(PERLASM_STYLE elf)
|
||||
endif()
|
||||
set(ASM_EXT S)
|
||||
enable_language(ASM)
|
||||
else()
|
||||
if (CMAKE_CL_64)
|
||||
message("Using nasm")
|
||||
set(PERLASM_STYLE nasm)
|
||||
else()
|
||||
message("Using win32n")
|
||||
set(PERLASM_STYLE win32n)
|
||||
endif()
|
||||
if (CMAKE_CL_64)
|
||||
message("Using nasm")
|
||||
set(PERLASM_STYLE nasm)
|
||||
else()
|
||||
message("Using win32n")
|
||||
set(PERLASM_STYLE win32n)
|
||||
endif()
|
||||
|
||||
# On Windows, we use the NASM output, specifically built with Yasm.
|
||||
set(ASM_EXT asm)
|
||||
enable_language(ASM_NASM)
|
||||
# On Windows, we use the NASM output, specifically built with Yasm.
|
||||
set(ASM_EXT asm)
|
||||
enable_language(ASM_NASM)
|
||||
endif()
|
||||
|
||||
function(perlasm dest src)
|
||||
add_custom_command(
|
||||
OUTPUT ${dest}
|
||||
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${PERLASM_STYLE} ${ARGN} > ${dest}
|
||||
DEPENDS
|
||||
${src}
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86_64-xlate.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86asm.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86gas.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86masm.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86nasm.pl
|
||||
WORKING_DIRECTORY .
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT ${dest}
|
||||
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${PERLASM_STYLE} ${PERLASM_FLAGS} ${ARGN} > ${dest}
|
||||
DEPENDS
|
||||
${src}
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86_64-xlate.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86asm.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86gas.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86masm.pl
|
||||
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86nasm.pl
|
||||
WORKING_DIRECTORY .
|
||||
)
|
||||
endfunction()
|
||||
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
|
||||
cpu-x86_64-asm.${ASM_EXT}
|
||||
cpu-intel.c
|
||||
)
|
||||
cpu-x86_64-asm.${ASM_EXT}
|
||||
cpu-intel.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86")
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
|
||||
cpu-x86-asm.${ASM_EXT}
|
||||
cpu-intel.c
|
||||
)
|
||||
cpu-x86-asm.${ASM_EXT}
|
||||
cpu-intel.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
|
||||
cpu-x86-asm.${ASM_EXT}
|
||||
cpu-arm.c
|
||||
)
|
||||
cpu-arm.c
|
||||
cpu-arm-asm.S
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "aarch64")
|
||||
set(
|
||||
CRYPTO_ARCH_SOURCES
|
||||
|
||||
cpu-arm.c
|
||||
)
|
||||
endif()
|
||||
|
||||
# Level 0.1 - depends on nothing outside this set.
|
||||
@@ -105,6 +125,7 @@ add_subdirectory(hmac)
|
||||
|
||||
# Level 3
|
||||
add_subdirectory(evp)
|
||||
add_subdirectory(hkdf)
|
||||
add_subdirectory(pem)
|
||||
add_subdirectory(x509)
|
||||
add_subdirectory(x509v3)
|
||||
@@ -113,58 +134,65 @@ add_subdirectory(x509v3)
|
||||
add_subdirectory(pkcs8)
|
||||
|
||||
add_library(
|
||||
crypto
|
||||
STATIC
|
||||
crypto
|
||||
|
||||
crypto.c
|
||||
crypto_error.c
|
||||
mem.c
|
||||
thread.c
|
||||
ex_data.c
|
||||
ex_data_impl.c
|
||||
time_support.c
|
||||
directory_posix.c
|
||||
directory_win.c
|
||||
crypto.c
|
||||
mem.c
|
||||
thread.c
|
||||
ex_data.c
|
||||
ex_data_impl.c
|
||||
time_support.c
|
||||
directory_posix.c
|
||||
directory_win.c
|
||||
|
||||
${CRYPTO_ARCH_SOURCES}
|
||||
${CRYPTO_ARCH_SOURCES}
|
||||
|
||||
$<TARGET_OBJECTS:stack>
|
||||
$<TARGET_OBJECTS:lhash>
|
||||
$<TARGET_OBJECTS:err>
|
||||
$<TARGET_OBJECTS:base64>
|
||||
$<TARGET_OBJECTS:bytestring>
|
||||
$<TARGET_OBJECTS:sha>
|
||||
$<TARGET_OBJECTS:md4>
|
||||
$<TARGET_OBJECTS:md5>
|
||||
$<TARGET_OBJECTS:digest>
|
||||
$<TARGET_OBJECTS:cipher>
|
||||
$<TARGET_OBJECTS:modes>
|
||||
$<TARGET_OBJECTS:aes>
|
||||
$<TARGET_OBJECTS:des>
|
||||
$<TARGET_OBJECTS:rc4>
|
||||
$<TARGET_OBJECTS:conf>
|
||||
$<TARGET_OBJECTS:chacha>
|
||||
$<TARGET_OBJECTS:poly1305>
|
||||
$<TARGET_OBJECTS:buf>
|
||||
$<TARGET_OBJECTS:bn>
|
||||
$<TARGET_OBJECTS:bio>
|
||||
$<TARGET_OBJECTS:rand>
|
||||
$<TARGET_OBJECTS:obj>
|
||||
$<TARGET_OBJECTS:asn1>
|
||||
$<TARGET_OBJECTS:engine>
|
||||
$<TARGET_OBJECTS:dh>
|
||||
$<TARGET_OBJECTS:dsa>
|
||||
$<TARGET_OBJECTS:rsa>
|
||||
$<TARGET_OBJECTS:ec>
|
||||
$<TARGET_OBJECTS:ecdh>
|
||||
$<TARGET_OBJECTS:ecdsa>
|
||||
$<TARGET_OBJECTS:hmac>
|
||||
$<TARGET_OBJECTS:evp>
|
||||
$<TARGET_OBJECTS:pem>
|
||||
$<TARGET_OBJECTS:x509>
|
||||
$<TARGET_OBJECTS:x509v3>
|
||||
$<TARGET_OBJECTS:pkcs8>
|
||||
$<TARGET_OBJECTS:stack>
|
||||
$<TARGET_OBJECTS:lhash>
|
||||
$<TARGET_OBJECTS:err>
|
||||
$<TARGET_OBJECTS:base64>
|
||||
$<TARGET_OBJECTS:bytestring>
|
||||
$<TARGET_OBJECTS:sha>
|
||||
$<TARGET_OBJECTS:md4>
|
||||
$<TARGET_OBJECTS:md5>
|
||||
$<TARGET_OBJECTS:digest>
|
||||
$<TARGET_OBJECTS:cipher>
|
||||
$<TARGET_OBJECTS:modes>
|
||||
$<TARGET_OBJECTS:aes>
|
||||
$<TARGET_OBJECTS:des>
|
||||
$<TARGET_OBJECTS:rc4>
|
||||
$<TARGET_OBJECTS:conf>
|
||||
$<TARGET_OBJECTS:chacha>
|
||||
$<TARGET_OBJECTS:poly1305>
|
||||
$<TARGET_OBJECTS:buf>
|
||||
$<TARGET_OBJECTS:bn>
|
||||
$<TARGET_OBJECTS:bio>
|
||||
$<TARGET_OBJECTS:rand>
|
||||
$<TARGET_OBJECTS:obj>
|
||||
$<TARGET_OBJECTS:asn1>
|
||||
$<TARGET_OBJECTS:engine>
|
||||
$<TARGET_OBJECTS:dh>
|
||||
$<TARGET_OBJECTS:dsa>
|
||||
$<TARGET_OBJECTS:rsa>
|
||||
$<TARGET_OBJECTS:ec>
|
||||
$<TARGET_OBJECTS:ecdh>
|
||||
$<TARGET_OBJECTS:ecdsa>
|
||||
$<TARGET_OBJECTS:hmac>
|
||||
$<TARGET_OBJECTS:evp>
|
||||
$<TARGET_OBJECTS:hkdf>
|
||||
$<TARGET_OBJECTS:pem>
|
||||
$<TARGET_OBJECTS:x509>
|
||||
$<TARGET_OBJECTS:x509v3>
|
||||
$<TARGET_OBJECTS:pkcs8>
|
||||
)
|
||||
|
||||
add_executable(
|
||||
constant_time_test
|
||||
|
||||
constant_time_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(constant_time_test crypto)
|
||||
|
||||
perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
|
||||
perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
|
||||
|
||||
+33
-23
@@ -1,44 +1,53 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
|
||||
aes-x86_64.${ASM_EXT}
|
||||
aesni-x86_64.${ASM_EXT}
|
||||
bsaes-x86_64.${ASM_EXT}
|
||||
vpaes-x86_64.${ASM_EXT}
|
||||
)
|
||||
aes-x86_64.${ASM_EXT}
|
||||
aesni-x86_64.${ASM_EXT}
|
||||
bsaes-x86_64.${ASM_EXT}
|
||||
vpaes-x86_64.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86")
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
|
||||
aes-586.${ASM_EXT}
|
||||
vpaes-x86.${ASM_EXT}
|
||||
aesni-x86.${ASM_EXT}
|
||||
)
|
||||
aes-586.${ASM_EXT}
|
||||
vpaes-x86.${ASM_EXT}
|
||||
aesni-x86.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
|
||||
aes-armv4.${ASM_EXT}
|
||||
bsaes-armv7.${ASM_EXT}
|
||||
)
|
||||
aes-armv4.${ASM_EXT}
|
||||
bsaes-armv7.${ASM_EXT}
|
||||
aesv8-armx.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "aarch64")
|
||||
set(
|
||||
AES_ARCH_SOURCES
|
||||
|
||||
aesv8-armx.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
aes
|
||||
aes
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
aes.c
|
||||
mode_wrappers.c
|
||||
aes.c
|
||||
mode_wrappers.c
|
||||
|
||||
${AES_ARCH_SOURCES}
|
||||
${AES_ARCH_SOURCES}
|
||||
)
|
||||
|
||||
perlasm(aes-x86_64.${ASM_EXT} asm/aes-x86_64.pl)
|
||||
@@ -50,3 +59,4 @@ perlasm(vpaes-x86.${ASM_EXT} asm/vpaes-x86.pl)
|
||||
perlasm(aesni-x86.${ASM_EXT} asm/aesni-x86.pl)
|
||||
perlasm(aes-armv4.${ASM_EXT} asm/aes-armv4.pl)
|
||||
perlasm(bsaes-armv7.${ASM_EXT} asm/bsaes-armv7.pl)
|
||||
perlasm(aesv8-armx.${ASM_EXT} asm/aesv8-armx.pl)
|
||||
|
||||
@@ -525,32 +525,6 @@ static const uint8_t Td4[256] = {
|
||||
0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U,
|
||||
0x21U, 0x0cU, 0x7dU, };
|
||||
|
||||
static const uint8_t Te4[256] = {
|
||||
0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, 0x30U, 0x01U, 0x67U,
|
||||
0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U,
|
||||
0x47U, 0xf0U, 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, 0xb7U,
|
||||
0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, 0x34U, 0xa5U, 0xe5U, 0xf1U,
|
||||
0x71U, 0xd8U, 0x31U, 0x15U, 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U,
|
||||
0x9aU, 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, 0x09U, 0x83U,
|
||||
0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U,
|
||||
0xe3U, 0x2fU, 0x84U, 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
|
||||
0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, 0xd0U, 0xefU, 0xaaU,
|
||||
0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU,
|
||||
0x9fU, 0xa8U, 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, 0xbcU,
|
||||
0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, 0xcdU, 0x0cU, 0x13U, 0xecU,
|
||||
0x5fU, 0x97U, 0x44U, 0x17U, 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U,
|
||||
0x73U, 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, 0x46U, 0xeeU,
|
||||
0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U,
|
||||
0x06U, 0x24U, 0x5cU, 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
|
||||
0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, 0x6cU, 0x56U, 0xf4U,
|
||||
0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U,
|
||||
0xb4U, 0xc6U, 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, 0x70U,
|
||||
0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, 0x61U, 0x35U, 0x57U, 0xb9U,
|
||||
0x86U, 0xc1U, 0x1dU, 0x9eU, 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU,
|
||||
0x94U, 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, 0x8cU, 0xa1U,
|
||||
0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U,
|
||||
0x54U, 0xbbU, 0x16U};
|
||||
|
||||
static const uint32_t rcon[] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
|
||||
|
||||
@@ -584,6 +584,16 @@ $code.=<<___;
|
||||
.type aesni_ecb_encrypt,\@function,5
|
||||
.align 16
|
||||
aesni_ecb_encrypt:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x58(%rsp),%rsp
|
||||
movaps %xmm6,(%rsp)
|
||||
movaps %xmm7,0x10(%rsp)
|
||||
movaps %xmm8,0x20(%rsp)
|
||||
movaps %xmm9,0x30(%rsp)
|
||||
.Lecb_enc_body:
|
||||
___
|
||||
$code.=<<___;
|
||||
and \$-16,$len
|
||||
jz .Lecb_ret
|
||||
|
||||
@@ -862,6 +872,16 @@ $code.=<<___;
|
||||
movups $inout5,0x50($out)
|
||||
|
||||
.Lecb_ret:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps (%rsp),%xmm6
|
||||
movaps 0x10(%rsp),%xmm7
|
||||
movaps 0x20(%rsp),%xmm8
|
||||
movaps 0x30(%rsp),%xmm9
|
||||
lea 0x58(%rsp),%rsp
|
||||
.Lecb_enc_ret:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
|
||||
___
|
||||
@@ -3225,28 +3245,9 @@ $code.=<<___;
|
||||
.extern __imp_RtlVirtualUnwind
|
||||
___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.type ecb_se_handler,\@abi-omnipotent
|
||||
.type ecb_ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ecb_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
pushfq
|
||||
sub \$64,%rsp
|
||||
|
||||
mov 152($context),%rax # pull context->Rsp
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ecb_se_handler,.-ecb_se_handler
|
||||
|
||||
.type ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ccm64_se_handler:
|
||||
ecb_ccm64_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
@@ -3283,7 +3284,7 @@ ccm64_se_handler:
|
||||
lea 0x58(%rax),%rax # adjust stack pointer
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ccm64_se_handler,.-ccm64_se_handler
|
||||
.size ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
|
||||
|
||||
.type ctr_xts_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
@@ -3457,14 +3458,15 @@ ___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.LSEH_info_ecb:
|
||||
.byte 9,0,0,0
|
||||
.rva ecb_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lecb_enc_body,.Lecb_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_enc:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_dec:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[]
|
||||
.LSEH_info_ctr32:
|
||||
.byte 9,0,0,0
|
||||
|
||||
@@ -0,0 +1,962 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# 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/.
|
||||
# ====================================================================
|
||||
#
|
||||
# This module implements support for ARMv8 AES instructions. The
|
||||
# module is endian-agnostic in sense that it supports both big- and
|
||||
# little-endian cases. As does it support both 32- and 64-bit modes
|
||||
# of operation. Latter is achieved by limiting amount of utilized
|
||||
# registers to 16, which implies additional NEON load and integer
|
||||
# instructions. This has no effect on mighty Apple A7, where results
|
||||
# are literally equal to the theoretical estimates based on AES
|
||||
# instruction latencies and issue rates. On Cortex-A53, an in-order
|
||||
# execution core, this costs up to 10-15%, which is partially
|
||||
# compensated by implementing dedicated code path for 128-bit
|
||||
# CBC encrypt case. On Cortex-A57 parallelizable mode performance
|
||||
# seems to be limited by sheer amount of NEON instructions...
|
||||
#
|
||||
# Performance in cycles per byte processed with 128-bit key:
|
||||
#
|
||||
# CBC enc CBC dec CTR
|
||||
# Apple A7 2.39 1.20 1.20
|
||||
# Cortex-A53 2.45 1.87 1.94
|
||||
# Cortex-A57 3.64 1.34 1.32
|
||||
|
||||
$flavour = shift;
|
||||
open STDOUT,">".shift;
|
||||
|
||||
$prefix="aes_v8";
|
||||
|
||||
$code=<<___;
|
||||
#include "arm_arch.h"
|
||||
|
||||
#if __ARM_MAX_ARCH__>=7
|
||||
.text
|
||||
___
|
||||
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
|
||||
$code.=".arch armv7-a\n.fpu neon\n.code 32\n" if ($flavour !~ /64/);
|
||||
#^^^^^^ this is done to simplify adoption by not depending
|
||||
# on latest binutils.
|
||||
|
||||
# Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax,
|
||||
# NEON is mostly 32-bit mnemonics, integer - mostly 64. Goal is to
|
||||
# maintain both 32- and 64-bit codes within single module and
|
||||
# transliterate common code to either flavour with regex vodoo.
|
||||
#
|
||||
{{{
|
||||
my ($inp,$bits,$out,$ptr,$rounds)=("x0","w1","x2","x3","w12");
|
||||
my ($zero,$rcon,$mask,$in0,$in1,$tmp,$key)=
|
||||
$flavour=~/64/? map("q$_",(0..6)) : map("q$_",(0..3,8..10));
|
||||
|
||||
|
||||
$code.=<<___;
|
||||
.align 5
|
||||
rcon:
|
||||
.long 0x01,0x01,0x01,0x01
|
||||
.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
|
||||
.long 0x1b,0x1b,0x1b,0x1b
|
||||
|
||||
.globl ${prefix}_set_encrypt_key
|
||||
.type ${prefix}_set_encrypt_key,%function
|
||||
.align 5
|
||||
${prefix}_set_encrypt_key:
|
||||
.Lenc_key:
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
stp x29,x30,[sp,#-16]!
|
||||
add x29,sp,#0
|
||||
___
|
||||
$code.=<<___;
|
||||
mov $ptr,#-1
|
||||
cmp $inp,#0
|
||||
b.eq .Lenc_key_abort
|
||||
cmp $out,#0
|
||||
b.eq .Lenc_key_abort
|
||||
mov $ptr,#-2
|
||||
cmp $bits,#128
|
||||
b.lt .Lenc_key_abort
|
||||
cmp $bits,#256
|
||||
b.gt .Lenc_key_abort
|
||||
tst $bits,#0x3f
|
||||
b.ne .Lenc_key_abort
|
||||
|
||||
adr $ptr,rcon
|
||||
cmp $bits,#192
|
||||
|
||||
veor $zero,$zero,$zero
|
||||
vld1.8 {$in0},[$inp],#16
|
||||
mov $bits,#8 // reuse $bits
|
||||
vld1.32 {$rcon,$mask},[$ptr],#32
|
||||
|
||||
b.lt .Loop128
|
||||
b.eq .L192
|
||||
b .L256
|
||||
|
||||
.align 4
|
||||
.Loop128:
|
||||
vtbl.8 $key,{$in0},$mask
|
||||
vext.8 $tmp,$zero,$in0,#12
|
||||
vst1.32 {$in0},[$out],#16
|
||||
aese $key,$zero
|
||||
subs $bits,$bits,#1
|
||||
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $key,$key,$rcon
|
||||
veor $in0,$in0,$tmp
|
||||
vshl.u8 $rcon,$rcon,#1
|
||||
veor $in0,$in0,$key
|
||||
b.ne .Loop128
|
||||
|
||||
vld1.32 {$rcon},[$ptr]
|
||||
|
||||
vtbl.8 $key,{$in0},$mask
|
||||
vext.8 $tmp,$zero,$in0,#12
|
||||
vst1.32 {$in0},[$out],#16
|
||||
aese $key,$zero
|
||||
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $key,$key,$rcon
|
||||
veor $in0,$in0,$tmp
|
||||
vshl.u8 $rcon,$rcon,#1
|
||||
veor $in0,$in0,$key
|
||||
|
||||
vtbl.8 $key,{$in0},$mask
|
||||
vext.8 $tmp,$zero,$in0,#12
|
||||
vst1.32 {$in0},[$out],#16
|
||||
aese $key,$zero
|
||||
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $key,$key,$rcon
|
||||
veor $in0,$in0,$tmp
|
||||
veor $in0,$in0,$key
|
||||
vst1.32 {$in0},[$out]
|
||||
add $out,$out,#0x50
|
||||
|
||||
mov $rounds,#10
|
||||
b .Ldone
|
||||
|
||||
.align 4
|
||||
.L192:
|
||||
vld1.8 {$in1},[$inp],#8
|
||||
vmov.i8 $key,#8 // borrow $key
|
||||
vst1.32 {$in0},[$out],#16
|
||||
vsub.i8 $mask,$mask,$key // adjust the mask
|
||||
|
||||
.Loop192:
|
||||
vtbl.8 $key,{$in1},$mask
|
||||
vext.8 $tmp,$zero,$in0,#12
|
||||
vst1.32 {$in1},[$out],#8
|
||||
aese $key,$zero
|
||||
subs $bits,$bits,#1
|
||||
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
|
||||
vdup.32 $tmp,${in0}[3]
|
||||
veor $tmp,$tmp,$in1
|
||||
veor $key,$key,$rcon
|
||||
vext.8 $in1,$zero,$in1,#12
|
||||
vshl.u8 $rcon,$rcon,#1
|
||||
veor $in1,$in1,$tmp
|
||||
veor $in0,$in0,$key
|
||||
veor $in1,$in1,$key
|
||||
vst1.32 {$in0},[$out],#16
|
||||
b.ne .Loop192
|
||||
|
||||
mov $rounds,#12
|
||||
add $out,$out,#0x20
|
||||
b .Ldone
|
||||
|
||||
.align 4
|
||||
.L256:
|
||||
vld1.8 {$in1},[$inp]
|
||||
mov $bits,#7
|
||||
mov $rounds,#14
|
||||
vst1.32 {$in0},[$out],#16
|
||||
|
||||
.Loop256:
|
||||
vtbl.8 $key,{$in1},$mask
|
||||
vext.8 $tmp,$zero,$in0,#12
|
||||
vst1.32 {$in1},[$out],#16
|
||||
aese $key,$zero
|
||||
subs $bits,$bits,#1
|
||||
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in0,$in0,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $key,$key,$rcon
|
||||
veor $in0,$in0,$tmp
|
||||
vshl.u8 $rcon,$rcon,#1
|
||||
veor $in0,$in0,$key
|
||||
vst1.32 {$in0},[$out],#16
|
||||
b.eq .Ldone
|
||||
|
||||
vdup.32 $key,${in0}[3] // just splat
|
||||
vext.8 $tmp,$zero,$in1,#12
|
||||
aese $key,$zero
|
||||
|
||||
veor $in1,$in1,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in1,$in1,$tmp
|
||||
vext.8 $tmp,$zero,$tmp,#12
|
||||
veor $in1,$in1,$tmp
|
||||
|
||||
veor $in1,$in1,$key
|
||||
b .Loop256
|
||||
|
||||
.Ldone:
|
||||
str $rounds,[$out]
|
||||
mov $ptr,#0
|
||||
|
||||
.Lenc_key_abort:
|
||||
mov x0,$ptr // return value
|
||||
`"ldr x29,[sp],#16" if ($flavour =~ /64/)`
|
||||
ret
|
||||
.size ${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key
|
||||
|
||||
.globl ${prefix}_set_decrypt_key
|
||||
.type ${prefix}_set_decrypt_key,%function
|
||||
.align 5
|
||||
${prefix}_set_decrypt_key:
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
stp x29,x30,[sp,#-16]!
|
||||
add x29,sp,#0
|
||||
___
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
stmdb sp!,{r4,lr}
|
||||
___
|
||||
$code.=<<___;
|
||||
bl .Lenc_key
|
||||
|
||||
cmp x0,#0
|
||||
b.ne .Ldec_key_abort
|
||||
|
||||
sub $out,$out,#240 // restore original $out
|
||||
mov x4,#-16
|
||||
add $inp,$out,x12,lsl#4 // end of key schedule
|
||||
|
||||
vld1.32 {v0.16b},[$out]
|
||||
vld1.32 {v1.16b},[$inp]
|
||||
vst1.32 {v0.16b},[$inp],x4
|
||||
vst1.32 {v1.16b},[$out],#16
|
||||
|
||||
.Loop_imc:
|
||||
vld1.32 {v0.16b},[$out]
|
||||
vld1.32 {v1.16b},[$inp]
|
||||
aesimc v0.16b,v0.16b
|
||||
aesimc v1.16b,v1.16b
|
||||
vst1.32 {v0.16b},[$inp],x4
|
||||
vst1.32 {v1.16b},[$out],#16
|
||||
cmp $inp,$out
|
||||
b.hi .Loop_imc
|
||||
|
||||
vld1.32 {v0.16b},[$out]
|
||||
aesimc v0.16b,v0.16b
|
||||
vst1.32 {v0.16b},[$inp]
|
||||
|
||||
eor x0,x0,x0 // return value
|
||||
.Ldec_key_abort:
|
||||
___
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
ldmia sp!,{r4,pc}
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
ldp x29,x30,[sp],#16
|
||||
ret
|
||||
___
|
||||
$code.=<<___;
|
||||
.size ${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key
|
||||
___
|
||||
}}}
|
||||
{{{
|
||||
sub gen_block () {
|
||||
my $dir = shift;
|
||||
my ($e,$mc) = $dir eq "en" ? ("e","mc") : ("d","imc");
|
||||
my ($inp,$out,$key)=map("x$_",(0..2));
|
||||
my $rounds="w3";
|
||||
my ($rndkey0,$rndkey1,$inout)=map("q$_",(0..3));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ${prefix}_${dir}crypt
|
||||
.type ${prefix}_${dir}crypt,%function
|
||||
.align 5
|
||||
${prefix}_${dir}crypt:
|
||||
ldr $rounds,[$key,#240]
|
||||
vld1.32 {$rndkey0},[$key],#16
|
||||
vld1.8 {$inout},[$inp]
|
||||
sub $rounds,$rounds,#2
|
||||
vld1.32 {$rndkey1},[$key],#16
|
||||
|
||||
.Loop_${dir}c:
|
||||
aes$e $inout,$rndkey0
|
||||
vld1.32 {$rndkey0},[$key],#16
|
||||
aes$mc $inout,$inout
|
||||
subs $rounds,$rounds,#2
|
||||
aes$e $inout,$rndkey1
|
||||
vld1.32 {$rndkey1},[$key],#16
|
||||
aes$mc $inout,$inout
|
||||
b.gt .Loop_${dir}c
|
||||
|
||||
aes$e $inout,$rndkey0
|
||||
vld1.32 {$rndkey0},[$key]
|
||||
aes$mc $inout,$inout
|
||||
aes$e $inout,$rndkey1
|
||||
veor $inout,$inout,$rndkey0
|
||||
|
||||
vst1.8 {$inout},[$out]
|
||||
ret
|
||||
.size ${prefix}_${dir}crypt,.-${prefix}_${dir}crypt
|
||||
___
|
||||
}
|
||||
&gen_block("en");
|
||||
&gen_block("de");
|
||||
}}}
|
||||
{{{
|
||||
my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5";
|
||||
my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12");
|
||||
my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
|
||||
|
||||
my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1);
|
||||
|
||||
### q8-q15 preloaded key schedule
|
||||
|
||||
$code.=<<___;
|
||||
.globl ${prefix}_cbc_encrypt
|
||||
.type ${prefix}_cbc_encrypt,%function
|
||||
.align 5
|
||||
${prefix}_cbc_encrypt:
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
stp x29,x30,[sp,#-16]!
|
||||
add x29,sp,#0
|
||||
___
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
mov ip,sp
|
||||
stmdb sp!,{r4-r8,lr}
|
||||
vstmdb sp!,{d8-d15} @ ABI specification says so
|
||||
ldmia ip,{r4-r5} @ load remaining args
|
||||
___
|
||||
$code.=<<___;
|
||||
subs $len,$len,#16
|
||||
mov $step,#16
|
||||
b.lo .Lcbc_abort
|
||||
cclr $step,eq
|
||||
|
||||
cmp $enc,#0 // en- or decrypting?
|
||||
ldr $rounds,[$key,#240]
|
||||
and $len,$len,#-16
|
||||
vld1.8 {$ivec},[$ivp]
|
||||
vld1.8 {$dat},[$inp],$step
|
||||
|
||||
vld1.32 {q8-q9},[$key] // load key schedule...
|
||||
sub $rounds,$rounds,#6
|
||||
add $key_,$key,x5,lsl#4 // pointer to last 7 round keys
|
||||
sub $rounds,$rounds,#2
|
||||
vld1.32 {q10-q11},[$key_],#32
|
||||
vld1.32 {q12-q13},[$key_],#32
|
||||
vld1.32 {q14-q15},[$key_],#32
|
||||
vld1.32 {$rndlast},[$key_]
|
||||
|
||||
add $key_,$key,#32
|
||||
mov $cnt,$rounds
|
||||
b.eq .Lcbc_dec
|
||||
|
||||
cmp $rounds,#2
|
||||
veor $dat,$dat,$ivec
|
||||
veor $rndzero_n_last,q8,$rndlast
|
||||
b.eq .Lcbc_enc128
|
||||
|
||||
.Loop_cbc_enc:
|
||||
aese $dat,q8
|
||||
vld1.32 {q8},[$key_],#16
|
||||
aesmc $dat,$dat
|
||||
subs $cnt,$cnt,#2
|
||||
aese $dat,q9
|
||||
vld1.32 {q9},[$key_],#16
|
||||
aesmc $dat,$dat
|
||||
b.gt .Loop_cbc_enc
|
||||
|
||||
aese $dat,q8
|
||||
aesmc $dat,$dat
|
||||
subs $len,$len,#16
|
||||
aese $dat,q9
|
||||
aesmc $dat,$dat
|
||||
cclr $step,eq
|
||||
aese $dat,q10
|
||||
aesmc $dat,$dat
|
||||
add $key_,$key,#16
|
||||
aese $dat,q11
|
||||
aesmc $dat,$dat
|
||||
vld1.8 {q8},[$inp],$step
|
||||
aese $dat,q12
|
||||
aesmc $dat,$dat
|
||||
veor q8,q8,$rndzero_n_last
|
||||
aese $dat,q13
|
||||
aesmc $dat,$dat
|
||||
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
|
||||
aese $dat,q14
|
||||
aesmc $dat,$dat
|
||||
aese $dat,q15
|
||||
|
||||
mov $cnt,$rounds
|
||||
veor $ivec,$dat,$rndlast
|
||||
vst1.8 {$ivec},[$out],#16
|
||||
b.hs .Loop_cbc_enc
|
||||
|
||||
b .Lcbc_done
|
||||
|
||||
.align 5
|
||||
.Lcbc_enc128:
|
||||
vld1.32 {$in0-$in1},[$key_]
|
||||
aese $dat,q8
|
||||
aesmc $dat,$dat
|
||||
b .Lenter_cbc_enc128
|
||||
.Loop_cbc_enc128:
|
||||
aese $dat,q8
|
||||
aesmc $dat,$dat
|
||||
vst1.8 {$ivec},[$out],#16
|
||||
.Lenter_cbc_enc128:
|
||||
aese $dat,q9
|
||||
aesmc $dat,$dat
|
||||
subs $len,$len,#16
|
||||
aese $dat,$in0
|
||||
aesmc $dat,$dat
|
||||
cclr $step,eq
|
||||
aese $dat,$in1
|
||||
aesmc $dat,$dat
|
||||
aese $dat,q10
|
||||
aesmc $dat,$dat
|
||||
aese $dat,q11
|
||||
aesmc $dat,$dat
|
||||
vld1.8 {q8},[$inp],$step
|
||||
aese $dat,q12
|
||||
aesmc $dat,$dat
|
||||
aese $dat,q13
|
||||
aesmc $dat,$dat
|
||||
aese $dat,q14
|
||||
aesmc $dat,$dat
|
||||
veor q8,q8,$rndzero_n_last
|
||||
aese $dat,q15
|
||||
veor $ivec,$dat,$rndlast
|
||||
b.hs .Loop_cbc_enc128
|
||||
|
||||
vst1.8 {$ivec},[$out],#16
|
||||
b .Lcbc_done
|
||||
___
|
||||
{
|
||||
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
|
||||
$code.=<<___;
|
||||
.align 5
|
||||
.Lcbc_dec:
|
||||
vld1.8 {$dat2},[$inp],#16
|
||||
subs $len,$len,#32 // bias
|
||||
add $cnt,$rounds,#2
|
||||
vorr $in1,$dat,$dat
|
||||
vorr $dat1,$dat,$dat
|
||||
vorr $in2,$dat2,$dat2
|
||||
b.lo .Lcbc_dec_tail
|
||||
|
||||
vorr $dat1,$dat2,$dat2
|
||||
vld1.8 {$dat2},[$inp],#16
|
||||
vorr $in0,$dat,$dat
|
||||
vorr $in1,$dat1,$dat1
|
||||
vorr $in2,$dat2,$dat2
|
||||
|
||||
.Loop3x_cbc_dec:
|
||||
aesd $dat0,q8
|
||||
aesd $dat1,q8
|
||||
aesd $dat2,q8
|
||||
vld1.32 {q8},[$key_],#16
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
subs $cnt,$cnt,#2
|
||||
aesd $dat0,q9
|
||||
aesd $dat1,q9
|
||||
aesd $dat2,q9
|
||||
vld1.32 {q9},[$key_],#16
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
b.gt .Loop3x_cbc_dec
|
||||
|
||||
aesd $dat0,q8
|
||||
aesd $dat1,q8
|
||||
aesd $dat2,q8
|
||||
veor $tmp0,$ivec,$rndlast
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
veor $tmp1,$in0,$rndlast
|
||||
aesd $dat0,q9
|
||||
aesd $dat1,q9
|
||||
aesd $dat2,q9
|
||||
veor $tmp2,$in1,$rndlast
|
||||
subs $len,$len,#0x30
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
vorr $ivec,$in2,$in2
|
||||
mov.lo x6,$len // x6, $cnt, is zero at this point
|
||||
aesd $dat0,q12
|
||||
aesd $dat1,q12
|
||||
aesd $dat2,q12
|
||||
add $inp,$inp,x6 // $inp is adjusted in such way that
|
||||
// at exit from the loop $dat1-$dat2
|
||||
// are loaded with last "words"
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
mov $key_,$key
|
||||
aesd $dat0,q13
|
||||
aesd $dat1,q13
|
||||
aesd $dat2,q13
|
||||
vld1.8 {$in0},[$inp],#16
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
vld1.8 {$in1},[$inp],#16
|
||||
aesd $dat0,q14
|
||||
aesd $dat1,q14
|
||||
aesd $dat2,q14
|
||||
vld1.8 {$in2},[$inp],#16
|
||||
aesimc $dat0,$dat0
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
|
||||
aesd $dat0,q15
|
||||
aesd $dat1,q15
|
||||
aesd $dat2,q15
|
||||
|
||||
add $cnt,$rounds,#2
|
||||
veor $tmp0,$tmp0,$dat0
|
||||
veor $tmp1,$tmp1,$dat1
|
||||
veor $dat2,$dat2,$tmp2
|
||||
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
|
||||
vorr $dat0,$in0,$in0
|
||||
vst1.8 {$tmp0},[$out],#16
|
||||
vorr $dat1,$in1,$in1
|
||||
vst1.8 {$tmp1},[$out],#16
|
||||
vst1.8 {$dat2},[$out],#16
|
||||
vorr $dat2,$in2,$in2
|
||||
b.hs .Loop3x_cbc_dec
|
||||
|
||||
cmn $len,#0x30
|
||||
b.eq .Lcbc_done
|
||||
nop
|
||||
|
||||
.Lcbc_dec_tail:
|
||||
aesd $dat1,q8
|
||||
aesd $dat2,q8
|
||||
vld1.32 {q8},[$key_],#16
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
subs $cnt,$cnt,#2
|
||||
aesd $dat1,q9
|
||||
aesd $dat2,q9
|
||||
vld1.32 {q9},[$key_],#16
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
b.gt .Lcbc_dec_tail
|
||||
|
||||
aesd $dat1,q8
|
||||
aesd $dat2,q8
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
aesd $dat1,q9
|
||||
aesd $dat2,q9
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
aesd $dat1,q12
|
||||
aesd $dat2,q12
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
cmn $len,#0x20
|
||||
aesd $dat1,q13
|
||||
aesd $dat2,q13
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
veor $tmp1,$ivec,$rndlast
|
||||
aesd $dat1,q14
|
||||
aesd $dat2,q14
|
||||
aesimc $dat1,$dat1
|
||||
aesimc $dat2,$dat2
|
||||
veor $tmp2,$in1,$rndlast
|
||||
aesd $dat1,q15
|
||||
aesd $dat2,q15
|
||||
b.eq .Lcbc_dec_one
|
||||
veor $tmp1,$tmp1,$dat1
|
||||
veor $tmp2,$tmp2,$dat2
|
||||
vorr $ivec,$in2,$in2
|
||||
vst1.8 {$tmp1},[$out],#16
|
||||
vst1.8 {$tmp2},[$out],#16
|
||||
b .Lcbc_done
|
||||
|
||||
.Lcbc_dec_one:
|
||||
veor $tmp1,$tmp1,$dat2
|
||||
vorr $ivec,$in2,$in2
|
||||
vst1.8 {$tmp1},[$out],#16
|
||||
|
||||
.Lcbc_done:
|
||||
vst1.8 {$ivec},[$ivp]
|
||||
.Lcbc_abort:
|
||||
___
|
||||
}
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
vldmia sp!,{d8-d15}
|
||||
ldmia sp!,{r4-r8,pc}
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
ldr x29,[sp],#16
|
||||
ret
|
||||
___
|
||||
$code.=<<___;
|
||||
.size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
|
||||
___
|
||||
}}}
|
||||
{{{
|
||||
my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
|
||||
my ($rounds,$cnt,$key_)=("w5","w6","x7");
|
||||
my ($ctr,$tctr0,$tctr1,$tctr2)=map("w$_",(8..10,12));
|
||||
my $step="x12"; # aliases with $tctr2
|
||||
|
||||
my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
|
||||
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
|
||||
|
||||
my ($dat,$tmp)=($dat0,$tmp0);
|
||||
|
||||
### q8-q15 preloaded key schedule
|
||||
|
||||
$code.=<<___;
|
||||
.globl ${prefix}_ctr32_encrypt_blocks
|
||||
.type ${prefix}_ctr32_encrypt_blocks,%function
|
||||
.align 5
|
||||
${prefix}_ctr32_encrypt_blocks:
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
stp x29,x30,[sp,#-16]!
|
||||
add x29,sp,#0
|
||||
___
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
mov ip,sp
|
||||
stmdb sp!,{r4-r10,lr}
|
||||
vstmdb sp!,{d8-d15} @ ABI specification says so
|
||||
ldr r4, [ip] @ load remaining arg
|
||||
___
|
||||
$code.=<<___;
|
||||
ldr $rounds,[$key,#240]
|
||||
|
||||
ldr $ctr, [$ivp, #12]
|
||||
vld1.32 {$dat0},[$ivp]
|
||||
|
||||
vld1.32 {q8-q9},[$key] // load key schedule...
|
||||
sub $rounds,$rounds,#4
|
||||
mov $step,#16
|
||||
cmp $len,#2
|
||||
add $key_,$key,x5,lsl#4 // pointer to last 5 round keys
|
||||
sub $rounds,$rounds,#2
|
||||
vld1.32 {q12-q13},[$key_],#32
|
||||
vld1.32 {q14-q15},[$key_],#32
|
||||
vld1.32 {$rndlast},[$key_]
|
||||
add $key_,$key,#32
|
||||
mov $cnt,$rounds
|
||||
cclr $step,lo
|
||||
#ifndef __ARMEB__
|
||||
rev $ctr, $ctr
|
||||
#endif
|
||||
vorr $dat1,$dat0,$dat0
|
||||
add $tctr1, $ctr, #1
|
||||
vorr $dat2,$dat0,$dat0
|
||||
add $ctr, $ctr, #2
|
||||
vorr $ivec,$dat0,$dat0
|
||||
rev $tctr1, $tctr1
|
||||
vmov.32 ${dat1}[3],$tctr1
|
||||
b.ls .Lctr32_tail
|
||||
rev $tctr2, $ctr
|
||||
sub $len,$len,#3 // bias
|
||||
vmov.32 ${dat2}[3],$tctr2
|
||||
b .Loop3x_ctr32
|
||||
|
||||
.align 4
|
||||
.Loop3x_ctr32:
|
||||
aese $dat0,q8
|
||||
aese $dat1,q8
|
||||
aese $dat2,q8
|
||||
vld1.32 {q8},[$key_],#16
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
aesmc $dat2,$dat2
|
||||
subs $cnt,$cnt,#2
|
||||
aese $dat0,q9
|
||||
aese $dat1,q9
|
||||
aese $dat2,q9
|
||||
vld1.32 {q9},[$key_],#16
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
aesmc $dat2,$dat2
|
||||
b.gt .Loop3x_ctr32
|
||||
|
||||
aese $dat0,q8
|
||||
aese $dat1,q8
|
||||
aese $dat2,q8
|
||||
mov $key_,$key
|
||||
aesmc $tmp0,$dat0
|
||||
vld1.8 {$in0},[$inp],#16
|
||||
aesmc $tmp1,$dat1
|
||||
aesmc $dat2,$dat2
|
||||
vorr $dat0,$ivec,$ivec
|
||||
aese $tmp0,q9
|
||||
vld1.8 {$in1},[$inp],#16
|
||||
aese $tmp1,q9
|
||||
aese $dat2,q9
|
||||
vorr $dat1,$ivec,$ivec
|
||||
aesmc $tmp0,$tmp0
|
||||
vld1.8 {$in2},[$inp],#16
|
||||
aesmc $tmp1,$tmp1
|
||||
aesmc $tmp2,$dat2
|
||||
vorr $dat2,$ivec,$ivec
|
||||
add $tctr0,$ctr,#1
|
||||
aese $tmp0,q12
|
||||
aese $tmp1,q12
|
||||
aese $tmp2,q12
|
||||
veor $in0,$in0,$rndlast
|
||||
add $tctr1,$ctr,#2
|
||||
aesmc $tmp0,$tmp0
|
||||
aesmc $tmp1,$tmp1
|
||||
aesmc $tmp2,$tmp2
|
||||
veor $in1,$in1,$rndlast
|
||||
add $ctr,$ctr,#3
|
||||
aese $tmp0,q13
|
||||
aese $tmp1,q13
|
||||
aese $tmp2,q13
|
||||
veor $in2,$in2,$rndlast
|
||||
rev $tctr0,$tctr0
|
||||
aesmc $tmp0,$tmp0
|
||||
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
|
||||
aesmc $tmp1,$tmp1
|
||||
aesmc $tmp2,$tmp2
|
||||
vmov.32 ${dat0}[3], $tctr0
|
||||
rev $tctr1,$tctr1
|
||||
aese $tmp0,q14
|
||||
aese $tmp1,q14
|
||||
aese $tmp2,q14
|
||||
vmov.32 ${dat1}[3], $tctr1
|
||||
rev $tctr2,$ctr
|
||||
aesmc $tmp0,$tmp0
|
||||
aesmc $tmp1,$tmp1
|
||||
aesmc $tmp2,$tmp2
|
||||
vmov.32 ${dat2}[3], $tctr2
|
||||
subs $len,$len,#3
|
||||
aese $tmp0,q15
|
||||
aese $tmp1,q15
|
||||
aese $tmp2,q15
|
||||
|
||||
mov $cnt,$rounds
|
||||
veor $in0,$in0,$tmp0
|
||||
veor $in1,$in1,$tmp1
|
||||
veor $in2,$in2,$tmp2
|
||||
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
|
||||
vst1.8 {$in0},[$out],#16
|
||||
vst1.8 {$in1},[$out],#16
|
||||
vst1.8 {$in2},[$out],#16
|
||||
b.hs .Loop3x_ctr32
|
||||
|
||||
adds $len,$len,#3
|
||||
b.eq .Lctr32_done
|
||||
cmp $len,#1
|
||||
mov $step,#16
|
||||
cclr $step,eq
|
||||
|
||||
.Lctr32_tail:
|
||||
aese $dat0,q8
|
||||
aese $dat1,q8
|
||||
vld1.32 {q8},[$key_],#16
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
subs $cnt,$cnt,#2
|
||||
aese $dat0,q9
|
||||
aese $dat1,q9
|
||||
vld1.32 {q9},[$key_],#16
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
b.gt .Lctr32_tail
|
||||
|
||||
aese $dat0,q8
|
||||
aese $dat1,q8
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
aese $dat0,q9
|
||||
aese $dat1,q9
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
vld1.8 {$in0},[$inp],$step
|
||||
aese $dat0,q12
|
||||
aese $dat1,q12
|
||||
vld1.8 {$in1},[$inp]
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
aese $dat0,q13
|
||||
aese $dat1,q13
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
aese $dat0,q14
|
||||
aese $dat1,q14
|
||||
veor $in0,$in0,$rndlast
|
||||
aesmc $dat0,$dat0
|
||||
aesmc $dat1,$dat1
|
||||
veor $in1,$in1,$rndlast
|
||||
aese $dat0,q15
|
||||
aese $dat1,q15
|
||||
|
||||
cmp $len,#1
|
||||
veor $in0,$in0,$dat0
|
||||
veor $in1,$in1,$dat1
|
||||
vst1.8 {$in0},[$out],#16
|
||||
b.eq .Lctr32_done
|
||||
vst1.8 {$in1},[$out]
|
||||
|
||||
.Lctr32_done:
|
||||
___
|
||||
$code.=<<___ if ($flavour !~ /64/);
|
||||
vldmia sp!,{d8-d15}
|
||||
ldmia sp!,{r4-r10,pc}
|
||||
___
|
||||
$code.=<<___ if ($flavour =~ /64/);
|
||||
ldr x29,[sp],#16
|
||||
ret
|
||||
___
|
||||
$code.=<<___;
|
||||
.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks
|
||||
___
|
||||
}}}
|
||||
$code.=<<___;
|
||||
#endif
|
||||
___
|
||||
########################################
|
||||
if ($flavour =~ /64/) { ######## 64-bit code
|
||||
my %opcode = (
|
||||
"aesd" => 0x4e285800, "aese" => 0x4e284800,
|
||||
"aesimc"=> 0x4e287800, "aesmc" => 0x4e286800 );
|
||||
|
||||
local *unaes = sub {
|
||||
my ($mnemonic,$arg)=@_;
|
||||
|
||||
$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o &&
|
||||
sprintf ".inst\t0x%08x\t//%s %s",
|
||||
$opcode{$mnemonic}|$1|($2<<5),
|
||||
$mnemonic,$arg;
|
||||
};
|
||||
|
||||
foreach(split("\n",$code)) {
|
||||
s/\`([^\`]*)\`/eval($1)/geo;
|
||||
|
||||
s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo; # old->new registers
|
||||
s/@\s/\/\//o; # old->new style commentary
|
||||
|
||||
#s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
|
||||
s/cclr\s+([wx])([^,]+),\s*([a-z]+)/csel $1$2,$1zr,$1$2,$3/o or
|
||||
s/mov\.([a-z]+)\s+([wx][0-9]+),\s*([wx][0-9]+)/csel $2,$3,$2,$1/o or
|
||||
s/vmov\.i8/movi/o or # fix up legacy mnemonics
|
||||
s/vext\.8/ext/o or
|
||||
s/vrev32\.8/rev32/o or
|
||||
s/vtst\.8/cmtst/o or
|
||||
s/vshr/ushr/o or
|
||||
s/^(\s+)v/$1/o or # strip off v prefix
|
||||
s/\bbx\s+lr\b/ret/o;
|
||||
|
||||
# fix up remainig legacy suffixes
|
||||
s/\.[ui]?8//o;
|
||||
m/\],#8/o and s/\.16b/\.8b/go;
|
||||
s/\.[ui]?32//o and s/\.16b/\.4s/go;
|
||||
s/\.[ui]?64//o and s/\.16b/\.2d/go;
|
||||
s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o;
|
||||
|
||||
print $_,"\n";
|
||||
}
|
||||
} else { ######## 32-bit code
|
||||
my %opcode = (
|
||||
"aesd" => 0xf3b00340, "aese" => 0xf3b00300,
|
||||
"aesimc"=> 0xf3b003c0, "aesmc" => 0xf3b00380 );
|
||||
|
||||
local *unaes = sub {
|
||||
my ($mnemonic,$arg)=@_;
|
||||
|
||||
if ($arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o) {
|
||||
my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
|
||||
|(($2&7)<<1) |(($2&8)<<2);
|
||||
# since ARMv7 instructions are always encoded little-endian.
|
||||
# correct solution is to use .inst directive, but older
|
||||
# assemblers don't implement it:-(
|
||||
sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
|
||||
$word&0xff,($word>>8)&0xff,
|
||||
($word>>16)&0xff,($word>>24)&0xff,
|
||||
$mnemonic,$arg;
|
||||
}
|
||||
};
|
||||
|
||||
sub unvtbl {
|
||||
my $arg=shift;
|
||||
|
||||
$arg =~ m/q([0-9]+),\s*\{q([0-9]+)\},\s*q([0-9]+)/o &&
|
||||
sprintf "vtbl.8 d%d,{q%d},d%d\n\t".
|
||||
"vtbl.8 d%d,{q%d},d%d", 2*$1,$2,2*$3, 2*$1+1,$2,2*$3+1;
|
||||
}
|
||||
|
||||
sub unvdup32 {
|
||||
my $arg=shift;
|
||||
|
||||
$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
|
||||
sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
|
||||
}
|
||||
|
||||
sub unvmov32 {
|
||||
my $arg=shift;
|
||||
|
||||
$arg =~ m/q([0-9]+)\[([0-3])\],(.*)/o &&
|
||||
sprintf "vmov.32 d%d[%d],%s",2*$1+($2>>1),$2&1,$3;
|
||||
}
|
||||
|
||||
foreach(split("\n",$code)) {
|
||||
s/\`([^\`]*)\`/eval($1)/geo;
|
||||
|
||||
s/\b[wx]([0-9]+)\b/r$1/go; # new->old registers
|
||||
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
|
||||
s/\{q([0-9]+)\},\s*\[(.+)\],#8/sprintf "{d%d},[$2]!",2*$1/eo or
|
||||
s/\],#[0-9]+/]!/o;
|
||||
|
||||
s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
|
||||
s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or
|
||||
s/vtbl\.8\s+(.*)/unvtbl($1)/geo or
|
||||
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
|
||||
s/vmov\.32\s+(.*)/unvmov32($1)/geo or
|
||||
s/^(\s+)b\./$1b/o or
|
||||
s/^(\s+)mov\./$1mov/o or
|
||||
s/^(\s+)ret/$1bx\tlr/o;
|
||||
|
||||
print $_,"\n";
|
||||
}
|
||||
}
|
||||
|
||||
close STDOUT;
|
||||
@@ -40,6 +40,7 @@
|
||||
# Core 2 9.30 8.69 +7%
|
||||
# Nehalem(**) 7.63 6.88 +11%
|
||||
# Atom 17.1 16.4 +4%
|
||||
# Silvermont - 12.9
|
||||
#
|
||||
# (*) Comparison is not completely fair, because "this" is ECB,
|
||||
# i.e. no extra processing such as counter values calculation
|
||||
@@ -78,6 +79,7 @@
|
||||
# Core 2 9.98
|
||||
# Nehalem 7.80
|
||||
# Atom 17.9
|
||||
# Silvermont 14.0
|
||||
#
|
||||
# November 2011.
|
||||
#
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
# Core 2(**) 28.1/41.4/18.3 21.9/25.2(***)
|
||||
# Nehalem 27.9/40.4/18.1 10.2/11.9
|
||||
# Atom 70.7/92.1/60.1 61.1/75.4(***)
|
||||
# Silvermont 45.4/62.9/24.1 49.2/61.1(***)
|
||||
#
|
||||
# (*) "Hyper-threading" in the context refers rather to cache shared
|
||||
# among multiple cores, than to specifically Intel HTT. As vast
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
# Core 2(**) 29.6/41.1/14.3 21.9/25.2(***)
|
||||
# Nehalem 29.6/40.3/14.6 10.0/11.8
|
||||
# Atom 57.3/74.2/32.1 60.9/77.2(***)
|
||||
# Silvermont 52.7/64.0/19.5 48.8/60.8(***)
|
||||
#
|
||||
# (*) "Hyper-threading" in the context refers rather to cache shared
|
||||
# among multiple cores, than to specifically Intel HTT. As vast
|
||||
|
||||
+30
-3
@@ -62,11 +62,22 @@
|
||||
# define __ARMEL__
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# if defined(__aarch64__)
|
||||
# define __ARM_ARCH__ 8
|
||||
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define __ARMEB__
|
||||
# else
|
||||
# define __ARMEL__
|
||||
# endif
|
||||
/* Why doesn't gcc define __ARM_ARCH__? Instead it defines
|
||||
* bunch of below macros. See all_architectires[] table in
|
||||
* gcc/config/arm/arm.c. On a side note it defines
|
||||
* __ARMEL__/__ARMEB__ for little-/big-endian. */
|
||||
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
|
||||
# elif defined(__ARM_ARCH)
|
||||
# define __ARM_ARCH__ __ARM_ARCH
|
||||
# elif defined(__ARM_ARCH_8A__)
|
||||
# define __ARM_ARCH__ 8
|
||||
# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
|
||||
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
|
||||
defined(__ARM_ARCH_7EM__)
|
||||
# define __ARM_ARCH__ 7
|
||||
@@ -87,6 +98,10 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Even when building for 32-bit ARM, support for aarch64 crypto instructions
|
||||
* will be included. */
|
||||
#define __ARM_MAX_ARCH__ 8
|
||||
|
||||
#if !__ASSEMBLER__
|
||||
|
||||
/* OPENSSL_armcap_P contains flags describing the capabilities of the CPU and
|
||||
@@ -94,6 +109,8 @@
|
||||
* |cpu.h|. */
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
|
||||
#define ARMV7_NEON (1 << 0)
|
||||
|
||||
@@ -101,9 +118,19 @@ extern uint32_t OPENSSL_armcap_P;
|
||||
* The Poly1305 NEON code is known to trigger bugs in the NEON units of some
|
||||
* phones. If this bit isn't set then the Poly1305 NEON code won't be used.
|
||||
* See https://code.google.com/p/chromium/issues/detail?id=341598. */
|
||||
#define ARMV7_NEON_FUNCTIONAL (1 << 1)
|
||||
#define ARMV7_NEON_FUNCTIONAL (1 << 10)
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
/* ARMV8_AES indicates support for hardware AES instructions. */
|
||||
#define ARMV8_AES (1 << 2)
|
||||
|
||||
/* ARMV8_SHA1 indicates support for hardware SHA-1 instructions. */
|
||||
#define ARMV8_SHA1 (1 << 3)
|
||||
|
||||
/* ARMV8_SHA256 indicates support for hardware SHA-256 instructions. */
|
||||
#define ARMV8_SHA256 (1 << 4)
|
||||
|
||||
/* ARMV8_PMULL indicates support for carryless multiplication. */
|
||||
#define ARMV8_PMULL (1 << 5)
|
||||
|
||||
|
||||
#endif /* OPENSSL_HEADER_THREAD_H */
|
||||
|
||||
+39
-40
@@ -1,46 +1,45 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
asn1
|
||||
asn1
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
a_bitstr.c
|
||||
a_bool.c
|
||||
a_bytes.c
|
||||
a_d2i_fp.c
|
||||
a_dup.c
|
||||
a_enum.c
|
||||
a_gentm.c
|
||||
a_i2d_fp.c
|
||||
a_int.c
|
||||
a_mbstr.c
|
||||
a_object.c
|
||||
a_octet.c
|
||||
a_print.c
|
||||
a_strnid.c
|
||||
a_time.c
|
||||
a_type.c
|
||||
a_utctm.c
|
||||
a_utf8.c
|
||||
asn1_error.c
|
||||
asn1_lib.c
|
||||
asn1_par.c
|
||||
asn_pack.c
|
||||
bio_asn1.c
|
||||
bio_ndef.c
|
||||
f_enum.c
|
||||
f_int.c
|
||||
f_string.c
|
||||
t_bitst.c
|
||||
t_pkey.c
|
||||
tasn_dec.c
|
||||
tasn_enc.c
|
||||
tasn_fre.c
|
||||
tasn_new.c
|
||||
tasn_prn.c
|
||||
tasn_typ.c
|
||||
tasn_utl.c
|
||||
x_bignum.c
|
||||
x_long.c
|
||||
a_bitstr.c
|
||||
a_bool.c
|
||||
a_bytes.c
|
||||
a_d2i_fp.c
|
||||
a_dup.c
|
||||
a_enum.c
|
||||
a_gentm.c
|
||||
a_i2d_fp.c
|
||||
a_int.c
|
||||
a_mbstr.c
|
||||
a_object.c
|
||||
a_octet.c
|
||||
a_print.c
|
||||
a_strnid.c
|
||||
a_time.c
|
||||
a_type.c
|
||||
a_utctm.c
|
||||
a_utf8.c
|
||||
asn1_lib.c
|
||||
asn1_par.c
|
||||
asn_pack.c
|
||||
bio_asn1.c
|
||||
bio_ndef.c
|
||||
f_enum.c
|
||||
f_int.c
|
||||
f_string.c
|
||||
t_bitst.c
|
||||
t_pkey.c
|
||||
tasn_dec.c
|
||||
tasn_enc.c
|
||||
tasn_fre.c
|
||||
tasn_new.c
|
||||
tasn_prn.c
|
||||
tasn_typ.c
|
||||
tasn_utl.c
|
||||
x_bignum.c
|
||||
x_long.c
|
||||
)
|
||||
|
||||
+18
-7
@@ -56,9 +56,12 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
||||
{ return M_ASN1_BIT_STRING_set(x, d, len); }
|
||||
|
||||
@@ -118,11 +121,12 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
ASN1_BIT_STRING *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
int i;
|
||||
int padding;
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
i=ASN1_R_STRING_TOO_SHORT;
|
||||
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
|
||||
ASN1_R_STRING_TOO_SHORT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -134,23 +138,31 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
ret=(*a);
|
||||
|
||||
p= *pp;
|
||||
i= *(p++);
|
||||
padding = *(p++);
|
||||
if (padding > 7)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
|
||||
ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We do this to preserve the settings. If we modify
|
||||
* the settings, via the _set_bit function, we will recalculate
|
||||
* on output */
|
||||
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
|
||||
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
|
||||
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|padding); /* set */
|
||||
|
||||
if (len-- > 1) /* using one because of the bits left byte */
|
||||
{
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
memcpy(s,p,(int)len);
|
||||
s[len-1]&=(0xff<<i);
|
||||
s[len-1]&=(0xff<<padding);
|
||||
p+=len;
|
||||
}
|
||||
else
|
||||
@@ -164,7 +176,6 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_BIT_STRING_free(ret);
|
||||
return(NULL);
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/time_support.h>
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <stdlib.h> /* For bsearch */
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -111,7 +111,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
|
||||
}
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
|
||||
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/time_support.h>
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/* Copyright (c) 2014, 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/err.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
const ERR_STRING_DATA ASN1_error_string_data[] = {
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIT_STRING_set_bit, 0), "ASN1_BIT_STRING_set_bit"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ENUMERATED_set, 0), "ASN1_ENUMERATED_set"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ENUMERATED_to_BN, 0), "ASN1_ENUMERATED_to_BN"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERALIZEDTIME_adj, 0), "ASN1_GENERALIZEDTIME_adj"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_INTEGER_set, 0), "ASN1_INTEGER_set"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_INTEGER_to_BN, 0), "ASN1_INTEGER_to_BN"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OBJECT_new, 0), "ASN1_OBJECT_new"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PCTX_new, 0), "ASN1_PCTX_new"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TABLE_add, 0), "ASN1_STRING_TABLE_add"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_set, 0), "ASN1_STRING_set"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_type_new, 0), "ASN1_STRING_type_new"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TIME_adj, 0), "ASN1_TIME_adj"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_UTCTIME_adj, 0), "ASN1_UTCTIME_adj"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_d2i_fp, 0), "ASN1_d2i_fp"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_dup, 0), "ASN1_dup"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_get_object, 0), "ASN1_get_object"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_i2d_bio, 0), "ASN1_i2d_bio"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_i2d_fp, 0), "ASN1_i2d_fp"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_d2i_fp, 0), "ASN1_item_d2i_fp"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_dup, 0), "ASN1_item_dup"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_ex_d2i, 0), "ASN1_item_ex_d2i"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_i2d_bio, 0), "ASN1_item_i2d_bio"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_i2d_fp, 0), "ASN1_item_i2d_fp"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_pack, 0), "ASN1_item_pack"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_item_unpack, 0), "ASN1_item_unpack"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_mbstring_ncopy, 0), "ASN1_mbstring_ncopy"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_pack_string, 0), "ASN1_pack_string"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_seq_pack, 0), "ASN1_seq_pack"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_seq_unpack, 0), "ASN1_seq_unpack"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_template_new, 0), "ASN1_template_new"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_unpack_string, 0), "ASN1_unpack_string"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_BIO_new_NDEF, 0), "BIO_new_NDEF"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_BN_to_ASN1_ENUMERATED, 0), "BN_to_ASN1_ENUMERATED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_BN_to_ASN1_INTEGER, 0), "BN_to_ASN1_INTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_a2d_ASN1_OBJECT, 0), "a2d_ASN1_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_a2i_ASN1_ENUMERATED, 0), "a2i_ASN1_ENUMERATED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_a2i_ASN1_INTEGER, 0), "a2i_ASN1_INTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_a2i_ASN1_STRING, 0), "a2i_ASN1_STRING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_check_tlen, 0), "asn1_check_tlen"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_collate_primitive, 0), "asn1_collate_primitive"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_collect, 0), "asn1_collect"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_d2i_ex_primitive, 0), "asn1_d2i_ex_primitive"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_d2i_read_bio, 0), "asn1_d2i_read_bio"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_do_adb, 0), "asn1_do_adb"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_ex_c2i, 0), "asn1_ex_c2i"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_find_end, 0), "asn1_find_end"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_item_ex_combine_new, 0), "asn1_item_ex_combine_new"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_template_ex_d2i, 0), "asn1_template_ex_d2i"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_asn1_template_noexp_d2i, 0), "asn1_template_noexp_d2i"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_c2i_ASN1_BIT_STRING, 0), "c2i_ASN1_BIT_STRING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_c2i_ASN1_INTEGER, 0), "c2i_ASN1_INTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_c2i_ASN1_OBJECT, 0), "c2i_ASN1_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_collect_data, 0), "collect_data"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_BOOLEAN, 0), "d2i_ASN1_BOOLEAN"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_OBJECT, 0), "d2i_ASN1_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_UINTEGER, 0), "d2i_ASN1_UINTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_UTCTIME, 0), "d2i_ASN1_UTCTIME"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_bytes, 0), "d2i_ASN1_bytes"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_d2i_ASN1_type_bytes, 0), "d2i_ASN1_type_bytes"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_i2d_ASN1_TIME, 0), "i2d_ASN1_TIME"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, ASN1_F_long_c2i, 0), "long_c2i"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ADDING_OBJECT), "ADDING_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_LENGTH_MISMATCH), "ASN1_LENGTH_MISMATCH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_PARSE_ERROR), "ASN1_PARSE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_SIG_PARSE_ERROR), "ASN1_SIG_PARSE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_AUX_ERROR), "AUX_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_CLASS), "BAD_CLASS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_GET_ASN1_OBJECT_CALL), "BAD_GET_ASN1_OBJECT_CALL"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_OBJECT_HEADER), "BAD_OBJECT_HEADER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_PASSWORD_READ), "BAD_PASSWORD_READ"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_TAG), "BAD_TAG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "BMPSTRING_IS_WRONG_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BN_LIB), "BN_LIB"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "BOOLEAN_IS_WRONG_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BUFFER_TOO_SMALL), "BUFFER_TOO_SMALL"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "CIPHER_HAS_NO_OBJECT_IDENTIFIER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CONTEXT_NOT_INITIALISED), "CONTEXT_NOT_INITIALISED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DATA_IS_WRONG), "DATA_IS_WRONG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DECODE_ERROR), "DECODE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DECODING_ERROR), "DECODING_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DEPTH_EXCEEDED), "DEPTH_EXCEEDED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ENCODE_ERROR), "ENCODE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_GETTING_TIME), "ERROR_GETTING_TIME"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_LOADING_SECTION), "ERROR_LOADING_SECTION"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_PARSING_SET_ELEMENT), "ERROR_PARSING_SET_ELEMENT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_SETTING_CIPHER_PARAMS), "ERROR_SETTING_CIPHER_PARAMS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_ASN1_SEQUENCE), "EXPECTING_AN_ASN1_SEQUENCE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_INTEGER), "EXPECTING_AN_INTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_OBJECT), "EXPECTING_AN_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_A_BOOLEAN), "EXPECTING_A_BOOLEAN"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_A_TIME), "EXPECTING_A_TIME"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_LENGTH_MISMATCH), "EXPLICIT_LENGTH_MISMATCH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), "EXPLICIT_TAG_NOT_CONSTRUCTED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIELD_MISSING), "FIELD_MISSING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIRST_NUM_TOO_LARGE), "FIRST_NUM_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG), "HEADER_TOO_LONG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BITSTRING_FORMAT), "ILLEGAL_BITSTRING_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BOOLEAN), "ILLEGAL_BOOLEAN"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_CHARACTERS), "ILLEGAL_CHARACTERS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_FORMAT), "ILLEGAL_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_HEX), "ILLEGAL_HEX"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_IMPLICIT_TAG), "ILLEGAL_IMPLICIT_TAG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_INTEGER), "ILLEGAL_INTEGER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NESTED_TAGGING), "ILLEGAL_NESTED_TAGGING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL), "ILLEGAL_NULL"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL_VALUE), "ILLEGAL_NULL_VALUE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OBJECT), "ILLEGAL_OBJECT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONAL_ANY), "ILLEGAL_OPTIONAL_ANY"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TAGGED_ANY), "ILLEGAL_TAGGED_ANY"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TIME_VALUE), "ILLEGAL_TIME_VALUE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_NOT_ASCII_FORMAT), "INTEGER_NOT_ASCII_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), "INTEGER_TOO_LARGE_FOR_LONG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BMPSTRING_LENGTH), "INVALID_BMPSTRING_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_DIGIT), "INVALID_DIGIT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MIME_TYPE), "INVALID_MIME_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MODIFIER), "INVALID_MODIFIER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_NUMBER), "INVALID_NUMBER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_OBJECT_ENCODING), "INVALID_OBJECT_ENCODING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_SEPARATOR), "INVALID_SEPARATOR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_TIME_FORMAT), "INVALID_TIME_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), "INVALID_UNIVERSALSTRING_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UTF8STRING), "INVALID_UTF8STRING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_IV_TOO_LARGE), "IV_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LENGTH_ERROR), "LENGTH_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LIST_ERROR), "LIST_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MALLOC_FAILURE), "MALLOC_FAILURE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_NO_CONTENT_TYPE), "MIME_NO_CONTENT_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_PARSE_ERROR), "MIME_PARSE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_SIG_PARSE_ERROR), "MIME_SIG_PARSE_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_ASN1_EOS), "MISSING_ASN1_EOS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_EOC), "MISSING_EOC"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_SECOND_NUMBER), "MISSING_SECOND_NUMBER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_VALUE), "MISSING_VALUE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_NOT_UNIVERSAL), "MSTRING_NOT_UNIVERSAL"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_WRONG_TAG), "MSTRING_WRONG_TAG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_ASN1_ERROR), "NESTED_ASN1_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_ASN1_STRING), "NESTED_ASN1_STRING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NON_HEX_CHARACTERS), "NON_HEX_CHARACTERS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ASCII_FORMAT), "NOT_ASCII_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ENOUGH_DATA), "NOT_ENOUGH_DATA"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_CONTENT_TYPE), "NO_CONTENT_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_DEFAULT_DIGEST), "NO_DEFAULT_DIGEST"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MATCHING_CHOICE_TYPE), "NO_MATCHING_CHOICE_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BODY_FAILURE), "NO_MULTIPART_BODY_FAILURE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BOUNDARY), "NO_MULTIPART_BOUNDARY"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_SIG_CONTENT_TYPE), "NO_SIG_CONTENT_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NULL_IS_WRONG_LENGTH), "NULL_IS_WRONG_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_OBJECT_NOT_ASCII_FORMAT), "OBJECT_NOT_ASCII_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ODD_NUMBER_OF_CHARS), "ODD_NUMBER_OF_CHARS"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_PRIVATE_KEY_HEADER_MISSING), "PRIVATE_KEY_HEADER_MISSING"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SECOND_NUMBER_TOO_LARGE), "SECOND_NUMBER_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_LENGTH_MISMATCH), "SEQUENCE_LENGTH_MISMATCH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "SEQUENCE_NOT_CONSTRUCTED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), "SEQUENCE_OR_SET_NEEDS_CONFIG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SHORT_LINE), "SHORT_LINE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SIG_INVALID_MIME_TYPE), "SIG_INVALID_MIME_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STREAMING_NOT_SUPPORTED), "STREAMING_NOT_SUPPORTED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_LONG), "STRING_TOO_LONG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_SHORT), "STRING_TOO_SHORT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TAG_VALUE_TOO_HIGH), "TAG_VALUE_TOO_HIGH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), "THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TIME_NOT_ASCII_FORMAT), "TIME_NOT_ASCII_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LONG), "TOO_LONG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TYPE_NOT_CONSTRUCTED), "TYPE_NOT_CONSTRUCTED"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "UNABLE_TO_DECODE_RSA_KEY"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), "UNABLE_TO_DECODE_RSA_PRIVATE_KEY"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "UNEXPECTED_EOC"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), "UNIVERSALSTRING_IS_WRONG_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "UNKNOWN_FORMAT"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_OBJECT_TYPE), "UNKNOWN_OBJECT_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "UNKNOWN_PUBLIC_KEY_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_TAG), "UNKNOWN_TAG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), "UNSUPPORTED_ANY_DEFINED_BY_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_CIPHER), "UNSUPPORTED_CIPHER"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), "UNSUPPORTED_ENCRYPTION_ALGORITHM"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), "UNSUPPORTED_PUBLIC_KEY_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_TYPE), "UNSUPPORTED_TYPE"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_TAG), "WRONG_TAG"},
|
||||
{ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_TYPE), "WRONG_TYPE"},
|
||||
{0, NULL},
|
||||
};
|
||||
@@ -57,13 +57,52 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1_mac.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
/* Used in asn1_mac.h.
|
||||
* TODO(davidben): Remove this once asn1_mac.h is gone or trimmed. */
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
|
||||
|
||||
/* Cross-module errors from crypto/x509/i2d_pr.c */
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, i2d_PrivateKey);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
|
||||
/* Cross-module errors from crypto/x509/asn1_gen.c.
|
||||
* TODO(davidben): Remove these once asn1_gen.c is gone. */
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, ASN1_generate_v3);
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_cb);
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, parse_tagging);
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, append_exp);
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_str2type);
|
||||
OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, bitstr_cb);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
|
||||
|
||||
static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
|
||||
static void asn1_put_length(unsigned char **pp, int length);
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -124,7 +125,7 @@ static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state);
|
||||
|
||||
static BIO_METHOD methods_asn1=
|
||||
static const BIO_METHOD methods_asn1=
|
||||
{
|
||||
BIO_TYPE_ASN1,
|
||||
"asn1",
|
||||
@@ -138,7 +139,7 @@ static BIO_METHOD methods_asn1=
|
||||
asn1_bio_callback_ctrl,
|
||||
};
|
||||
|
||||
BIO_METHOD *BIO_f_asn1(void)
|
||||
const BIO_METHOD *BIO_f_asn1(void)
|
||||
{
|
||||
return(&methods_asn1);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ print <<EOF;
|
||||
* Mask of various character properties
|
||||
*/
|
||||
|
||||
static unsigned char char_type[] = {
|
||||
static const unsigned char char_type[] = {
|
||||
EOF
|
||||
|
||||
for($i = 0; $i < 128; $i++) {
|
||||
|
||||
@@ -159,7 +159,6 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
|
||||
if (sp == NULL)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
@@ -200,6 +199,8 @@ err:
|
||||
err_sl:
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -163,7 +163,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
|
||||
if (sp == NULL)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
@@ -204,6 +203,8 @@ err:
|
||||
err_sl:
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
|
||||
if (sp == NULL)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
@@ -198,6 +197,8 @@ err:
|
||||
err_sl:
|
||||
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
|
||||
+14
-3
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -599,14 +601,13 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
||||
{
|
||||
int flags, aclass;
|
||||
int ret;
|
||||
const unsigned char *p, *q;
|
||||
const unsigned char *p;
|
||||
if (!val)
|
||||
return 0;
|
||||
flags = tt->flags;
|
||||
aclass = flags & ASN1_TFLG_TAG_CLASS;
|
||||
|
||||
p = *in;
|
||||
q = p;
|
||||
|
||||
if (flags & ASN1_TFLG_SK_MASK)
|
||||
{
|
||||
@@ -663,7 +664,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
||||
while(len > 0)
|
||||
{
|
||||
ASN1_VALUE *skfield;
|
||||
q = p;
|
||||
const unsigned char *q = p;
|
||||
/* See if EOC found */
|
||||
if (asn1_check_eoc(&p, len))
|
||||
{
|
||||
@@ -836,6 +837,16 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|
||||
}
|
||||
else if (cst)
|
||||
{
|
||||
if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
|
||||
|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
|
||||
|| utype == V_ASN1_ENUMERATED)
|
||||
{
|
||||
/* These types only have primitive encodings. */
|
||||
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,
|
||||
ASN1_R_TYPE_NOT_PRIMITIVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf.length = 0;
|
||||
buf.max = 0;
|
||||
buf.data = NULL;
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -210,6 +212,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
|
||||
memerr:
|
||||
OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ERR_R_MALLOC_FAILURE);
|
||||
ASN1_item_ex_free(pval, it);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname) CRYPTO_pop_info();
|
||||
#endif
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
|
||||
@@ -74,7 +74,7 @@ static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
|
||||
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
|
||||
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
|
||||
static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
|
||||
NULL, 0,
|
||||
bn_new,
|
||||
bn_free,
|
||||
@@ -126,7 +126,13 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
||||
int utype, char *free_cont, const ASN1_ITEM *it)
|
||||
{
|
||||
BIGNUM *bn;
|
||||
if(!*pval) bn_new(pval, it);
|
||||
if(!*pval)
|
||||
{
|
||||
if (!bn_new(pval, it))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
bn = (BIGNUM *)*pval;
|
||||
if(!BN_bin2bn(cont, len, bn)) {
|
||||
bn_free(pval, it);
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -74,7 +76,7 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const A
|
||||
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
|
||||
|
||||
static ASN1_PRIMITIVE_FUNCS long_pf = {
|
||||
static const ASN1_PRIMITIVE_FUNCS long_pf = {
|
||||
NULL, 0,
|
||||
long_new,
|
||||
long_free,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
base64
|
||||
base64
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
base64.c
|
||||
base64.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
base64_test
|
||||
base64_test
|
||||
|
||||
base64_test.c
|
||||
base64_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(base64_test crypto)
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static const unsigned char data_bin2ascii[65] =
|
||||
|
||||
+16
-17
@@ -1,31 +1,30 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
bio
|
||||
bio
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
bio.c
|
||||
bio_error.c
|
||||
bio_mem.c
|
||||
buffer.c
|
||||
connect.c
|
||||
fd.c
|
||||
file.c
|
||||
hexdump.c
|
||||
pair.c
|
||||
printf.c
|
||||
socket.c
|
||||
socket_helper.c
|
||||
bio.c
|
||||
bio_mem.c
|
||||
buffer.c
|
||||
connect.c
|
||||
fd.c
|
||||
file.c
|
||||
hexdump.c
|
||||
pair.c
|
||||
printf.c
|
||||
socket.c
|
||||
socket_helper.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
bio_test
|
||||
bio_test
|
||||
|
||||
bio_test.c
|
||||
bio_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(bio_test crypto)
|
||||
if (WIN32)
|
||||
target_link_libraries(bio_test ws2_32)
|
||||
target_link_libraries(bio_test ws2_32)
|
||||
endif()
|
||||
|
||||
+2
-1
@@ -57,8 +57,9 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Copyright (c) 2014, 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/err.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
const ERR_STRING_DATA BIO_error_string_data[] = {
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_callback_ctrl, 0), "BIO_callback_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ctrl, 0), "BIO_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new, 0), "BIO_new"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_file, 0), "BIO_new_file"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_mem_buf, 0), "BIO_new_mem_buf"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ctrl, 0), "bio_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_io, 0), "bio_io"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ip_and_port_to_socket_and_addr, 0), "bio_ip_and_port_to_socket_and_addr"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_make_pair, 0), "bio_make_pair"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_write, 0), "bio_write"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_buffer_ctrl, 0), "buffer_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_conn_ctrl, 0), "conn_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_conn_state, 0), "conn_state"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_file_ctrl, 0), "file_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_file_read, 0), "file_read"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_mem_write, 0), "mem_write"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ASN1_OBJECT_TOO_LONG), "ASN1_OBJECT_TOO_LONG"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "BAD_FOPEN_MODE"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "BROKEN_PIPE"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "CONNECT_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ERROR_SETTING_NBIO), "ERROR_SETTING_NBIO"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_ARGUMENT), "INVALID_ARGUMENT"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_IN_USE), "IN_USE"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_KEEPALIVE), "KEEPALIVE"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NBIO_CONNECT_ERROR), "NBIO_CONNECT_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_HOSTNAME_SPECIFIED), "NO_HOSTNAME_SPECIFIED"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_SPECIFIED), "NO_PORT_SPECIFIED"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "NO_SUCH_FILE"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "NULL_PARAMETER"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_SYS_LIB), "SYS_LIB"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET), "UNABLE_TO_CREATE_SOCKET"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "UNINITIALIZED"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_METHOD), "UNSUPPORTED_METHOD"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO), "WRITE_TO_READ_ONLY_BIO"},
|
||||
{0, NULL},
|
||||
};
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -27,14 +27,17 @@
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#pragma warning(push, 3)
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
static int closesocket(int sock) {
|
||||
@@ -119,6 +122,155 @@ static int test_socket_connect(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* bio_read_zero_copy_wrapper is a wrapper around the zero-copy APIs to make
|
||||
* testing easier. */
|
||||
static size_t bio_read_zero_copy_wrapper(BIO *bio, uint8_t *data, size_t len) {
|
||||
uint8_t *read_buf;
|
||||
size_t read_buf_offset;
|
||||
size_t available_bytes;
|
||||
size_t len_read = 0;
|
||||
|
||||
do {
|
||||
if (!BIO_zero_copy_get_read_buf(bio, &read_buf, &read_buf_offset,
|
||||
&available_bytes)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
available_bytes = MIN(available_bytes, len - len_read);
|
||||
memmove(data + len_read, read_buf + read_buf_offset, available_bytes);
|
||||
|
||||
BIO_zero_copy_get_read_buf_done(bio, available_bytes);
|
||||
|
||||
len_read += available_bytes;
|
||||
} while (len - len_read > 0 && available_bytes > 0);
|
||||
|
||||
return len_read;
|
||||
}
|
||||
|
||||
/* bio_write_zero_copy_wrapper is a wrapper around the zero-copy APIs to make
|
||||
* testing easier. */
|
||||
static size_t bio_write_zero_copy_wrapper(BIO *bio, const uint8_t *data,
|
||||
size_t len) {
|
||||
uint8_t *write_buf;
|
||||
size_t write_buf_offset;
|
||||
size_t available_bytes;
|
||||
size_t len_written = 0;
|
||||
|
||||
do {
|
||||
if (!BIO_zero_copy_get_write_buf(bio, &write_buf, &write_buf_offset,
|
||||
&available_bytes)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
available_bytes = MIN(available_bytes, len - len_written);
|
||||
memmove(write_buf + write_buf_offset, data + len_written, available_bytes);
|
||||
|
||||
BIO_zero_copy_get_write_buf_done(bio, available_bytes);
|
||||
|
||||
len_written += available_bytes;
|
||||
} while (len - len_written > 0 && available_bytes > 0);
|
||||
|
||||
return len_written;
|
||||
}
|
||||
|
||||
static int test_zero_copy_bio_pairs(void) {
|
||||
/* Test read and write, especially triggering the ring buffer wrap-around.*/
|
||||
BIO* bio1;
|
||||
BIO* bio2;
|
||||
size_t i, j;
|
||||
uint8_t bio1_application_send_buffer[1024];
|
||||
uint8_t bio2_application_recv_buffer[1024];
|
||||
size_t total_read = 0;
|
||||
size_t total_write = 0;
|
||||
uint8_t* write_buf;
|
||||
size_t write_buf_offset;
|
||||
size_t available_bytes;
|
||||
size_t bytes_left;
|
||||
|
||||
const size_t kLengths[] = {254, 255, 256, 257, 510, 511, 512, 513};
|
||||
|
||||
/* These trigger ring buffer wrap around. */
|
||||
const size_t kPartialLengths[] = {0, 1, 2, 3, 128, 255, 256, 257, 511, 512};
|
||||
|
||||
static const size_t kBufferSize = 512;
|
||||
|
||||
srand(1);
|
||||
for (i = 0; i < sizeof(bio1_application_send_buffer); i++) {
|
||||
bio1_application_send_buffer[i] = rand() & 255;
|
||||
}
|
||||
|
||||
/* Transfer bytes from bio1_application_send_buffer to
|
||||
* bio2_application_recv_buffer in various ways. */
|
||||
for (i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
|
||||
for (j = 0; j < sizeof(kPartialLengths) / sizeof(kPartialLengths[0]); j++) {
|
||||
total_write = 0;
|
||||
total_read = 0;
|
||||
|
||||
BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize);
|
||||
|
||||
total_write += bio_write_zero_copy_wrapper(
|
||||
bio1, bio1_application_send_buffer, kLengths[i]);
|
||||
|
||||
/* This tests interleaved read/write calls. Do a read between zero copy
|
||||
* write calls. */
|
||||
if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
|
||||
&available_bytes)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Free kPartialLengths[j] bytes in the beginning of bio1 write buffer.
|
||||
* This enables ring buffer wrap around for the next write. */
|
||||
total_read += BIO_read(bio2, bio2_application_recv_buffer + total_read,
|
||||
kPartialLengths[j]);
|
||||
|
||||
size_t interleaved_write_len = MIN(kPartialLengths[j], available_bytes);
|
||||
|
||||
/* Write the data for the interleaved write call. If the buffer becomes
|
||||
* empty after a read, the write offset is normally set to 0. Check that
|
||||
* this does not happen for interleaved read/write and that
|
||||
* |write_buf_offset| is still valid. */
|
||||
memcpy(write_buf + write_buf_offset,
|
||||
bio1_application_send_buffer + total_write, interleaved_write_len);
|
||||
if (BIO_zero_copy_get_write_buf_done(bio1, interleaved_write_len)) {
|
||||
total_write += interleaved_write_len;
|
||||
}
|
||||
|
||||
/* Do another write in case |write_buf_offset| was wrapped */
|
||||
total_write += bio_write_zero_copy_wrapper(
|
||||
bio1, bio1_application_send_buffer + total_write,
|
||||
kPartialLengths[j] - interleaved_write_len);
|
||||
|
||||
/* Drain the rest. */
|
||||
bytes_left = BIO_pending(bio2);
|
||||
total_read += bio_read_zero_copy_wrapper(
|
||||
bio2, bio2_application_recv_buffer + total_read, bytes_left);
|
||||
|
||||
BIO_free(bio1);
|
||||
BIO_free(bio2);
|
||||
|
||||
if (total_read != total_write) {
|
||||
fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
|
||||
(unsigned)j);
|
||||
return 0;
|
||||
}
|
||||
if (total_read > kLengths[i] + kPartialLengths[j]) {
|
||||
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
|
||||
(unsigned)j);
|
||||
return 0;
|
||||
}
|
||||
if (memcmp(bio1_application_send_buffer, bio2_application_recv_buffer,
|
||||
total_read) != 0) {
|
||||
fprintf(stderr, "Buffers not equal in round (%u, %u)\n", (unsigned)i,
|
||||
(unsigned)j);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_printf(void) {
|
||||
/* Test a short output, a very long one, and various sizes around
|
||||
* 256 (the size of the buffer) to ensure edge cases are correct. */
|
||||
@@ -201,6 +353,10 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!test_zero_copy_bio_pairs()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
+5
-2
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -313,8 +315,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
case BIO_CTRL_WPENDING:
|
||||
ret = (long)ctx->obuf_len;
|
||||
if (ret == 0) {
|
||||
if (b->next_bio == NULL)
|
||||
if (b->next_bio == NULL) {
|
||||
return 0;
|
||||
}
|
||||
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
|
||||
}
|
||||
break;
|
||||
@@ -480,7 +483,7 @@ static int buffer_puts(BIO *b, const char *str) {
|
||||
return buffer_write(b, str, strlen(str));
|
||||
}
|
||||
|
||||
static BIO_METHOD methods_buffer = {
|
||||
static const BIO_METHOD methods_buffer = {
|
||||
BIO_TYPE_BUFFER, "buffer", buffer_write, buffer_read,
|
||||
buffer_puts, buffer_gets, buffer_ctrl, buffer_new,
|
||||
buffer_free, buffer_callback_ctrl,
|
||||
|
||||
@@ -59,12 +59,18 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#pragma warning(push, 3)
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <openssl/buf.h>
|
||||
@@ -391,10 +397,11 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
/* use this one to start the connection */
|
||||
if (data->state != BIO_CONN_S_OK)
|
||||
if (data->state != BIO_CONN_S_OK) {
|
||||
ret = (long)conn_state(bio, data);
|
||||
else
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
case BIO_C_GET_CONNECT:
|
||||
/* TODO(fork): can this be removed? (Or maybe this whole file). */
|
||||
|
||||
@@ -57,12 +57,15 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#pragma warning(push, 3)
|
||||
#include <Windows.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <openssl/buf.h>
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* hexdump_ctx contains the state of a hexdump. */
|
||||
@@ -81,9 +82,10 @@ static char to_char(uint8_t b) {
|
||||
return b;
|
||||
}
|
||||
|
||||
/* hexdump adds |len| bytes of |data| to the current hex dump described by
|
||||
/* hexdump_write adds |len| bytes of |data| to the current hex dump described by
|
||||
* |ctx|. */
|
||||
static int hexdump(struct hexdump_ctx *ctx, const uint8_t *data, size_t len) {
|
||||
static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data,
|
||||
size_t len) {
|
||||
size_t i;
|
||||
char buf[10];
|
||||
unsigned l;
|
||||
@@ -182,7 +184,7 @@ int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) {
|
||||
ctx.bio = bio;
|
||||
ctx.indent = indent;
|
||||
|
||||
if (!hexdump(&ctx, data, len) || !finish(&ctx)) {
|
||||
if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,7 @@ typedef unsigned short u_short;
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
+344
-72
@@ -53,6 +53,7 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -70,7 +71,13 @@ struct bio_bio_st {
|
||||
size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
|
||||
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
|
||||
size_t size;
|
||||
char *buf; /* "size" elements (if != NULL) */
|
||||
uint8_t *buf; /* "size" elements (if != NULL) */
|
||||
char buf_externally_allocated; /* true iff buf was externally allocated. */
|
||||
|
||||
char zero_copy_read_lock; /* true iff a zero copy read operation
|
||||
* is in progress. */
|
||||
char zero_copy_write_lock; /* true iff a zero copy write operation
|
||||
* is in progress. */
|
||||
|
||||
size_t request; /* valid iff peer != NULL; 0 if len != 0,
|
||||
* otherwise set by peer to number of bytes
|
||||
@@ -85,11 +92,9 @@ static int bio_new(BIO *bio) {
|
||||
if (b == NULL) {
|
||||
return 0;
|
||||
}
|
||||
memset(b, 0, sizeof(struct bio_bio_st));
|
||||
|
||||
b->peer = NULL;
|
||||
b->size = 17 * 1024; /* enough for one TLS record (just a default) */
|
||||
b->buf = NULL;
|
||||
|
||||
bio->ptr = b;
|
||||
return 1;
|
||||
}
|
||||
@@ -140,7 +145,7 @@ static int bio_free(BIO *bio) {
|
||||
bio_destroy_pair(bio);
|
||||
}
|
||||
|
||||
if (b->buf != NULL) {
|
||||
if (b->buf != NULL && !b->buf_externally_allocated) {
|
||||
OPENSSL_free(b->buf);
|
||||
}
|
||||
|
||||
@@ -149,6 +154,268 @@ static int bio_free(BIO *bio) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t bio_zero_copy_get_read_buf(struct bio_bio_st* peer_b,
|
||||
uint8_t** out_read_buf,
|
||||
size_t* out_buf_offset) {
|
||||
size_t max_available;
|
||||
if (peer_b->len > peer_b->size - peer_b->offset) {
|
||||
/* Only the first half of the ring buffer can be read. */
|
||||
max_available = peer_b->size - peer_b->offset;
|
||||
} else {
|
||||
max_available = peer_b->len;
|
||||
}
|
||||
|
||||
*out_read_buf = peer_b->buf;
|
||||
*out_buf_offset = peer_b->offset;
|
||||
return max_available;
|
||||
}
|
||||
|
||||
int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
|
||||
size_t* out_buf_offset,
|
||||
size_t* out_available_bytes) {
|
||||
struct bio_bio_st* b;
|
||||
struct bio_bio_st* peer_b;
|
||||
size_t max_available;
|
||||
*out_available_bytes = 0;
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
if (!bio->init) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = bio->ptr;
|
||||
|
||||
if (!b || !b->peer) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer_b = b->peer->ptr;
|
||||
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (peer_b->zero_copy_read_lock) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer_b->request = 0; /* Is not used by zero-copy API. */
|
||||
|
||||
max_available =
|
||||
bio_zero_copy_get_read_buf(peer_b, out_read_buf, out_buf_offset);
|
||||
|
||||
assert(peer_b->buf != NULL);
|
||||
if (max_available > 0) {
|
||||
peer_b->zero_copy_read_lock = 1;
|
||||
}
|
||||
|
||||
*out_available_bytes = max_available;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
|
||||
struct bio_bio_st* b;
|
||||
struct bio_bio_st* peer_b;
|
||||
size_t max_available;
|
||||
size_t dummy_read_offset;
|
||||
uint8_t* dummy_read_buf;
|
||||
|
||||
assert(BIO_get_retry_flags(bio) == 0);
|
||||
|
||||
if (!bio->init) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
|
||||
BIO_R_UNINITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = bio->ptr;
|
||||
|
||||
if (!b || !b->peer) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer_b = b->peer->ptr;
|
||||
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!peer_b->zero_copy_read_lock) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
|
||||
BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_available =
|
||||
bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
|
||||
if (bytes_read > max_available) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
|
||||
BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer_b->len -= bytes_read;
|
||||
assert(peer_b->len >= 0);
|
||||
assert(peer_b->offset + bytes_read <= peer_b->size);
|
||||
|
||||
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
|
||||
* offset even if buffer becomes empty, to make sure
|
||||
* write_offset = (offset + len) mod size does not change. */
|
||||
if (peer_b->offset + bytes_read == peer_b->size ||
|
||||
(!peer_b->zero_copy_write_lock && peer_b->len == 0)) {
|
||||
peer_b->offset = 0;
|
||||
} else {
|
||||
peer_b->offset += bytes_read;
|
||||
}
|
||||
|
||||
bio->num_read += bytes_read;
|
||||
peer_b->zero_copy_read_lock = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b,
|
||||
uint8_t** out_write_buf,
|
||||
size_t* out_buf_offset) {
|
||||
size_t write_offset;
|
||||
size_t max_available;
|
||||
|
||||
assert(b->len <= b->size);
|
||||
|
||||
write_offset = b->offset + b->len;
|
||||
|
||||
if (write_offset >= b->size) {
|
||||
/* Only the first half of the ring buffer can be written to. */
|
||||
write_offset -= b->size;
|
||||
/* write up to the start of the ring buffer. */
|
||||
max_available = b->offset - write_offset;
|
||||
} else {
|
||||
/* write up to the end the buffer. */
|
||||
max_available = b->size - write_offset;
|
||||
}
|
||||
|
||||
*out_write_buf = b->buf;
|
||||
*out_buf_offset = write_offset;
|
||||
return max_available;
|
||||
}
|
||||
|
||||
int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
|
||||
size_t* out_buf_offset,
|
||||
size_t* out_available_bytes) {
|
||||
struct bio_bio_st* b;
|
||||
struct bio_bio_st* peer_b;
|
||||
size_t max_available;
|
||||
|
||||
*out_available_bytes = 0;
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
if (!bio->init) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = bio->ptr;
|
||||
|
||||
if (!b || !b->buf || !b->peer) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
peer_b = b->peer->ptr;
|
||||
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(b->buf != NULL);
|
||||
|
||||
if (b->zero_copy_write_lock) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->request = 0;
|
||||
if (b->closed) {
|
||||
/* Bio is already closed. */
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_available = bio_zero_copy_get_write_buf(b, out_write_buf, out_buf_offset);
|
||||
|
||||
if (max_available > 0) {
|
||||
b->zero_copy_write_lock = 1;
|
||||
}
|
||||
|
||||
*out_available_bytes = max_available;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
|
||||
struct bio_bio_st* b;
|
||||
struct bio_bio_st* peer_b;
|
||||
|
||||
size_t rest;
|
||||
size_t dummy_write_offset;
|
||||
uint8_t* dummy_write_buf;
|
||||
|
||||
if (!bio->init) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
|
||||
BIO_R_UNINITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = bio->ptr;
|
||||
|
||||
if (!b || !b->buf || !b->peer) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
peer_b = b->peer->ptr;
|
||||
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
|
||||
BIO_R_UNSUPPORTED_METHOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->request = 0;
|
||||
if (b->closed) {
|
||||
/* BIO is already closed. */
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!b->zero_copy_write_lock) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
|
||||
BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
|
||||
|
||||
if (bytes_written > rest) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
|
||||
BIO_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bio->num_write += bytes_written;
|
||||
/* Move write offset. */
|
||||
b->len += bytes_written;
|
||||
b->zero_copy_write_lock = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bio_read(BIO *bio, char *buf, int size_) {
|
||||
size_t size = size_;
|
||||
size_t rest;
|
||||
@@ -169,7 +436,7 @@ static int bio_read(BIO *bio, char *buf, int size_) {
|
||||
|
||||
peer_b->request = 0; /* will be set in "retry_read" situation */
|
||||
|
||||
if (buf == NULL || size == 0) {
|
||||
if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -214,7 +481,10 @@ static int bio_read(BIO *bio, char *buf, int size_) {
|
||||
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
|
||||
|
||||
peer_b->len -= chunk;
|
||||
if (peer_b->len) {
|
||||
/* If zero_copy_write_lock == 1 we must advance the offset even if buffer
|
||||
* becomes empty, to make sure write_offset = (offset + len) % size
|
||||
* does not change. */
|
||||
if (peer_b->len || peer_b->zero_copy_write_lock) {
|
||||
peer_b->offset += chunk;
|
||||
assert(peer_b->offset <= peer_b->size);
|
||||
if (peer_b->offset == peer_b->size) {
|
||||
@@ -248,6 +518,10 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
|
||||
assert(b->peer != NULL);
|
||||
assert(b->buf != NULL);
|
||||
|
||||
if (b->zero_copy_write_lock) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->request = 0;
|
||||
if (b->closed) {
|
||||
/* we already closed */
|
||||
@@ -304,7 +578,9 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
|
||||
return num;
|
||||
}
|
||||
|
||||
static int bio_make_pair(BIO *bio1, BIO *bio2) {
|
||||
static int bio_make_pair(BIO* bio1, BIO* bio2,
|
||||
size_t writebuf1_len, uint8_t* ext_writebuf1,
|
||||
size_t writebuf2_len, uint8_t* ext_writebuf2) {
|
||||
struct bio_bio_st *b1, *b2;
|
||||
|
||||
assert(bio1 != NULL);
|
||||
@@ -318,21 +594,42 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(b1->buf_externally_allocated == 0);
|
||||
assert(b2->buf_externally_allocated == 0);
|
||||
|
||||
if (b1->buf == NULL) {
|
||||
b1->buf = OPENSSL_malloc(b1->size);
|
||||
if (b1->buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
if (writebuf1_len) {
|
||||
b1->size = writebuf1_len;
|
||||
}
|
||||
if (!ext_writebuf1) {
|
||||
b1->buf_externally_allocated = 0;
|
||||
b1->buf = OPENSSL_malloc(b1->size);
|
||||
if (b1->buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
b1->buf = ext_writebuf1;
|
||||
b1->buf_externally_allocated = 1;
|
||||
}
|
||||
b1->len = 0;
|
||||
b1->offset = 0;
|
||||
}
|
||||
|
||||
if (b2->buf == NULL) {
|
||||
b2->buf = OPENSSL_malloc(b2->size);
|
||||
if (b2->buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
if (writebuf2_len) {
|
||||
b2->size = writebuf2_len;
|
||||
}
|
||||
if (!ext_writebuf2) {
|
||||
b2->buf_externally_allocated = 0;
|
||||
b2->buf = OPENSSL_malloc(b2->size);
|
||||
if (b2->buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
b2->buf = ext_writebuf2;
|
||||
b2->buf_externally_allocated = 1;
|
||||
}
|
||||
b2->len = 0;
|
||||
b2->offset = 0;
|
||||
@@ -341,9 +638,13 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) {
|
||||
b1->peer = bio2;
|
||||
b1->closed = 0;
|
||||
b1->request = 0;
|
||||
b1->zero_copy_read_lock = 0;
|
||||
b1->zero_copy_write_lock = 0;
|
||||
b2->peer = bio1;
|
||||
b2->closed = 0;
|
||||
b2->request = 0;
|
||||
b2->zero_copy_read_lock = 0;
|
||||
b2->zero_copy_write_lock = 0;
|
||||
|
||||
bio1->init = 1;
|
||||
bio2->init = 1;
|
||||
@@ -360,27 +661,6 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
|
||||
switch (cmd) {
|
||||
/* specific CTRL codes */
|
||||
|
||||
case BIO_C_SET_BUFF_SIZE:
|
||||
if (b->peer) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_IN_USE);
|
||||
ret = 0;
|
||||
} else if (num == 0) {
|
||||
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_INVALID_ARGUMENT);
|
||||
ret = 0;
|
||||
} else {
|
||||
size_t new_size = num;
|
||||
|
||||
if (b->size != new_size) {
|
||||
if (b->buf) {
|
||||
OPENSSL_free(b->buf);
|
||||
b->buf = NULL;
|
||||
}
|
||||
b->size = new_size;
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case BIO_C_GET_WRITE_BUF_SIZE:
|
||||
ret = (long)b->size;
|
||||
break;
|
||||
@@ -419,14 +699,6 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
|
||||
|
||||
/* standard CTRL codes follow */
|
||||
|
||||
case BIO_CTRL_RESET:
|
||||
if (b->buf != NULL) {
|
||||
b->len = 0;
|
||||
b->offset = 0;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = bio->shutdown;
|
||||
break;
|
||||
@@ -478,35 +750,43 @@ static int bio_puts(BIO *bio, const char *str) {
|
||||
return bio_write(bio, str, strlen(str));
|
||||
}
|
||||
|
||||
int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p,
|
||||
size_t writebuf2) {
|
||||
static const BIO_METHOD methods_biop = {
|
||||
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
|
||||
bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
|
||||
bio_free, NULL /* no bio_callback_ctrl */
|
||||
};
|
||||
|
||||
const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
|
||||
|
||||
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
|
||||
BIO** bio2_p, size_t writebuf2) {
|
||||
return BIO_new_bio_pair_external_buf(bio1_p, writebuf1, NULL, bio2_p,
|
||||
writebuf2, NULL);
|
||||
}
|
||||
|
||||
int BIO_new_bio_pair_external_buf(BIO** bio1_p, size_t writebuf1_len,
|
||||
uint8_t* ext_writebuf1,
|
||||
BIO** bio2_p, size_t writebuf2_len,
|
||||
uint8_t* ext_writebuf2) {
|
||||
BIO *bio1 = NULL, *bio2 = NULL;
|
||||
long r;
|
||||
int ret = 0;
|
||||
|
||||
bio1 = BIO_new(BIO_s_bio());
|
||||
/* External buffers must have sizes greater than 0. */
|
||||
if ((ext_writebuf1 && !writebuf1_len) || (ext_writebuf2 && !writebuf2_len)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
bio1 = BIO_new(bio_s_bio());
|
||||
if (bio1 == NULL) {
|
||||
goto err;
|
||||
}
|
||||
bio2 = BIO_new(BIO_s_bio());
|
||||
bio2 = BIO_new(bio_s_bio());
|
||||
if (bio2 == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (writebuf1) {
|
||||
r = BIO_set_write_buffer_size(bio1, writebuf1);
|
||||
if (!r) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (writebuf2) {
|
||||
r = BIO_set_write_buffer_size(bio2, writebuf2);
|
||||
if (!r) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bio_make_pair(bio1, bio2)) {
|
||||
if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len,
|
||||
ext_writebuf2)) {
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
@@ -528,14 +808,6 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const BIO_METHOD methods_biop = {
|
||||
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
|
||||
bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
|
||||
bio_free, NULL /* no bio_callback_ctrl */
|
||||
};
|
||||
|
||||
const BIO_METHOD *BIO_s_bio(void) { return &methods_biop; }
|
||||
|
||||
size_t BIO_ctrl_get_read_request(BIO *bio) {
|
||||
return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
|
||||
}
|
||||
|
||||
+9
-2
@@ -58,9 +58,14 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#pragma warning(push, 3)
|
||||
#include <WinSock2.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
@@ -145,11 +150,13 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
case BIO_C_GET_FD:
|
||||
if (b->init) {
|
||||
ip = (int *)ptr;
|
||||
if (ip != NULL)
|
||||
if (ip != NULL) {
|
||||
*ip = b->num;
|
||||
}
|
||||
ret = b->num;
|
||||
} else
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = b->shutdown;
|
||||
|
||||
@@ -18,15 +18,17 @@
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#pragma warning(push, 3)
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
typedef int socklen_t;
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
+40
-43
@@ -1,67 +1,64 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
if (${ARCH} STREQUAL "x86_64")
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
|
||||
asm/x86_64-gcc.c
|
||||
x86_64-mont.${ASM_EXT}
|
||||
x86_64-mont5.${ASM_EXT}
|
||||
modexp512-x86_64.${ASM_EXT}
|
||||
rsaz-x86_64.${ASM_EXT}
|
||||
rsaz-avx2.${ASM_EXT}
|
||||
asm/x86_64-gcc.c
|
||||
x86_64-mont.${ASM_EXT}
|
||||
x86_64-mont5.${ASM_EXT}
|
||||
rsaz-x86_64.${ASM_EXT}
|
||||
rsaz-avx2.${ASM_EXT}
|
||||
|
||||
rsaz_exp.c
|
||||
)
|
||||
rsaz_exp.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "x86")
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
|
||||
bn-586.${ASM_EXT}
|
||||
co-586.${ASM_EXT}
|
||||
x86-mont.${ASM_EXT}
|
||||
)
|
||||
bn-586.${ASM_EXT}
|
||||
co-586.${ASM_EXT}
|
||||
x86-mont.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
set(
|
||||
BN_ARCH_SOURCES
|
||||
|
||||
armv4-mont.${ASM_EXT}
|
||||
)
|
||||
armv4-mont.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
bn
|
||||
bn
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
bn_error.c
|
||||
add.c
|
||||
bn.c
|
||||
cmp.c
|
||||
convert.c
|
||||
ctx.c
|
||||
div.c
|
||||
exponentiation.c
|
||||
generic.c
|
||||
gcd.c
|
||||
kronecker.c
|
||||
montgomery.c
|
||||
mul.c
|
||||
prime.c
|
||||
random.c
|
||||
shift.c
|
||||
sqrt.c
|
||||
add.c
|
||||
bn.c
|
||||
cmp.c
|
||||
convert.c
|
||||
ctx.c
|
||||
div.c
|
||||
exponentiation.c
|
||||
generic.c
|
||||
gcd.c
|
||||
kronecker.c
|
||||
montgomery.c
|
||||
mul.c
|
||||
prime.c
|
||||
random.c
|
||||
shift.c
|
||||
sqrt.c
|
||||
|
||||
${BN_ARCH_SOURCES}
|
||||
${BN_ARCH_SOURCES}
|
||||
)
|
||||
|
||||
perlasm(x86_64-mont.${ASM_EXT} asm/x86_64-mont.pl)
|
||||
perlasm(x86_64-mont5.${ASM_EXT} asm/x86_64-mont5.pl)
|
||||
perlasm(modexp512-x86_64.${ASM_EXT} asm/modexp512-x86_64.pl)
|
||||
perlasm(rsaz-x86_64.${ASM_EXT} asm/rsaz-x86_64.pl)
|
||||
perlasm(rsaz-avx2.${ASM_EXT} asm/rsaz-avx2.pl)
|
||||
perlasm(bn-586.${ASM_EXT} asm/bn-586.pl)
|
||||
@@ -70,9 +67,9 @@ perlasm(x86-mont.${ASM_EXT} asm/x86-mont.pl)
|
||||
perlasm(armv4-mont.${ASM_EXT} asm/armv4-mont.pl)
|
||||
|
||||
add_executable(
|
||||
bn_test
|
||||
bn_test
|
||||
|
||||
bn_test.c
|
||||
bn_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(bn_test crypto)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,8 +61,12 @@
|
||||
#
|
||||
# rsa2048 sign/sec OpenSSL 1.0.1 scalar(*) this
|
||||
# 2.3GHz Haswell 621 765/+23% 1113/+79%
|
||||
# 2.3GHz Broadwell(**) 688 1200(***)/+74% 1120/+63%
|
||||
#
|
||||
# (*) if system doesn't support AVX2, for reference purposes;
|
||||
# (**) scaled to 2.3GHz to simplify comparison;
|
||||
# (***) scalar AD*X code is faster than AVX2 and is preferred code
|
||||
# path for Broadwell;
|
||||
|
||||
$flavour = shift;
|
||||
$output = shift;
|
||||
@@ -99,7 +103,7 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
||||
open OUT,"| $^X $xlate $flavour $output";
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT = *OUT;
|
||||
|
||||
if ($avx>1) {{{
|
||||
|
||||
@@ -95,7 +95,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| $^X $xlate $flavour $output";
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
|
||||
+73
-91
@@ -64,7 +64,7 @@
|
||||
#define asm __asm__
|
||||
|
||||
/*
|
||||
* "m"(a), "+m"(r) is the way to favor DirectPath µ-code;
|
||||
* "m"(a), "+m"(r) is the way to favor DirectPath µ-code;
|
||||
* "g"(0) let the compiler to decide where does it
|
||||
* want to keep the value of zero;
|
||||
*/
|
||||
@@ -100,8 +100,9 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
|
||||
if (num <= 0)
|
||||
if (num <= 0) {
|
||||
return (c1);
|
||||
}
|
||||
|
||||
while (num & ~3) {
|
||||
mul_add(rp[0], ap[0], w, c1);
|
||||
@@ -114,23 +115,26 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
}
|
||||
if (num) {
|
||||
mul_add(rp[0], ap[0], w, c1);
|
||||
if (--num == 0)
|
||||
if (--num == 0) {
|
||||
return c1;
|
||||
}
|
||||
mul_add(rp[1], ap[1], w, c1);
|
||||
if (--num == 0)
|
||||
if (--num == 0) {
|
||||
return c1;
|
||||
}
|
||||
mul_add(rp[2], ap[2], w, c1);
|
||||
return c1;
|
||||
}
|
||||
|
||||
return (c1);
|
||||
return c1;
|
||||
}
|
||||
|
||||
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
|
||||
BN_ULONG c1 = 0;
|
||||
|
||||
if (num <= 0)
|
||||
return (c1);
|
||||
if (num <= 0) {
|
||||
return c1;
|
||||
}
|
||||
|
||||
while (num & ~3) {
|
||||
mul(rp[0], ap[0], w, c1);
|
||||
@@ -143,19 +147,22 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
|
||||
}
|
||||
if (num) {
|
||||
mul(rp[0], ap[0], w, c1);
|
||||
if (--num == 0)
|
||||
if (--num == 0) {
|
||||
return c1;
|
||||
}
|
||||
mul(rp[1], ap[1], w, c1);
|
||||
if (--num == 0)
|
||||
if (--num == 0) {
|
||||
return c1;
|
||||
}
|
||||
mul(rp[2], ap[2], w, c1);
|
||||
}
|
||||
return (c1);
|
||||
return c1;
|
||||
}
|
||||
|
||||
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
if (n <= 0)
|
||||
if (n <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (n & ~3) {
|
||||
sqr(r[0], r[1], a[0]);
|
||||
@@ -168,11 +175,13 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
}
|
||||
if (n) {
|
||||
sqr(r[0], r[1], a[0]);
|
||||
if (--n == 0)
|
||||
if (--n == 0) {
|
||||
return;
|
||||
}
|
||||
sqr(r[2], r[3], a[1]);
|
||||
if (--n == 0)
|
||||
if (--n == 0) {
|
||||
return;
|
||||
}
|
||||
sqr(r[4], r[5], a[2]);
|
||||
}
|
||||
}
|
||||
@@ -190,8 +199,9 @@ BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
BN_ULONG ret;
|
||||
size_t i = 0;
|
||||
|
||||
if (n <= 0)
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
" subq %0,%0 \n" /* clear carry */
|
||||
@@ -216,8 +226,9 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
BN_ULONG ret;
|
||||
size_t i = 0;
|
||||
|
||||
if (n <= 0)
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
asm volatile (
|
||||
" subq %0,%0 \n" /* clear borrow */
|
||||
@@ -242,47 +253,56 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
|
||||
BN_ULONG t1, t2;
|
||||
int c = 0;
|
||||
|
||||
if (n <= 0)
|
||||
return ((BN_ULONG)0);
|
||||
if (n <= 0) {
|
||||
return (BN_ULONG)0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
t1 = a[0];
|
||||
t2 = b[0];
|
||||
r[0] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
if (--n <= 0)
|
||||
}
|
||||
if (--n <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = a[1];
|
||||
t2 = b[1];
|
||||
r[1] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
if (--n <= 0)
|
||||
}
|
||||
if (--n <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = a[2];
|
||||
t2 = b[2];
|
||||
r[2] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
if (--n <= 0)
|
||||
}
|
||||
if (--n <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = a[3];
|
||||
t2 = b[3];
|
||||
r[3] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
if (--n <= 0)
|
||||
}
|
||||
if (--n <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
a += 4;
|
||||
b += 4;
|
||||
r += 4;
|
||||
}
|
||||
return (c);
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -292,80 +312,45 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* original macros are kept for reference purposes */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
t1 = ta * tb; \
|
||||
t2 = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
t1 = BN_UMULT_HIGH(ta, tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
#else
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
/* Keep in mind that carrying into high part of multiplication result can not
|
||||
* overflow, because it cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
|
||||
asm("addq %0,%0; adcq %2,%1" : "+d"(t2), "+r"(c2) : "g"(0) : "cc"); \
|
||||
asm("addq %0,%0; adcq %2,%1" : "+a"(t1), "+d"(t2) : "g"(0) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#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) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -468,7 +453,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -507,7 +491,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -582,7 +565,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
|
||||
+6
-2
@@ -57,6 +57,8 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -198,13 +200,15 @@ unsigned BN_num_bits_word(BN_ULONG l) {
|
||||
if (l & 0xffff000000000000L) {
|
||||
if (l & 0xff00000000000000L) {
|
||||
return (bits[(int)(l >> 56)] + 56);
|
||||
} else
|
||||
} else {
|
||||
return (bits[(int)(l >> 48)] + 48);
|
||||
}
|
||||
} else {
|
||||
if (l & 0x0000ff0000000000L) {
|
||||
return (bits[(int)(l >> 40)] + 40);
|
||||
} else
|
||||
} else {
|
||||
return (bits[(int)(l >> 32)] + 32);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright (c) 2014, 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/err.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
const ERR_STRING_DATA BN_error_string_data[] = {
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_get, 0), "BN_CTX_get"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_new, 0), "BN_CTX_new"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_start, 0), "BN_CTX_start"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_bn2dec, 0), "BN_bn2dec"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_bn2hex, 0), "BN_bn2hex"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_div, 0), "BN_div"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_div_recp, 0), "BN_div_recp"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_exp, 0), "BN_exp"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_generate_dsa_nonce, 0), "BN_generate_dsa_nonce"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_generate_prime_ex, 0), "BN_generate_prime_ex"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_exp2_mont, 0), "BN_mod_exp2_mont"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_exp_mont, 0), "BN_mod_exp_mont"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_exp_mont_consttime, 0), "BN_mod_exp_mont_consttime"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_exp_mont_word, 0), "BN_mod_exp_mont_word"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_inverse, 0), "BN_mod_inverse"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_inverse_no_branch, 0), "BN_mod_inverse_no_branch"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_lshift_quick, 0), "BN_mod_lshift_quick"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_mod_sqrt, 0), "BN_mod_sqrt"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_new, 0), "BN_new"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_rand, 0), "BN_rand"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_rand_range, 0), "BN_rand_range"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_sqrt, 0), "BN_sqrt"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_usub, 0), "BN_usub"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_bn_wexpand, 0), "bn_wexpand"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_mod_exp_recp, 0), "mod_exp_recp"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_ARG2_LT_ARG3), "ARG2_LT_ARG3"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_BAD_RECIPROCAL), "BAD_RECIPROCAL"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_BIGNUM_TOO_LONG), "BIGNUM_TOO_LONG"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_BITS_TOO_SMALL), "BITS_TOO_SMALL"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_CALLED_WITH_EVEN_MODULUS), "CALLED_WITH_EVEN_MODULUS"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_DIV_BY_ZERO), "DIV_BY_ZERO"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), "EXPAND_ON_STATIC_BIGNUM_DATA"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_INPUT_NOT_REDUCED), "INPUT_NOT_REDUCED"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_INVALID_RANGE), "INVALID_RANGE"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_NEGATIVE_NUMBER), "NEGATIVE_NUMBER"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_A_SQUARE), "NOT_A_SQUARE"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_INITIALIZED), "NOT_INITIALIZED"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_INVERSE), "NO_INVERSE"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_PRIVATE_KEY_TOO_LARGE), "PRIVATE_KEY_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_P_IS_NOT_PRIME), "P_IS_NOT_PRIME"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_TOO_MANY_ITERATIONS), "TOO_MANY_ITERATIONS"},
|
||||
{ERR_PACK(ERR_LIB_BN, 0, BN_R_TOO_MANY_TEMPORARY_VARIABLES), "TOO_MANY_TEMPORARY_VARIABLES"},
|
||||
{0, NULL},
|
||||
};
|
||||
+194
-99
@@ -68,6 +68,7 @@
|
||||
* Laboratories. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
@@ -77,6 +78,7 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static const int num0 = 100; /* number of tests */
|
||||
static const int num1 = 50; /* additional tests for some functions */
|
||||
static const int num2 = 5; /* number of tests for slow functions */
|
||||
@@ -143,11 +145,12 @@ int main(int argc, char *argv[]) {
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1) {
|
||||
if (strcmp(*argv, "-results") == 0)
|
||||
if (strcmp(*argv, "-results") == 0) {
|
||||
results = 1;
|
||||
else if (strcmp(*argv, "-out") == 0) {
|
||||
if (--argc < 1)
|
||||
} else if (strcmp(*argv, "-out") == 0) {
|
||||
if (--argc < 1) {
|
||||
break;
|
||||
}
|
||||
outfile = *(++argv);
|
||||
}
|
||||
argc--;
|
||||
@@ -156,8 +159,9 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
if (ctx == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL) {
|
||||
@@ -173,82 +177,98 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!results)
|
||||
if (!results) {
|
||||
BIO_puts(out, "obase=16\nibase=16\n");
|
||||
}
|
||||
|
||||
message(out, "BN_add");
|
||||
if (!test_add(out))
|
||||
if (!test_add(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_sub");
|
||||
if (!test_sub(out))
|
||||
if (!test_sub(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_lshift1");
|
||||
if (!test_lshift1(out))
|
||||
if (!test_lshift1(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_lshift (fixed)");
|
||||
if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL)))
|
||||
if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL))) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_lshift");
|
||||
if (!test_lshift(out, ctx, NULL))
|
||||
if (!test_lshift(out, ctx, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_rshift1");
|
||||
if (!test_rshift1(out))
|
||||
if (!test_rshift1(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_rshift");
|
||||
if (!test_rshift(out, ctx))
|
||||
if (!test_rshift(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_sqr");
|
||||
if (!test_sqr(out, ctx))
|
||||
if (!test_sqr(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mul");
|
||||
if (!test_mul(out))
|
||||
if (!test_mul(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_div");
|
||||
if (!test_div(out, ctx))
|
||||
if (!test_div(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_div_word");
|
||||
if (!test_div_word(out))
|
||||
if (!test_div_word(out)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mod");
|
||||
if (!test_mod(out, ctx))
|
||||
if (!test_mod(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mod_mul");
|
||||
if (!test_mod_mul(out, ctx))
|
||||
if (!test_mod_mul(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mont");
|
||||
if (!test_mont(out, ctx))
|
||||
if (!test_mont(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mod_exp");
|
||||
if (!test_mod_exp(out, ctx))
|
||||
if (!test_mod_exp(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mod_exp_mont_consttime");
|
||||
@@ -266,23 +286,27 @@ int main(int argc, char *argv[]) {
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_mod_sqrt");
|
||||
if (!test_mod_sqrt(out, ctx))
|
||||
if (!test_mod_sqrt(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "Small prime generation");
|
||||
if (!test_small_prime(out, ctx))
|
||||
if (!test_small_prime(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_sqrt");
|
||||
if (!test_sqrt(out, ctx))
|
||||
if (!test_sqrt(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out, "BN_bn2bin_padded");
|
||||
if (!test_bn2bin_padded(out, ctx))
|
||||
if (!test_bn2bin_padded(out, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
(void)BIO_flush(out);
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
@@ -350,8 +374,9 @@ int test_sub(BIO *bp) {
|
||||
if (i < num1) {
|
||||
BN_rand(&a, 512, 0, 0);
|
||||
BN_copy(&b, &a);
|
||||
if (BN_set_bit(&a, i) == 0)
|
||||
if (BN_set_bit(&a, i) == 0) {
|
||||
return (0);
|
||||
}
|
||||
BN_add_word(&b, i);
|
||||
} else {
|
||||
BN_rand(&b, 400 + i - num1, 0, 0);
|
||||
@@ -398,8 +423,9 @@ int test_div(BIO *bp, BN_CTX *ctx) {
|
||||
BN_copy(&b, &a);
|
||||
BN_lshift(&a, &a, i);
|
||||
BN_add_word(&a, i);
|
||||
} else
|
||||
} else {
|
||||
BN_rand(&b, 50 + 3 * (i - num1), 0, 0);
|
||||
}
|
||||
a.neg = rand_neg();
|
||||
b.neg = rand_neg();
|
||||
BN_div(&d, &c, &a, &b, ctx);
|
||||
@@ -559,9 +585,9 @@ int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_) {
|
||||
d = BN_new();
|
||||
BN_one(c);
|
||||
|
||||
if (a_)
|
||||
if (a_) {
|
||||
a = a_;
|
||||
else {
|
||||
} else {
|
||||
a = BN_new();
|
||||
BN_rand(a, 200, 0, 0); /**/
|
||||
a->neg = rand_neg();
|
||||
@@ -608,8 +634,9 @@ int test_mul(BIO *bp) {
|
||||
BN_CTX *ctx;
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
if (ctx == NULL) {
|
||||
abort();
|
||||
}
|
||||
|
||||
BN_init(&a);
|
||||
BN_init(&b);
|
||||
@@ -621,8 +648,9 @@ int test_mul(BIO *bp) {
|
||||
if (i <= num1) {
|
||||
BN_rand(&a, 100, 0, 0);
|
||||
BN_rand(&b, 100, 0, 0);
|
||||
} else
|
||||
} else {
|
||||
BN_rand(&b, i - num1, 0, 0);
|
||||
}
|
||||
a.neg = rand_neg();
|
||||
b.neg = rand_neg();
|
||||
BN_mul(&c, &a, &b, ctx);
|
||||
@@ -653,40 +681,98 @@ int test_mul(BIO *bp) {
|
||||
}
|
||||
|
||||
int test_sqr(BIO *bp, BN_CTX *ctx) {
|
||||
BIGNUM a, c, d, e;
|
||||
int i;
|
||||
BIGNUM *a, *c, *d, *e;
|
||||
int i, ret = 0;
|
||||
|
||||
BN_init(&a);
|
||||
BN_init(&c);
|
||||
BN_init(&d);
|
||||
BN_init(&e);
|
||||
a = BN_new();
|
||||
c = BN_new();
|
||||
d = BN_new();
|
||||
e = BN_new();
|
||||
if (a == NULL || c == NULL || d == NULL || e == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num0; i++) {
|
||||
BN_rand(&a, 40 + i * 10, 0, 0);
|
||||
a.neg = rand_neg();
|
||||
BN_sqr(&c, &a, ctx);
|
||||
BN_rand(a, 40 + i * 10, 0, 0);
|
||||
a->neg = rand_neg();
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, &a);
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, &a);
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, &c);
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_div(&d, &e, &c, &a, ctx);
|
||||
BN_sub(&d, &d, &a);
|
||||
if (!BN_is_zero(&d) || !BN_is_zero(&e)) {
|
||||
BN_div(d, e, c, a, ctx);
|
||||
BN_sub(d, d, a);
|
||||
if (!BN_is_zero(d) || !BN_is_zero(e)) {
|
||||
fprintf(stderr, "Square test failed!\n");
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
BN_free(&a);
|
||||
BN_free(&c);
|
||||
BN_free(&d);
|
||||
BN_free(&e);
|
||||
return (1);
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d)) {
|
||||
fprintf(stderr,
|
||||
"Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d)) {
|
||||
fprintf(stderr,
|
||||
"Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (a != NULL) {
|
||||
BN_free(a);
|
||||
}
|
||||
if (c != NULL) {
|
||||
BN_free(c);
|
||||
}
|
||||
if (d != NULL) {
|
||||
BN_free(d);
|
||||
}
|
||||
if (e != NULL) {
|
||||
BN_free(e);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -766,16 +852,18 @@ int test_mont(BIO *bp, BN_CTX *ctx) {
|
||||
BN_init(&n);
|
||||
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL)
|
||||
if (mont == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_rand(&a, 100, 0, 0); /**/
|
||||
BN_rand(&b, 100, 0, 0); /**/
|
||||
for (i = 0; i < num2; i++) {
|
||||
int bits = (200 * (i + 1)) / num2;
|
||||
|
||||
if (bits == 0)
|
||||
if (bits == 0) {
|
||||
continue;
|
||||
}
|
||||
BN_rand(&n, bits, 0, 1);
|
||||
BN_MONT_CTX_set(mont, &n, ctx);
|
||||
|
||||
@@ -882,8 +970,9 @@ int test_mod_mul(BIO *bp, BN_CTX *ctx) {
|
||||
if (!BN_mod_mul(e, a, b, c, ctx)) {
|
||||
unsigned long l;
|
||||
|
||||
while ((l = ERR_get_error()))
|
||||
while ((l = ERR_get_error())) {
|
||||
fprintf(stderr, "ERROR:%s\n", ERR_error_string(l, NULL));
|
||||
}
|
||||
abort();
|
||||
}
|
||||
if (bp != NULL) {
|
||||
@@ -940,8 +1029,9 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx) {
|
||||
BN_rand(a, 20 + i * 5, 0, 0); /**/
|
||||
BN_rand(b, 2 + i, 0, 0); /**/
|
||||
|
||||
if (!BN_mod_exp(d, a, b, c, ctx))
|
||||
if (!BN_mod_exp(d, a, b, c, ctx)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
@@ -986,8 +1076,9 @@ int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx) {
|
||||
BN_rand(a, 20 + i * 5, 0, 0); /**/
|
||||
BN_rand(b, 2 + i, 0, 0); /**/
|
||||
|
||||
if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL))
|
||||
if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
|
||||
return (00);
|
||||
}
|
||||
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
@@ -1036,8 +1127,9 @@ int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) {
|
||||
/* Zero exponent */
|
||||
BN_rand(a, 1024, 0, 0);
|
||||
BN_zero(p);
|
||||
if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
|
||||
if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
if (!BN_is_one(d)) {
|
||||
fprintf(stderr, "Modular exponentiation test failed!\n");
|
||||
return 0;
|
||||
@@ -1045,8 +1137,9 @@ int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) {
|
||||
/* Zero input */
|
||||
BN_rand(p, 1024, 0, 0);
|
||||
BN_zero(a);
|
||||
if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
|
||||
if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
if (!BN_is_zero(d)) {
|
||||
fprintf(stderr, "Modular exponentiation test failed!\n");
|
||||
return 0;
|
||||
@@ -1068,10 +1161,10 @@ int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) {
|
||||
}
|
||||
/* Finally, some regular test vectors. */
|
||||
BN_rand(e, 1024, 0, 0);
|
||||
if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
|
||||
return 0;
|
||||
if (!BN_mod_exp(a, e, p, m, ctx))
|
||||
if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL) ||
|
||||
!BN_mod_exp(a, e, p, m, ctx)) {
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(a, d) != 0) {
|
||||
fprintf(stderr, "Modular exponentiation test failed!\n");
|
||||
return 0;
|
||||
@@ -1083,7 +1176,7 @@ int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) {
|
||||
BN_free(m);
|
||||
BN_free(d);
|
||||
BN_free(e);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_exp(BIO *bp, BN_CTX *ctx) {
|
||||
@@ -1101,8 +1194,9 @@ int test_exp(BIO *bp, BN_CTX *ctx) {
|
||||
BN_rand(a, 20 + i * 5, 0, 0); /**/
|
||||
BN_rand(b, 2 + i, 0, 0); /**/
|
||||
|
||||
if (BN_exp(d, a, b, ctx) <= 0)
|
||||
if (BN_exp(d, a, b, ctx) <= 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
@@ -1115,8 +1209,9 @@ int test_exp(BIO *bp, BN_CTX *ctx) {
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_one(e);
|
||||
for (; !BN_is_zero(b); BN_sub(b, b, one))
|
||||
for (; !BN_is_zero(b); BN_sub(b, b, one)) {
|
||||
BN_mul(e, e, a, ctx);
|
||||
}
|
||||
BN_sub(e, e, d);
|
||||
if (!BN_is_zero(e)) {
|
||||
fprintf(stderr, "Exponentiation test failed!\n");
|
||||
@@ -1128,7 +1223,7 @@ int test_exp(BIO *bp, BN_CTX *ctx) {
|
||||
BN_free(d);
|
||||
BN_free(e);
|
||||
BN_free(one);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* test_exp_mod_zero tests that x**0 mod 1 == 0. */
|
||||
@@ -1170,14 +1265,15 @@ static int test_exp_mod_zero(void) {
|
||||
static int genprime_cb(int p, int n, BN_GENCB *arg) {
|
||||
char c = '*';
|
||||
|
||||
if (p == 0)
|
||||
if (p == 0) {
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
} else if (p == 1) {
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
} else if (p == 2) {
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
} else if (p == 3) {
|
||||
c = '\n';
|
||||
}
|
||||
putc(c, stdout);
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
@@ -1192,8 +1288,9 @@ int test_mod_sqrt(BIO *bp, BN_CTX *ctx) {
|
||||
a = BN_new();
|
||||
p = BN_new();
|
||||
r = BN_new();
|
||||
if (a == NULL || p == NULL || r == NULL)
|
||||
if (a == NULL || p == NULL || r == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_GENCB_set(&cb, genprime_cb, NULL);
|
||||
|
||||
@@ -1201,16 +1298,18 @@ int test_mod_sqrt(BIO *bp, BN_CTX *ctx) {
|
||||
if (i < 8) {
|
||||
unsigned primes[8] = {2, 3, 5, 7, 11, 13, 17, 19};
|
||||
|
||||
if (!BN_set_word(p, primes[i]))
|
||||
if (!BN_set_word(p, primes[i])) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_set_word(a, 32))
|
||||
goto err;
|
||||
if (!BN_set_word(r, 2 * i + 1))
|
||||
if (!BN_set_word(a, 32) ||
|
||||
!BN_set_word(r, 2 * i + 1)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb))
|
||||
if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) {
|
||||
goto err;
|
||||
}
|
||||
putc('\n', stdout);
|
||||
}
|
||||
p->neg = rand_neg();
|
||||
@@ -1218,31 +1317,24 @@ int test_mod_sqrt(BIO *bp, BN_CTX *ctx) {
|
||||
for (j = 0; j < num2; j++) {
|
||||
/* construct 'a' such that it is a square modulo p,
|
||||
* but in general not a proper square and not reduced modulo p */
|
||||
if (!BN_rand(r, 256, 0, 3))
|
||||
if (!BN_rand(r, 256, 0, 3) ||
|
||||
!BN_nnmod(r, r, p, ctx) ||
|
||||
!BN_mod_sqr(r, r, p, ctx) ||
|
||||
!BN_rand(a, 256, 0, 3) ||
|
||||
!BN_nnmod(a, a, p, ctx) ||
|
||||
!BN_mod_sqr(a, a, p, ctx) ||
|
||||
!BN_mul(a, a, r, ctx)) {
|
||||
goto err;
|
||||
if (!BN_nnmod(r, r, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_sqr(r, r, p, ctx))
|
||||
goto err;
|
||||
if (!BN_rand(a, 256, 0, 3))
|
||||
goto err;
|
||||
if (!BN_nnmod(a, a, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_sqr(a, a, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mul(a, a, r, ctx))
|
||||
goto err;
|
||||
if (rand_neg())
|
||||
if (!BN_sub(a, a, p))
|
||||
}
|
||||
if (rand_neg() && !BN_sub(a, a, p)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_sqrt(r, a, p, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_sqr(r, r, p, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_nnmod(a, a, p, ctx))
|
||||
if (!BN_mod_sqrt(r, a, p, ctx) ||
|
||||
!BN_mod_sqr(r, r, p, ctx) ||
|
||||
!BN_nnmod(a, a, p, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_cmp(a, r) != 0) {
|
||||
fprintf(stderr, "BN_mod_sqrt failed: a = ");
|
||||
@@ -1264,12 +1356,15 @@ int test_mod_sqrt(BIO *bp, BN_CTX *ctx) {
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (a != NULL)
|
||||
if (a != NULL) {
|
||||
BN_free(a);
|
||||
if (p != NULL)
|
||||
}
|
||||
if (p != NULL) {
|
||||
BN_free(p);
|
||||
if (r != NULL)
|
||||
}
|
||||
if (r != NULL) {
|
||||
BN_free(r);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
+6
-4
@@ -54,6 +54,8 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -203,14 +205,14 @@ static void BN_STACK_init(BN_STACK *st) {
|
||||
}
|
||||
|
||||
static void BN_STACK_finish(BN_STACK *st) {
|
||||
if (st->size)
|
||||
if (st->size) {
|
||||
OPENSSL_free(st->indexes);
|
||||
}
|
||||
}
|
||||
|
||||
static int BN_STACK_push(BN_STACK *st, unsigned int idx) {
|
||||
if (st->depth == st->size)
|
||||
/* Need to expand */
|
||||
{
|
||||
if (st->depth == st->size) {
|
||||
/* Need to expand */
|
||||
unsigned int newsize =
|
||||
(st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES);
|
||||
unsigned int *newitems = OPENSSL_malloc(newsize * sizeof(unsigned int));
|
||||
|
||||
+14
-7
@@ -263,7 +263,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
#ifdef BN_LLONG
|
||||
BN_ULLONG t2;
|
||||
|
||||
#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(div_asm)
|
||||
#if defined(BN_LLONG) && !defined(div_asm)
|
||||
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
|
||||
#else
|
||||
q = div_asm(n0, n1, d0);
|
||||
@@ -278,12 +278,14 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
t2 = (BN_ULLONG)d1 * q;
|
||||
|
||||
for (;;) {
|
||||
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2]))
|
||||
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0)
|
||||
if (rem < d0) {
|
||||
break; /* don't let rem overflow */
|
||||
}
|
||||
t2 -= d1;
|
||||
}
|
||||
#else /* !BN_LLONG */
|
||||
@@ -316,14 +318,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
|
||||
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0)
|
||||
if (rem < d0) {
|
||||
break; /* don't let rem overflow */
|
||||
if (t2l < d1)
|
||||
}
|
||||
if (t2l < d1) {
|
||||
t2h--;
|
||||
}
|
||||
t2l -= d1;
|
||||
}
|
||||
#endif /* !BN_LLONG */
|
||||
@@ -357,7 +362,9 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
* BN_rshift() will overwrite it.
|
||||
*/
|
||||
int neg = num->neg;
|
||||
BN_rshift(rm, snum, norm_shift);
|
||||
if (!BN_rshift(rm, snum, norm_shift)) {
|
||||
goto err;
|
||||
}
|
||||
if (!BN_is_zero(rm)) {
|
||||
rm->neg = neg;
|
||||
}
|
||||
|
||||
+98
-69
@@ -109,6 +109,7 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -416,7 +417,7 @@ err:
|
||||
|
||||
static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx) {
|
||||
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
|
||||
int i, j, bits, ret = 0, wstart, window;
|
||||
int start = 1;
|
||||
BIGNUM *aa;
|
||||
/* Table of variables obtained from 'ctx' */
|
||||
@@ -485,15 +486,16 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
start = 1; /* This is used to avoid multiplication etc
|
||||
* when there is only the value '1' in the
|
||||
* buffer. */
|
||||
wvalue = 0; /* The 'value' of the window */
|
||||
wstart = bits - 1; /* The top bit of the window */
|
||||
wend = 0; /* The bottom bit of the window */
|
||||
|
||||
if (!BN_one(r)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int wvalue; /* The 'value' of the window */
|
||||
int wend; /* The bottom bit of the window */
|
||||
|
||||
if (BN_is_bit_set(p, wstart) == 0) {
|
||||
if (!start) {
|
||||
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
|
||||
@@ -542,7 +544,6 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* move the 'window' down further */
|
||||
wstart -= wend + 1;
|
||||
wvalue = 0;
|
||||
start = 0;
|
||||
if (wstart < 0) {
|
||||
break;
|
||||
@@ -601,7 +602,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
||||
|
||||
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
|
||||
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
|
||||
int i, j, bits, ret = 0, wstart, window;
|
||||
int start = 1;
|
||||
BIGNUM *d, *r;
|
||||
const BIGNUM *aa;
|
||||
@@ -680,18 +681,18 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
start = 1; /* This is used to avoid multiplication etc
|
||||
* when there is only the value '1' in the
|
||||
* buffer. */
|
||||
wvalue = 0; /* The 'value' of the window */
|
||||
wstart = bits - 1; /* The top bit of the window */
|
||||
wend = 0; /* The bottom bit of the window */
|
||||
|
||||
j = m->top; /* borrow j */
|
||||
if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
|
||||
if (bn_wexpand(r, j) == NULL)
|
||||
if (bn_wexpand(r, j) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
/* 2^(top*BN_BITS2) - m */
|
||||
r->d[0] = (0 - m->d[0]) & BN_MASK2;
|
||||
for (i = 1; i < j; i++)
|
||||
for (i = 1; i < j; i++) {
|
||||
r->d[i] = (~m->d[i]) & BN_MASK2;
|
||||
}
|
||||
r->top = j;
|
||||
/* Upper words will be zero if the corresponding words of 'm'
|
||||
* were 0xfff[...], so decrement r->top accordingly. */
|
||||
@@ -701,10 +702,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int wvalue; /* The 'value' of the window */
|
||||
int wend; /* The bottom bit of the window */
|
||||
|
||||
if (BN_is_bit_set(p, wstart) == 0) {
|
||||
if (!start) {
|
||||
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
|
||||
goto err;
|
||||
if (!start && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (wstart == 0) {
|
||||
break;
|
||||
@@ -716,7 +719,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
/* We now have wstart on a 'set' bit, we now need to work out how bit a
|
||||
* window to do. To do this we need to scan forward until the last set bit
|
||||
* before the end of the window */
|
||||
j = wstart;
|
||||
wvalue = 1;
|
||||
wend = 0;
|
||||
for (i = 1; i < window; i++) {
|
||||
@@ -748,7 +750,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* move the 'window' down further */
|
||||
wstart -= wend + 1;
|
||||
wvalue = 0;
|
||||
start = 0;
|
||||
if (wstart < 0) {
|
||||
break;
|
||||
@@ -878,13 +879,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
/* Allocate a montgomery context if it was not supplied by the caller.
|
||||
* If this is not done, things will break in the montgomery part.
|
||||
*/
|
||||
if (in_mont != NULL)
|
||||
if (in_mont != NULL) {
|
||||
mont = in_mont;
|
||||
else {
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set(mont, m, ctx))
|
||||
} else {
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RSAZ_ENABLED
|
||||
@@ -893,8 +894,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
* crypto/bn/rsaz_exp.c and accompanying assembly modules. */
|
||||
if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024) &&
|
||||
rsaz_avx2_eligible()) {
|
||||
if (NULL == bn_wexpand(rr, 16))
|
||||
if (NULL == bn_wexpand(rr, 16)) {
|
||||
goto err;
|
||||
}
|
||||
RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d, mont->n0[0]);
|
||||
rr->top = 16;
|
||||
rr->neg = 0;
|
||||
@@ -902,8 +904,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
ret = 1;
|
||||
goto err;
|
||||
} else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
|
||||
if (NULL == bn_wexpand(rr, 8))
|
||||
if (NULL == bn_wexpand(rr, 8)) {
|
||||
goto err;
|
||||
}
|
||||
RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
|
||||
rr->top = 8;
|
||||
rr->neg = 0;
|
||||
@@ -918,8 +921,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
#if defined(OPENSSL_BN_ASM_MONT5)
|
||||
if (window >= 5) {
|
||||
window = 5; /* ~5% improvement for RSA2048 sign, and even for RSA4096 */
|
||||
if ((top & 7) == 0)
|
||||
if ((top & 7) == 0) {
|
||||
powerbufLen += 2 * top * sizeof(m->d[0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void)0;
|
||||
@@ -932,20 +936,24 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
sizeof(m->d[0]) *
|
||||
(top * numPowers + ((2 * top) > numPowers ? (2 * top) : numPowers));
|
||||
#ifdef alloca
|
||||
if (powerbufLen < 3072)
|
||||
if (powerbufLen < 3072) {
|
||||
powerbufFree = alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
|
||||
powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
|
||||
goto err;
|
||||
{
|
||||
if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
|
||||
powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
|
||||
memset(powerbuf, 0, powerbufLen);
|
||||
|
||||
#ifdef alloca
|
||||
if (powerbufLen < 3072)
|
||||
if (powerbufLen < 3072) {
|
||||
powerbufFree = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* lay down tmp and am right after powers table */
|
||||
@@ -961,20 +969,23 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
|
||||
/* 2^(top*BN_BITS2) - m */
|
||||
tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
|
||||
for (i = 1; i < top; i++)
|
||||
for (i = 1; i < top; i++) {
|
||||
tmp.d[i] = (~m->d[i]) & BN_MASK2;
|
||||
}
|
||||
tmp.top = top;
|
||||
} else if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
|
||||
} else if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* prepare a^1 in Montgomery domain */
|
||||
if (a->neg || BN_ucmp(a, m) >= 0) {
|
||||
if (!BN_mod(&am, a, m, ctx))
|
||||
if (!BN_mod(&am, a, m, ctx) ||
|
||||
!BN_to_montgomery(&am, &am, mont, ctx)) {
|
||||
goto err;
|
||||
if (!BN_to_montgomery(&am, &am, mont, ctx))
|
||||
goto err;
|
||||
} else if (!BN_to_montgomery(&am, a, mont, ctx))
|
||||
}
|
||||
} else if (!BN_to_montgomery(&am, a, mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_BN_ASM_MONT5)
|
||||
/* This optimization uses ideas from http://eprint.iacr.org/2011/239,
|
||||
@@ -1001,16 +1012,20 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* BN_to_montgomery can contaminate words above .top
|
||||
* [in BN_DEBUG[_DEBUG] build]... */
|
||||
for (i = am.top; i < top; i++)
|
||||
for (i = am.top; i < top; i++) {
|
||||
am.d[i] = 0;
|
||||
for (i = tmp.top; i < top; i++)
|
||||
}
|
||||
for (i = tmp.top; i < top; i++) {
|
||||
tmp.d[i] = 0;
|
||||
}
|
||||
|
||||
if (top & 7)
|
||||
if (top & 7) {
|
||||
np2 = np;
|
||||
else
|
||||
for (np2 = am.d + top, i = 0; i < top; i++)
|
||||
} else {
|
||||
for (np2 = am.d + top, i = 0; i < top; i++) {
|
||||
np2[2 * i] = np[i];
|
||||
}
|
||||
}
|
||||
|
||||
bn_scatter5(tmp.d, top, powerbuf, 0);
|
||||
bn_scatter5(am.d, am.top, powerbuf, 1);
|
||||
@@ -1043,8 +1058,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
}
|
||||
|
||||
bits--;
|
||||
for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
|
||||
for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) {
|
||||
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
|
||||
}
|
||||
bn_gather5(tmp.d, top, powerbuf, wvalue);
|
||||
|
||||
/* At this point |bits| is 4 mod 5 and at least -1. (|bits| is the first bit
|
||||
@@ -1056,8 +1072,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
*/
|
||||
if (top & 7) {
|
||||
while (bits >= 0) {
|
||||
for (wvalue = 0, i = 0; i < 5; i++, bits--)
|
||||
for (wvalue = 0, i = 0; i < 5; i++, bits--) {
|
||||
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
|
||||
}
|
||||
|
||||
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
|
||||
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
|
||||
@@ -1101,17 +1118,18 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
tmp.top = top;
|
||||
bn_correct_top(&tmp);
|
||||
if (ret) {
|
||||
if (!BN_copy(rr, &tmp))
|
||||
if (!BN_copy(rr, &tmp)) {
|
||||
ret = 0;
|
||||
}
|
||||
goto err; /* non-zero ret means it's not error */
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers))
|
||||
goto err;
|
||||
if (!copy_to_prebuf(&am, top, powerbuf, 1, numPowers))
|
||||
if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers) ||
|
||||
!copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If the window size is greater than 1, then calculate
|
||||
* val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
|
||||
@@ -1119,24 +1137,26 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
* to use the slight performance advantage of sqr over mul).
|
||||
*/
|
||||
if (window > 1) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
|
||||
goto err;
|
||||
if (!copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers))
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx) ||
|
||||
!copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
|
||||
goto err;
|
||||
}
|
||||
for (i = 3; i < numPowers; i++) {
|
||||
/* Calculate a^i = a^(i-1) * a */
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
|
||||
goto err;
|
||||
if (!copy_to_prebuf(&tmp, top, powerbuf, i, numPowers))
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx) ||
|
||||
!copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bits--;
|
||||
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
|
||||
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) {
|
||||
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
|
||||
if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers))
|
||||
}
|
||||
if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Scan the exponent one window at a time starting from the most
|
||||
* significant bits.
|
||||
@@ -1146,32 +1166,38 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* Scan the window, squaring the result as we go */
|
||||
for (i = 0; i < window; i++, bits--) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
|
||||
}
|
||||
|
||||
/* Fetch the appropriate pre-computed value from the pre-buf */
|
||||
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers))
|
||||
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Multiply the result into the intermediate result */
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the final result from montgomery to standard format */
|
||||
if (!BN_from_montgomery(rr, &tmp, mont, ctx))
|
||||
if (!BN_from_montgomery(rr, &tmp, mont, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if ((in_mont == NULL) && (mont != NULL))
|
||||
if ((in_mont == NULL) && (mont != NULL)) {
|
||||
BN_MONT_CTX_free(mont);
|
||||
}
|
||||
if (powerbuf != NULL) {
|
||||
OPENSSL_cleanse(powerbuf, powerbufLen);
|
||||
if (powerbufFree)
|
||||
if (powerbufFree) {
|
||||
OPENSSL_free(powerbufFree);
|
||||
}
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
return (ret);
|
||||
@@ -1238,13 +1264,11 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (in_mont != NULL)
|
||||
if (in_mont != NULL) {
|
||||
mont = in_mont;
|
||||
else {
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (!BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
} else {
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -1477,28 +1501,33 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
|
||||
if (!wvalue1 && BN_is_bit_set(p1, b)) {
|
||||
/* consider bits b-window1+1 .. b for this window */
|
||||
i = b - window1 + 1;
|
||||
while (!BN_is_bit_set(p1, i)) /* works for i<0 */
|
||||
/* works for i<0 */
|
||||
while (!BN_is_bit_set(p1, i)) {
|
||||
i++;
|
||||
}
|
||||
wpos1 = i;
|
||||
wvalue1 = 1;
|
||||
for (i = b - 1; i >= wpos1; i--) {
|
||||
wvalue1 <<= 1;
|
||||
if (BN_is_bit_set(p1, i))
|
||||
if (BN_is_bit_set(p1, i)) {
|
||||
wvalue1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!wvalue2 && BN_is_bit_set(p2, b)) {
|
||||
/* consider bits b-window2+1 .. b for this window */
|
||||
i = b - window2 + 1;
|
||||
while (!BN_is_bit_set(p2, i))
|
||||
while (!BN_is_bit_set(p2, i)) {
|
||||
i++;
|
||||
}
|
||||
wpos2 = i;
|
||||
wvalue2 = 1;
|
||||
for (i = b - 1; i >= wpos2; i--) {
|
||||
wvalue2 <<= 1;
|
||||
if (BN_is_bit_set(p2, i))
|
||||
if (BN_is_bit_set(p2, i)) {
|
||||
wvalue2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-11
@@ -258,12 +258,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_one(X);
|
||||
BN_zero(Y);
|
||||
if (BN_copy(B, a) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_copy(A, n) == NULL) {
|
||||
if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
A->neg = 0;
|
||||
@@ -570,12 +566,8 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_one(X);
|
||||
BN_zero(Y);
|
||||
if (BN_copy(B, a) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_copy(A, n) == NULL) {
|
||||
if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
A->neg = 0;
|
||||
@@ -586,8 +578,9 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
|
||||
*/
|
||||
pB = &local_B;
|
||||
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
if (!BN_nnmod(B, pB, A, ctx))
|
||||
if (!BN_nnmod(B, pB, A, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
|
||||
+144
-207
@@ -130,40 +130,8 @@
|
||||
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
|
||||
}
|
||||
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
#define mul_add(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULONG high, low, ret, tmp = (a); \
|
||||
ret = (r); \
|
||||
high = BN_UMULT_HIGH(w, tmp); \
|
||||
ret += (c); \
|
||||
low = (w) * tmp; \
|
||||
(c) = (ret < (c)) ? 1 : 0; \
|
||||
(c) += high; \
|
||||
ret += low; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
|
||||
#define mul(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULONG high, low, ret, ta = (a); \
|
||||
low = (w) * ta; \
|
||||
high = BN_UMULT_HIGH(w, ta); \
|
||||
ret = low + (c); \
|
||||
(c) = high; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
|
||||
#define sqr(r0, r1, a) \
|
||||
{ \
|
||||
BN_ULONG tmp = (a); \
|
||||
(r0) = tmp * tmp; \
|
||||
(r1) = BN_UMULT_HIGH(tmp, tmp); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*************************************************************
|
||||
* No long long type
|
||||
*/
|
||||
@@ -424,7 +392,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
|
||||
#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
|
||||
|
||||
#if defined(BN_LLONG) && defined(BN_DIV2W)
|
||||
#if defined(BN_LLONG)
|
||||
|
||||
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
|
||||
@@ -502,7 +470,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
@@ -617,23 +585,27 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
t1 = a[0];
|
||||
t2 = b[0];
|
||||
r[0] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[1];
|
||||
t2 = b[1];
|
||||
r[1] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[2];
|
||||
t2 = b[2];
|
||||
r[2] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[3];
|
||||
t2 = b[3];
|
||||
r[3] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
}
|
||||
a += 4;
|
||||
b += 4;
|
||||
r += 4;
|
||||
@@ -643,8 +615,9 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
t1 = a[0];
|
||||
t2 = b[0];
|
||||
r[0] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2)
|
||||
if (t1 != t2) {
|
||||
c = (t1 < t2);
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
r++;
|
||||
@@ -659,175 +632,151 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
tt = (t + t) & BN_MASK; \
|
||||
if (tt < t) \
|
||||
c2++; \
|
||||
t1 = (BN_ULONG)Lw(tt); \
|
||||
t2 = (BN_ULONG)Hw(tt); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
/* Keep in mind that additions to multiplication result can not overflow,
|
||||
* because its high half cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
BN_ULLONG tt = t + c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(tt); \
|
||||
hi = (BN_ULONG)Hw(tt); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_LOHI)
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because the high word of
|
||||
* a multiplication result cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_UMULT_LOHI(t1, t2, ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
BN_UMULT_LOHI(t0, t1, ta, tb); \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_ULONG lo, hi, tt; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
tt = hi + ((c0 < lo) ? 1 : 0); \
|
||||
c1 += tt; \
|
||||
c2 += (c1 < tt) ? 1 : 0; \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
BN_UMULT_LOHI(t1, t2, ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
t1 = ta * tb; \
|
||||
t2 = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
t1 = BN_UMULT_HIGH(ta, tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
t1 = ta * ta; \
|
||||
t2 = BN_UMULT_HIGH(ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, ta); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
if (t2 & BN_TBIT) \
|
||||
c2++; \
|
||||
t2 = (t2 + t2) & BN_MASK2; \
|
||||
if (t1 & BN_TBIT) \
|
||||
t2++; \
|
||||
t1 = (t1 + t1) & BN_MASK2; \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
* the high word of a multiplication result cannot be all-ones. */
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG tt; \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
tt = hi; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
tt++; \
|
||||
c1 = (c1 + tt) & BN_MASK2; \
|
||||
if (c1 < tt) \
|
||||
c2++; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
sqr64(t1, t2, (a)[i]); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
do { \
|
||||
BN_ULONG lo, hi; \
|
||||
sqr64(lo, hi, (a)[i]); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
#endif /* !BN_LLONG */
|
||||
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -930,12 +879,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -974,12 +917,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -1054,12 +991,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -1124,11 +1055,13 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
#ifdef mul64
|
||||
mh = HBITS(ml);
|
||||
ml = LBITS(ml);
|
||||
for (j = 0; j < num; ++j)
|
||||
for (j = 0; j < num; ++j) {
|
||||
mul(tp[j], ap[j], ml, mh, c0);
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < num; ++j)
|
||||
for (j = 0; j < num; ++j) {
|
||||
mul(tp[j], ap[j], ml, c0);
|
||||
}
|
||||
#endif
|
||||
|
||||
tp[num] = c0;
|
||||
@@ -1141,11 +1074,13 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
#ifdef mul64
|
||||
mh = HBITS(ml);
|
||||
ml = LBITS(ml);
|
||||
for (j = 0; j < num; ++j)
|
||||
for (j = 0; j < num; ++j) {
|
||||
mul_add(tp[j], ap[j], ml, mh, c0);
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < num; ++j)
|
||||
for (j = 0; j < num; ++j) {
|
||||
mul_add(tp[j], ap[j], ml, c0);
|
||||
}
|
||||
#endif
|
||||
c1 = (tp[num] + c0) & BN_MASK2;
|
||||
tp[num] = c1;
|
||||
@@ -1178,13 +1113,15 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
|
||||
c0 = bn_sub_words(rp, tp, np, num);
|
||||
if (tp[num] != 0 || c0 == 0) {
|
||||
for (i = 0; i < num + 2; i++)
|
||||
for (i = 0; i < num + 2; i++) {
|
||||
vp[i] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < num; i++)
|
||||
for (i = 0; i < num; i++) {
|
||||
rp[i] = tp[i], vp[i] = 0;
|
||||
}
|
||||
vp[num] = 0;
|
||||
vp[num + 1] = 0;
|
||||
return 1;
|
||||
|
||||
+31
-12
@@ -127,6 +127,13 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#pragma warning(push, 3)
|
||||
#include <intrin.h>
|
||||
#pragma warning(pop)
|
||||
#pragma intrinsic(__umulh, _umul128)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -137,8 +144,14 @@ BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
|
||||
|
||||
#if defined(OPENSSL_64_BIT)
|
||||
|
||||
#define BN_ULLONG unsigned long long
|
||||
#if !defined(_MSC_VER)
|
||||
/* MSVC doesn't support two-word integers on 64-bit. */
|
||||
#define BN_LLONG __int128_t
|
||||
#define BN_ULLONG __uint128_t
|
||||
#endif
|
||||
|
||||
#define BN_BITS 128
|
||||
#define BN_BITS2 64
|
||||
#define BN_BYTES 8
|
||||
#define BN_BITS4 32
|
||||
#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
|
||||
@@ -155,9 +168,11 @@ BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
|
||||
|
||||
#elif defined(OPENSSL_32_BIT)
|
||||
|
||||
#define BN_ULLONG unsigned long long
|
||||
#define BN_MASK (0xffffffffffffffffLL)
|
||||
#define BN_LLONG int64_t
|
||||
#define BN_ULLONG uint64_t
|
||||
#define BN_MASK (0xffffffffffffffffLL)
|
||||
#define BN_BITS 64
|
||||
#define BN_BITS2 32
|
||||
#define BN_BYTES 4
|
||||
#define BN_BITS4 16
|
||||
#define BN_MASK2 (0xffffffffL)
|
||||
@@ -183,6 +198,11 @@ BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
|
||||
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
|
||||
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
|
||||
|
||||
#if defined(BN_LLONG)
|
||||
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
|
||||
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
|
||||
#endif
|
||||
|
||||
BN_ULONG bn_mul_add_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, int num, BN_ULONG w);
|
||||
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
|
||||
@@ -208,6 +228,8 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
|
||||
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
||||
|
||||
#if !defined(BN_LLONG)
|
||||
|
||||
#define LBITS(a) ((a) & BN_MASK2l)
|
||||
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
|
||||
#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
|
||||
@@ -238,8 +260,10 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
(h) = ht; \
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
# if defined(__GNUC__) && __GNUC__ >= 2
|
||||
# define BN_UMULT_HIGH(a,b) ({ \
|
||||
register BN_ULONG ret,discard; \
|
||||
__asm__ ("mulq %3" \
|
||||
@@ -252,14 +276,9 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
: "=a"(low),"=d"(high) \
|
||||
: "a"(a),"g"(b) \
|
||||
: "cc");
|
||||
# endif
|
||||
# if defined(_MSC_VER) && _MSC_VER>=1400
|
||||
unsigned __int64 __umulh (unsigned __int64 a,unsigned __int64 b);
|
||||
unsigned __int64 _umul128 (unsigned __int64 a,unsigned __int64 b,
|
||||
unsigned __int64 *h);
|
||||
# pragma intrinsic(__umulh,_umul128)
|
||||
# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
|
||||
# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# define BN_UMULT_HIGH(a, b) __umulh((a), (b))
|
||||
# define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
|
||||
# endif
|
||||
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/thread.h>
|
||||
|
||||
@@ -512,8 +514,9 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_copy(t, a))
|
||||
if (BN_copy(t, a)) {
|
||||
retn = BN_from_montgomery_word(ret, t, mont);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return retn;
|
||||
|
||||
+5
-2
@@ -57,6 +57,7 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -149,8 +150,9 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
|
||||
assert(cl >= 0);
|
||||
c = bn_sub_words(r, a, b, cl);
|
||||
|
||||
if (dl == 0)
|
||||
if (dl == 0) {
|
||||
return c;
|
||||
}
|
||||
|
||||
r += cl;
|
||||
a += cl;
|
||||
@@ -329,8 +331,9 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
|
||||
/* Else do normal multiply */
|
||||
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
|
||||
bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
|
||||
if ((dna + dnb) < 0)
|
||||
if ((dna + dnb) < 0) {
|
||||
memset(&r[2 * n2 + dna + dnb], 0, sizeof(BN_ULONG) * -(dna + dnb));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+194
-194
@@ -138,9 +138,196 @@
|
||||
/* NUMPRIMES is the number of primes that fit into a uint16_t. */
|
||||
#define NUMPRIMES 2048
|
||||
|
||||
/* primes is defined at the bottom of the file and contains all the primes that
|
||||
* fit into a uint16_t. */
|
||||
static const uint16_t primes[NUMPRIMES];
|
||||
/* primes contains all the primes that fit into a uint16_t. */
|
||||
static const uint16_t primes[NUMPRIMES] = {
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
|
||||
37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79,
|
||||
83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
|
||||
139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
|
||||
197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
|
||||
263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
|
||||
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
|
||||
397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457,
|
||||
461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
|
||||
541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
|
||||
607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
|
||||
673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
|
||||
751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823,
|
||||
827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
|
||||
907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977,
|
||||
983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
|
||||
1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117,
|
||||
1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
|
||||
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289,
|
||||
1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
|
||||
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453,
|
||||
1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531,
|
||||
1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607,
|
||||
1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
|
||||
1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777,
|
||||
1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
|
||||
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951,
|
||||
1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029,
|
||||
2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113,
|
||||
2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
|
||||
2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293,
|
||||
2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
|
||||
2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447,
|
||||
2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
|
||||
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659,
|
||||
2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713,
|
||||
2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,
|
||||
2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887,
|
||||
2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971,
|
||||
2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
|
||||
3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187,
|
||||
3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
|
||||
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359,
|
||||
3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461,
|
||||
3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
|
||||
3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617,
|
||||
3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701,
|
||||
3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
|
||||
3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889,
|
||||
3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
|
||||
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073,
|
||||
4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157,
|
||||
4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253,
|
||||
4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349,
|
||||
4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451,
|
||||
4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
|
||||
4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643,
|
||||
4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
|
||||
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817,
|
||||
4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
|
||||
4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009,
|
||||
5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,
|
||||
5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209,
|
||||
5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
|
||||
5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417,
|
||||
5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501,
|
||||
5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581,
|
||||
5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683,
|
||||
5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783,
|
||||
5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
|
||||
5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953,
|
||||
5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
|
||||
6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163,
|
||||
6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263,
|
||||
6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337,
|
||||
6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427,
|
||||
6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553,
|
||||
6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659,
|
||||
6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737,
|
||||
6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
|
||||
6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947,
|
||||
6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013,
|
||||
7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127,
|
||||
7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229,
|
||||
7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333,
|
||||
7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477,
|
||||
7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547,
|
||||
7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
|
||||
7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717,
|
||||
7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
|
||||
7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927,
|
||||
7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053,
|
||||
8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147,
|
||||
8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237,
|
||||
8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329,
|
||||
8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
|
||||
8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563,
|
||||
8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663,
|
||||
8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737,
|
||||
8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
|
||||
8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933,
|
||||
8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029,
|
||||
9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137,
|
||||
9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
|
||||
9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337,
|
||||
9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421,
|
||||
9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497,
|
||||
9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623,
|
||||
9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721,
|
||||
9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
|
||||
9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901,
|
||||
9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
|
||||
10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133,
|
||||
10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223,
|
||||
10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313,
|
||||
10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429,
|
||||
10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529,
|
||||
10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639,
|
||||
10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733,
|
||||
10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
|
||||
10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957,
|
||||
10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071,
|
||||
11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171,
|
||||
11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279,
|
||||
11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393,
|
||||
11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491,
|
||||
11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617,
|
||||
11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
|
||||
11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831,
|
||||
11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933,
|
||||
11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037,
|
||||
12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119,
|
||||
12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241,
|
||||
12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343,
|
||||
12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437,
|
||||
12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
|
||||
12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613,
|
||||
12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713,
|
||||
12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823,
|
||||
12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923,
|
||||
12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009,
|
||||
13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127,
|
||||
13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229,
|
||||
13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
|
||||
13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457,
|
||||
13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577,
|
||||
13591, 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687,
|
||||
13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759,
|
||||
13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877,
|
||||
13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967,
|
||||
13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083,
|
||||
14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
|
||||
14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347,
|
||||
14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447,
|
||||
14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551,
|
||||
14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653,
|
||||
14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747,
|
||||
14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831,
|
||||
14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939,
|
||||
14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
|
||||
15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161,
|
||||
15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269,
|
||||
15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349,
|
||||
15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443,
|
||||
15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559,
|
||||
15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649,
|
||||
15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749,
|
||||
15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
|
||||
15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959,
|
||||
15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069,
|
||||
16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187,
|
||||
16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301,
|
||||
16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421,
|
||||
16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529,
|
||||
16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649,
|
||||
16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
|
||||
16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883,
|
||||
16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981,
|
||||
16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077,
|
||||
17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191,
|
||||
17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321,
|
||||
17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401,
|
||||
17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491,
|
||||
17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
|
||||
17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729,
|
||||
17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839,
|
||||
17851, 17863,
|
||||
};
|
||||
|
||||
static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
|
||||
const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
|
||||
@@ -495,8 +682,9 @@ loop:
|
||||
for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) {
|
||||
if ((mods[i] + delta) % primes[i] == 0) {
|
||||
delta += 2;
|
||||
if (delta > maxdelta)
|
||||
if (delta > maxdelta) {
|
||||
goto again;
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
@@ -506,8 +694,9 @@ loop:
|
||||
* that gcd(rnd-1,primes) == 1 (except for 2) */
|
||||
if (((mods[i] + delta) % primes[i]) <= 1) {
|
||||
delta += 2;
|
||||
if (delta > maxdelta)
|
||||
if (delta > maxdelta) {
|
||||
goto again;
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
@@ -649,192 +838,3 @@ err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const uint16_t primes[NUMPRIMES] = {
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
|
||||
37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79,
|
||||
83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
|
||||
139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
|
||||
197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
|
||||
263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
|
||||
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
|
||||
397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457,
|
||||
461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
|
||||
541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
|
||||
607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
|
||||
673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
|
||||
751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823,
|
||||
827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
|
||||
907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977,
|
||||
983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
|
||||
1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117,
|
||||
1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
|
||||
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289,
|
||||
1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
|
||||
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453,
|
||||
1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531,
|
||||
1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607,
|
||||
1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
|
||||
1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777,
|
||||
1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
|
||||
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951,
|
||||
1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029,
|
||||
2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113,
|
||||
2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
|
||||
2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293,
|
||||
2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
|
||||
2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447,
|
||||
2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
|
||||
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659,
|
||||
2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713,
|
||||
2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,
|
||||
2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887,
|
||||
2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971,
|
||||
2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
|
||||
3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187,
|
||||
3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
|
||||
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359,
|
||||
3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461,
|
||||
3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
|
||||
3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617,
|
||||
3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701,
|
||||
3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
|
||||
3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889,
|
||||
3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
|
||||
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073,
|
||||
4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157,
|
||||
4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253,
|
||||
4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349,
|
||||
4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451,
|
||||
4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
|
||||
4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643,
|
||||
4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
|
||||
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817,
|
||||
4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
|
||||
4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009,
|
||||
5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,
|
||||
5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209,
|
||||
5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
|
||||
5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417,
|
||||
5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501,
|
||||
5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581,
|
||||
5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683,
|
||||
5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783,
|
||||
5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
|
||||
5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953,
|
||||
5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
|
||||
6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163,
|
||||
6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263,
|
||||
6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337,
|
||||
6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427,
|
||||
6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553,
|
||||
6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659,
|
||||
6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737,
|
||||
6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
|
||||
6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947,
|
||||
6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013,
|
||||
7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127,
|
||||
7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229,
|
||||
7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333,
|
||||
7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477,
|
||||
7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547,
|
||||
7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
|
||||
7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717,
|
||||
7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
|
||||
7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927,
|
||||
7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053,
|
||||
8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147,
|
||||
8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237,
|
||||
8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329,
|
||||
8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
|
||||
8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563,
|
||||
8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663,
|
||||
8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737,
|
||||
8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
|
||||
8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933,
|
||||
8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029,
|
||||
9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137,
|
||||
9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
|
||||
9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337,
|
||||
9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421,
|
||||
9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497,
|
||||
9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623,
|
||||
9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721,
|
||||
9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
|
||||
9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901,
|
||||
9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
|
||||
10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133,
|
||||
10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223,
|
||||
10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313,
|
||||
10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429,
|
||||
10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529,
|
||||
10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639,
|
||||
10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733,
|
||||
10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
|
||||
10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957,
|
||||
10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071,
|
||||
11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171,
|
||||
11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279,
|
||||
11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393,
|
||||
11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491,
|
||||
11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617,
|
||||
11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
|
||||
11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831,
|
||||
11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933,
|
||||
11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037,
|
||||
12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119,
|
||||
12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241,
|
||||
12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343,
|
||||
12347, 12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437,
|
||||
12451, 12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
|
||||
12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613,
|
||||
12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713,
|
||||
12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823,
|
||||
12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923,
|
||||
12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009,
|
||||
13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127,
|
||||
13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229,
|
||||
13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
|
||||
13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457,
|
||||
13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577,
|
||||
13591, 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687,
|
||||
13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759,
|
||||
13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877,
|
||||
13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967,
|
||||
13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083,
|
||||
14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
|
||||
14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347,
|
||||
14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447,
|
||||
14449, 14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551,
|
||||
14557, 14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653,
|
||||
14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747,
|
||||
14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831,
|
||||
14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939,
|
||||
14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
|
||||
15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161,
|
||||
15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269,
|
||||
15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349,
|
||||
15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443,
|
||||
15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559,
|
||||
15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649,
|
||||
15661, 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749,
|
||||
15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
|
||||
15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959,
|
||||
15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069,
|
||||
16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187,
|
||||
16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301,
|
||||
16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421,
|
||||
16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529,
|
||||
16547, 16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649,
|
||||
16651, 16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
|
||||
16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883,
|
||||
16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981,
|
||||
16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077,
|
||||
17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191,
|
||||
17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321,
|
||||
17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401,
|
||||
17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491,
|
||||
17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
|
||||
17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729,
|
||||
17737, 17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839,
|
||||
17851, 17863, };
|
||||
|
||||
+6
-3
@@ -108,6 +108,8 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/rand.h>
|
||||
@@ -136,9 +138,10 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* make a random number and set the top and bottom bits */
|
||||
if (RAND_pseudo_bytes(buf, bytes) <= 0)
|
||||
/* Make a random number and set the top and bottom bits. */
|
||||
if (!RAND_bytes(buf, bytes)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (top != -1) {
|
||||
if (top) {
|
||||
@@ -286,7 +289,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
|
||||
|
||||
for (attempt = 0;; attempt++) {
|
||||
for (done = 0; done < num_k_bytes;) {
|
||||
if (RAND_pseudo_bytes(random_bytes, sizeof(random_bytes)) != 1) {
|
||||
if (!RAND_bytes(random_bytes, sizeof(random_bytes))) {
|
||||
goto err;
|
||||
}
|
||||
SHA512_Init(&sha);
|
||||
|
||||
@@ -56,8 +56,11 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
|
||||
int i, nw, lb, rb;
|
||||
BN_ULONG *t, *f;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
buf
|
||||
buf
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
buf.c
|
||||
buf_error.c
|
||||
buf.c
|
||||
)
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/buf.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/* Copyright (c) 2014, 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/err.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
|
||||
const ERR_STRING_DATA BUF_error_string_data[] = {
|
||||
{ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_new, 0), "BUF_MEM_new"},
|
||||
{ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_memdup, 0), "BUF_memdup"},
|
||||
{ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_strndup, 0), "BUF_strndup"},
|
||||
{ERR_PACK(ERR_LIB_BUF, BUF_F_buf_mem_grow, 0), "buf_mem_grow"},
|
||||
{0, NULL},
|
||||
};
|
||||
@@ -1,19 +1,19 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
bytestring
|
||||
bytestring
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
ber.c
|
||||
cbs.c
|
||||
cbb.c
|
||||
ber.c
|
||||
cbs.c
|
||||
cbb.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
bytestring_test
|
||||
bytestring_test
|
||||
|
||||
bytestring_test.c
|
||||
bytestring_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(bytestring_test crypto)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
@@ -122,15 +124,17 @@ static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
|
||||
* implicit and the tags within are fragments of a primitive type that
|
||||
* need to be concatenated. */
|
||||
if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
|
||||
CBS in_copy, contents;
|
||||
unsigned tag;
|
||||
size_t header_len;
|
||||
CBS in_copy, inner_contents;
|
||||
unsigned inner_tag;
|
||||
size_t inner_header_len;
|
||||
|
||||
CBS_init(&in_copy, CBS_data(in), CBS_len(in));
|
||||
if (!CBS_get_any_asn1_element(&in_copy, &contents, &tag, &header_len)) {
|
||||
if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag,
|
||||
&inner_header_len)) {
|
||||
return 0;
|
||||
}
|
||||
if (CBS_len(&contents) > header_len && is_primitive_type(tag)) {
|
||||
if (CBS_len(&inner_contents) > inner_header_len &&
|
||||
is_primitive_type(inner_tag)) {
|
||||
squash_child_headers = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
+12
-2
@@ -15,6 +15,7 @@
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -24,7 +25,6 @@ static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
|
||||
|
||||
base = OPENSSL_malloc(sizeof(struct cbb_buffer_st));
|
||||
if (base == NULL) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,12 @@ int CBB_init(CBB *cbb, size_t initial_capacity) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cbb_init(cbb, buf, initial_capacity);
|
||||
if (!cbb_init(cbb, buf, initial_capacity)) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
|
||||
@@ -275,6 +280,11 @@ int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) {
|
||||
}
|
||||
|
||||
int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
|
||||
if ((tag & 0x1f) == 0x1f) {
|
||||
/* Long form identifier octets are not supported. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb) ||
|
||||
!CBB_add_u8(cbb, tag)) {
|
||||
return 0;
|
||||
|
||||
@@ -82,8 +82,9 @@ int CBS_contains_zero_byte(const CBS *cbs) {
|
||||
}
|
||||
|
||||
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
|
||||
if (len != cbs->len)
|
||||
if (len != cbs->len) {
|
||||
return 0;
|
||||
}
|
||||
return CRYPTO_memcmp(cbs->data, data, len) == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
if (${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
CHACHA_ARCH_SOURCES
|
||||
set(
|
||||
CHACHA_ARCH_SOURCES
|
||||
|
||||
chacha_vec_arm.S
|
||||
)
|
||||
chacha_vec_arm.S
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
chacha
|
||||
chacha
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
chacha_generic.c
|
||||
chacha_vec.c
|
||||
chacha_generic.c
|
||||
chacha_vec.c
|
||||
|
||||
${CHACHA_ARCH_SOURCES}
|
||||
${CHACHA_ARCH_SOURCES}
|
||||
)
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
#include <openssl/chacha.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
|
||||
#if defined(OPENSSL_WINDOWS) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || !defined(__SSE2__)
|
||||
|
||||
/* sigma contains the ChaCha constants, which happen to be an ASCII string. */
|
||||
static const char sigma[16] = "expand 32-byte k";
|
||||
static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
|
||||
'2', '-', 'b', 'y', 't', 'e', ' ', 'k' };
|
||||
|
||||
#define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
|
||||
#define XOR(v, w) ((v) ^ (w))
|
||||
@@ -54,7 +58,7 @@ void CRYPTO_chacha_20_neon(uint8_t *out, const uint8_t *in, size_t in_len,
|
||||
size_t counter);
|
||||
#endif
|
||||
|
||||
/* chacha_core performs |num_rounds| rounds of ChaCha20 on the input words in
|
||||
/* chacha_core performs 20 rounds of ChaCha on the input words in
|
||||
* |input| and writes the 64 output bytes to |output|. */
|
||||
static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
|
||||
uint32_t x[16];
|
||||
@@ -88,8 +92,7 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
|
||||
size_t todo, i;
|
||||
|
||||
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
|
||||
if (CRYPTO_is_NEON_capable() && ((intptr_t)in & 15) == 0 &&
|
||||
((intptr_t)out & 15) == 0) {
|
||||
if (CRYPTO_is_NEON_capable()) {
|
||||
CRYPTO_chacha_20_neon(out, in, in_len, key, nonce, counter);
|
||||
return;
|
||||
}
|
||||
|
||||
+19
-21
@@ -25,7 +25,9 @@
|
||||
|
||||
#include <openssl/chacha.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS) && (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) && defined(__SSE2__)
|
||||
#if defined(ASM_GEN) || \
|
||||
!defined(OPENSSL_WINDOWS) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) && defined(__SSE2__)
|
||||
|
||||
#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
|
||||
|
||||
@@ -38,12 +40,20 @@ typedef unsigned vec __attribute__((vector_size(16)));
|
||||
* This implementation supports parallel processing of multiple blocks,
|
||||
* including potentially using general-purpose registers. */
|
||||
#if __ARM_NEON__
|
||||
#include <string.h>
|
||||
#include <arm_neon.h>
|
||||
#define GPR_TOO 1
|
||||
#define VBPI 2
|
||||
#define ONE (vec) vsetq_lane_u32(1, vdupq_n_u32(0), 0)
|
||||
#define LOAD(m) (vec)(*((vec *)(m)))
|
||||
#define STORE(m, r) (*((vec *)(m))) = (r)
|
||||
#define LOAD_ALIGNED(m) (vec)(*((vec *)(m)))
|
||||
#define LOAD(m) ({ \
|
||||
memcpy(alignment_buffer, m, 16); \
|
||||
LOAD_ALIGNED(alignment_buffer); \
|
||||
})
|
||||
#define STORE(m, r) ({ \
|
||||
(*((vec *)(alignment_buffer))) = (r); \
|
||||
memcpy(m, alignment_buffer, 16); \
|
||||
})
|
||||
#define ROTV1(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 1)
|
||||
#define ROTV2(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 2)
|
||||
#define ROTV3(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 3)
|
||||
@@ -71,6 +81,7 @@ typedef unsigned vec __attribute__((vector_size(16)));
|
||||
#endif
|
||||
#define ONE (vec) _mm_set_epi32(0, 0, 0, 1)
|
||||
#define LOAD(m) (vec) _mm_loadu_si128((__m128i *)(m))
|
||||
#define LOAD_ALIGNED(m) (vec) _mm_load_si128((__m128i *)(m))
|
||||
#define STORE(m, r) _mm_storeu_si128((__m128i *)(m), (__m128i)(r))
|
||||
#define ROTV1(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(0, 3, 2, 1))
|
||||
#define ROTV2(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(1, 0, 3, 2))
|
||||
@@ -148,30 +159,17 @@ void CRYPTO_chacha_20(
|
||||
{
|
||||
unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
|
||||
#if defined(__ARM_NEON__)
|
||||
unsigned *np;
|
||||
uint32_t np[2];
|
||||
uint8_t alignment_buffer[16] __attribute__((aligned(16)));
|
||||
#endif
|
||||
vec s0, s1, s2, s3;
|
||||
#if !defined(__ARM_NEON__) && !defined(__SSE2__)
|
||||
__attribute__ ((aligned (16))) unsigned key[8], nonce[4];
|
||||
#endif
|
||||
__attribute__ ((aligned (16))) unsigned chacha_const[] =
|
||||
{0x61707865,0x3320646E,0x79622D32,0x6B206574};
|
||||
#if defined(__ARM_NEON__) || defined(__SSE2__)
|
||||
kp = (unsigned *)key;
|
||||
#else
|
||||
((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
|
||||
((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
|
||||
nonce[0] = REVW_BE(((unsigned *)nonce)[0]);
|
||||
nonce[1] = REVW_BE(((unsigned *)nonce)[1]);
|
||||
nonce[2] = REVW_BE(((unsigned *)nonce)[2]);
|
||||
nonce[3] = REVW_BE(((unsigned *)nonce)[3]);
|
||||
kp = (unsigned *)key;
|
||||
np = (unsigned *)nonce;
|
||||
#endif
|
||||
#if defined(__ARM_NEON__)
|
||||
np = (unsigned*) nonce;
|
||||
memcpy(np, nonce, 8);
|
||||
#endif
|
||||
s0 = LOAD(chacha_const);
|
||||
s0 = LOAD_ALIGNED(chacha_const);
|
||||
s1 = LOAD(&((vec*)kp)[0]);
|
||||
s2 = LOAD(&((vec*)kp)[1]);
|
||||
s3 = (vec){
|
||||
@@ -326,4 +324,4 @@ void CRYPTO_chacha_20(
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !OPENSSL_WINDOWS && (OPENSSL_X86_64 || OPENSSL_X86) && SSE2 */
|
||||
#endif /* ASM_GEN || !OPENSSL_WINDOWS && (OPENSSL_X86_64 || OPENSSL_X86) && SSE2 */
|
||||
|
||||
+1333
-797
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2014, 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 package generates chacha_vec_arm.S from chacha_vec.c.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const defaultCompiler = "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
|
||||
|
||||
func main() {
|
||||
compiler := defaultCompiler
|
||||
if len(os.Args) > 1 {
|
||||
compiler = os.Args[1]
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-O3",
|
||||
"-mcpu=cortex-a8",
|
||||
"-mfpu=neon",
|
||||
"-fpic",
|
||||
"-DASM_GEN",
|
||||
"-I", "../../include",
|
||||
"-S", "chacha_vec.c",
|
||||
"-o", "-",
|
||||
}
|
||||
|
||||
output, err := os.OpenFile("chacha_vec_arm.S", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer output.Close()
|
||||
|
||||
output.WriteString(preamble)
|
||||
output.WriteString(compiler)
|
||||
output.WriteString(" ")
|
||||
output.WriteString(strings.Join(args, " "))
|
||||
output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n\n")
|
||||
|
||||
cmd := exec.Command(compiler, args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
asm, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
attr28 := []byte(".eabi_attribute 28,")
|
||||
globalDirective := []byte(".global\t")
|
||||
newLine := []byte("\n")
|
||||
attr28Handled := false
|
||||
|
||||
scanner := bufio.NewScanner(asm)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Bytes()
|
||||
|
||||
if bytes.Contains(line, attr28) {
|
||||
output.WriteString(attr28Block)
|
||||
attr28Handled = true
|
||||
continue
|
||||
}
|
||||
|
||||
output.Write(line)
|
||||
output.Write(newLine)
|
||||
|
||||
if i := bytes.Index(line, globalDirective); i >= 0 {
|
||||
output.Write(line[:i])
|
||||
output.WriteString(".hidden\t")
|
||||
output.Write(line[i+len(globalDirective):])
|
||||
output.Write(newLine)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !attr28Handled {
|
||||
panic("EABI attribute 28 not seen in processing")
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
output.WriteString(trailer)
|
||||
}
|
||||
|
||||
const preamble = `# Copyright (c) 2014, Google Inc.
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# This file contains a pre-compiled version of chacha_vec.c for ARM. This is
|
||||
# needed to support switching on NEON code at runtime. If the whole of OpenSSL
|
||||
# were to be compiled with the needed flags to build chacha_vec.c, then it
|
||||
# wouldn't be possible to run on non-NEON systems.
|
||||
#
|
||||
# This file was generated by chacha_vec_arm_generate.go using the following
|
||||
# compiler command:
|
||||
#
|
||||
# `
|
||||
|
||||
const attr28Block = `
|
||||
# EABI attribute 28 sets whether VFP register arguments were used to build this
|
||||
# file. If object files are inconsistent on this point, the linker will refuse
|
||||
# to link them. Thus we report whatever the compiler expects since we don't use
|
||||
# VFP arguments.
|
||||
|
||||
#if defined(__ARM_PCS_VFP)
|
||||
.eabi_attribute 28, 1
|
||||
#else
|
||||
.eabi_attribute 28, 0
|
||||
#endif
|
||||
|
||||
`
|
||||
|
||||
const trailer = `
|
||||
#endif /* !OPENSSL_NO_ASM */
|
||||
`
|
||||
@@ -1,33 +1,36 @@
|
||||
include_directories(. .. ../../include)
|
||||
|
||||
add_library(
|
||||
cipher
|
||||
cipher
|
||||
|
||||
OBJECT
|
||||
OBJECT
|
||||
|
||||
cipher.c
|
||||
cipher_error.c
|
||||
derive_key.c
|
||||
aead.c
|
||||
cipher.c
|
||||
derive_key.c
|
||||
aead.c
|
||||
|
||||
e_null.c
|
||||
e_rc2.c
|
||||
e_rc4.c
|
||||
e_des.c
|
||||
e_aes.c
|
||||
e_chacha20poly1305.c
|
||||
e_null.c
|
||||
e_rc2.c
|
||||
e_rc4.c
|
||||
e_des.c
|
||||
e_aes.c
|
||||
e_chacha20poly1305.c
|
||||
|
||||
tls_cbc.c
|
||||
e_tls.c
|
||||
e_ssl3.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
cipher_test
|
||||
cipher_test
|
||||
|
||||
cipher_test.c
|
||||
cipher_test.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
aead_test
|
||||
aead_test
|
||||
|
||||
aead_test.c
|
||||
aead_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(cipher_test crypto)
|
||||
|
||||
+125
-48
@@ -18,7 +18,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* This program tests an AEAD against a series of test vectors from a file. The
|
||||
* test vector file consists of key-value lines where the key and value are
|
||||
@@ -49,11 +51,14 @@ enum {
|
||||
CT, /* hex encoded ciphertext (not including the authenticator,
|
||||
which is next). */
|
||||
TAG, /* hex encoded authenticator. */
|
||||
NO_SEAL, /* non-zero length if seal(IN) is not expected to be CT+TAG,
|
||||
however open(CT+TAG) should still be IN. */
|
||||
FAILS, /* non-zero length if open(CT+TAG) is expected to fail. */
|
||||
NUM_TYPES,
|
||||
};
|
||||
|
||||
static const char NAMES[6][NUM_TYPES] = {
|
||||
"KEY", "NONCE", "IN", "AD", "CT", "TAG",
|
||||
static const char NAMES[8][NUM_TYPES] = {
|
||||
"KEY", "NONCE", "IN", "AD", "CT", "TAG", "NO_SEAL", "FAILS",
|
||||
};
|
||||
|
||||
static unsigned char hex_digit(char h) {
|
||||
@@ -69,12 +74,16 @@ static unsigned char hex_digit(char h) {
|
||||
}
|
||||
|
||||
static int run_test_case(const EVP_AEAD *aead,
|
||||
unsigned char bufs[NUM_TYPES][BUF_MAX],
|
||||
uint8_t bufs[NUM_TYPES][BUF_MAX],
|
||||
const unsigned int lengths[NUM_TYPES],
|
||||
unsigned int line_no) {
|
||||
EVP_AEAD_CTX ctx;
|
||||
size_t ciphertext_len, plaintext_len;
|
||||
unsigned char out[BUF_MAX + EVP_AEAD_MAX_OVERHEAD], out2[BUF_MAX];
|
||||
uint8_t out[BUF_MAX + EVP_AEAD_MAX_OVERHEAD + 1];
|
||||
/* Note: When calling |EVP_AEAD_CTX_open|, the "stateful" AEADs require
|
||||
* |max_out| be at least |in_len| despite the final output always being
|
||||
* smaller by at least tag length. */
|
||||
uint8_t out2[sizeof(out)];
|
||||
|
||||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG],
|
||||
NULL)) {
|
||||
@@ -82,27 +91,33 @@ static int run_test_case(const EVP_AEAD *aead,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_AEAD_CTX_seal(&ctx, out, &ciphertext_len, sizeof(out), bufs[NONCE],
|
||||
lengths[NONCE], bufs[IN], lengths[IN], bufs[AD],
|
||||
lengths[AD])) {
|
||||
fprintf(stderr, "Failed to run AEAD on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
if (!lengths[NO_SEAL]) {
|
||||
if (!EVP_AEAD_CTX_seal(&ctx, out, &ciphertext_len, sizeof(out), bufs[NONCE],
|
||||
lengths[NONCE], bufs[IN], lengths[IN], bufs[AD],
|
||||
lengths[AD])) {
|
||||
fprintf(stderr, "Failed to run AEAD on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ciphertext_len != lengths[CT] + lengths[TAG]) {
|
||||
fprintf(stderr, "Bad output length on line %u: %u vs %u\n", line_no,
|
||||
(unsigned)ciphertext_len, (unsigned)(lengths[CT] + lengths[TAG]));
|
||||
return 0;
|
||||
}
|
||||
if (ciphertext_len != lengths[CT] + lengths[TAG]) {
|
||||
fprintf(stderr, "Bad output length on line %u: %u vs %u\n", line_no,
|
||||
(unsigned)ciphertext_len, (unsigned)(lengths[CT] + lengths[TAG]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(out, bufs[CT], lengths[CT]) != 0) {
|
||||
fprintf(stderr, "Bad output on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
if (memcmp(out, bufs[CT], lengths[CT]) != 0) {
|
||||
fprintf(stderr, "Bad output on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(out + lengths[CT], bufs[TAG], lengths[TAG]) != 0) {
|
||||
fprintf(stderr, "Bad tag on line %u\n", line_no);
|
||||
return 0;
|
||||
if (memcmp(out + lengths[CT], bufs[TAG], lengths[TAG]) != 0) {
|
||||
fprintf(stderr, "Bad tag on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
memcpy(out, bufs[CT], lengths[CT]);
|
||||
memcpy(out + lengths[CT], bufs[TAG], lengths[TAG]);
|
||||
ciphertext_len = lengths[CT] + lengths[TAG];
|
||||
}
|
||||
|
||||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
|
||||
@@ -114,34 +129,64 @@ static int run_test_case(const EVP_AEAD *aead,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_AEAD_CTX_open(&ctx, out2, &plaintext_len, lengths[IN], bufs[NONCE],
|
||||
lengths[NONCE], out, ciphertext_len, bufs[AD],
|
||||
lengths[AD])) {
|
||||
fprintf(stderr, "Failed to decrypt on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
int ret = EVP_AEAD_CTX_open(&ctx, out2, &plaintext_len, sizeof(out2),
|
||||
bufs[NONCE], lengths[NONCE], out, ciphertext_len,
|
||||
bufs[AD], lengths[AD]);
|
||||
if (lengths[FAILS]) {
|
||||
if (ret) {
|
||||
fprintf(stderr, "Decrypted bad data on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
ERR_clear_error();
|
||||
} else {
|
||||
if (!ret) {
|
||||
fprintf(stderr, "Failed to decrypt on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (plaintext_len != lengths[IN]) {
|
||||
fprintf(stderr, "Bad decrypt on line %u: %u\n", line_no,
|
||||
(unsigned)ciphertext_len);
|
||||
return 0;
|
||||
}
|
||||
if (plaintext_len != lengths[IN]) {
|
||||
fprintf(stderr, "Bad decrypt on line %u: %u\n", line_no,
|
||||
(unsigned)ciphertext_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
|
||||
* reset after each operation. */
|
||||
EVP_AEAD_CTX_cleanup(&ctx);
|
||||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG],
|
||||
NULL)) {
|
||||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
|
||||
* reset after each operation. */
|
||||
EVP_AEAD_CTX_cleanup(&ctx);
|
||||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG],
|
||||
NULL)) {
|
||||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out[0] ^= 0x80;
|
||||
if (EVP_AEAD_CTX_open(&ctx, out2, &plaintext_len, lengths[IN], bufs[NONCE],
|
||||
lengths[NONCE], out, ciphertext_len, bufs[AD],
|
||||
lengths[AD])) {
|
||||
fprintf(stderr, "Decrypted bad data on line %u\n", line_no);
|
||||
return 0;
|
||||
/* Garbage at the end isn't ignored. */
|
||||
out[ciphertext_len] = 0;
|
||||
if (EVP_AEAD_CTX_open(&ctx, out2, &plaintext_len, sizeof(out2),
|
||||
bufs[NONCE], lengths[NONCE], out, ciphertext_len + 1,
|
||||
bufs[AD], lengths[AD])) {
|
||||
fprintf(stderr, "Decrypted bad data on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
|
||||
* reset after each operation. */
|
||||
EVP_AEAD_CTX_cleanup(&ctx);
|
||||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG],
|
||||
NULL)) {
|
||||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Verify integrity is checked. */
|
||||
out[0] ^= 0x80;
|
||||
if (EVP_AEAD_CTX_open(&ctx, out2, &plaintext_len, sizeof(out2), bufs[NONCE],
|
||||
lengths[NONCE], out, ciphertext_len, bufs[AD],
|
||||
lengths[AD])) {
|
||||
fprintf(stderr, "Decrypted bad data on line %u\n", line_no);
|
||||
return 0;
|
||||
}
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
EVP_AEAD_CTX_cleanup(&ctx);
|
||||
@@ -157,6 +202,7 @@ int main(int argc, char **argv) {
|
||||
unsigned int lengths[NUM_TYPES];
|
||||
|
||||
CRYPTO_library_init();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "%s <aead> <test file.txt>\n", argv[0]);
|
||||
@@ -169,8 +215,38 @@ int main(int argc, char **argv) {
|
||||
aead = EVP_aead_aes_256_gcm();
|
||||
} else if (strcmp(argv[1], "chacha20-poly1305") == 0) {
|
||||
aead = EVP_aead_chacha20_poly1305();
|
||||
} else if (strcmp(argv[1], "rc4-md5") == 0) {
|
||||
} else if (strcmp(argv[1], "rc4-md5-tls") == 0) {
|
||||
aead = EVP_aead_rc4_md5_tls();
|
||||
} else if (strcmp(argv[1], "rc4-sha1-tls") == 0) {
|
||||
aead = EVP_aead_rc4_sha1_tls();
|
||||
} else if (strcmp(argv[1], "aes-128-cbc-sha1-tls") == 0) {
|
||||
aead = EVP_aead_aes_128_cbc_sha1_tls();
|
||||
} else if (strcmp(argv[1], "aes-128-cbc-sha1-tls-implicit-iv") == 0) {
|
||||
aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv();
|
||||
} else if (strcmp(argv[1], "aes-128-cbc-sha256-tls") == 0) {
|
||||
aead = EVP_aead_aes_128_cbc_sha256_tls();
|
||||
} else if (strcmp(argv[1], "aes-256-cbc-sha1-tls") == 0) {
|
||||
aead = EVP_aead_aes_256_cbc_sha1_tls();
|
||||
} else if (strcmp(argv[1], "aes-256-cbc-sha1-tls-implicit-iv") == 0) {
|
||||
aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv();
|
||||
} else if (strcmp(argv[1], "aes-256-cbc-sha256-tls") == 0) {
|
||||
aead = EVP_aead_aes_256_cbc_sha256_tls();
|
||||
} else if (strcmp(argv[1], "aes-256-cbc-sha384-tls") == 0) {
|
||||
aead = EVP_aead_aes_256_cbc_sha384_tls();
|
||||
} else if (strcmp(argv[1], "des-ede3-cbc-sha1-tls") == 0) {
|
||||
aead = EVP_aead_des_ede3_cbc_sha1_tls();
|
||||
} else if (strcmp(argv[1], "des-ede3-cbc-sha1-tls-implicit-iv") == 0) {
|
||||
aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv();
|
||||
} else if (strcmp(argv[1], "rc4-md5-ssl3") == 0) {
|
||||
aead = EVP_aead_rc4_md5_ssl3();
|
||||
} else if (strcmp(argv[1], "rc4-sha1-ssl3") == 0) {
|
||||
aead = EVP_aead_rc4_sha1_ssl3();
|
||||
} else if (strcmp(argv[1], "aes-128-cbc-sha1-ssl3") == 0) {
|
||||
aead = EVP_aead_aes_128_cbc_sha1_ssl3();
|
||||
} else if (strcmp(argv[1], "aes-256-cbc-sha1-ssl3") == 0) {
|
||||
aead = EVP_aead_aes_256_cbc_sha1_ssl3();
|
||||
} else if (strcmp(argv[1], "des-ede3-cbc-sha1-ssl3") == 0) {
|
||||
aead = EVP_aead_des_ede3_cbc_sha1_ssl3();
|
||||
} else if (strcmp(argv[1], "aes-128-key-wrap") == 0) {
|
||||
aead = EVP_aead_aes_128_key_wrap();
|
||||
} else if (strcmp(argv[1], "aes-256-key-wrap") == 0) {
|
||||
@@ -218,6 +294,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (any_values_set) {
|
||||
if (!run_test_case(aead, bufs, lengths, line_no)) {
|
||||
BIO_print_errors_fp(stderr);
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/* Copyright (c) 2014, 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/err.h>
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
|
||||
const ERR_STRING_DATA CIPHER_error_string_data[] = {
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_AEAD_CTX_init, 0), "EVP_AEAD_CTX_init"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_AEAD_CTX_open, 0), "EVP_AEAD_CTX_open"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_AEAD_CTX_seal, 0), "EVP_AEAD_CTX_seal"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_CIPHER_CTX_copy, 0), "EVP_CIPHER_CTX_copy"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_CIPHER_CTX_ctrl, 0), "EVP_CIPHER_CTX_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_CIPHER_CTX_set_key_length, 0), "EVP_CIPHER_CTX_set_key_length"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_CipherInit_ex, 0), "EVP_CipherInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_DecryptFinal_ex, 0), "EVP_DecryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_EVP_EncryptFinal_ex, 0), "EVP_EncryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_gcm_init, 0), "aead_aes_gcm_init"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_gcm_open, 0), "aead_aes_gcm_open"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_gcm_seal, 0), "aead_aes_gcm_seal"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_key_wrap_init, 0), "aead_aes_key_wrap_init"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_key_wrap_open, 0), "aead_aes_key_wrap_open"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_aes_key_wrap_seal, 0), "aead_aes_key_wrap_seal"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_chacha20_poly1305_init, 0), "aead_chacha20_poly1305_init"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_chacha20_poly1305_open, 0), "aead_chacha20_poly1305_open"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_chacha20_poly1305_seal, 0), "aead_chacha20_poly1305_seal"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_rc4_md5_tls_init, 0), "aead_rc4_md5_tls_init"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_rc4_md5_tls_open, 0), "aead_rc4_md5_tls_open"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aead_rc4_md5_tls_seal, 0), "aead_rc4_md5_tls_seal"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aes_init_key, 0), "aes_init_key"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, CIPHER_F_aesni_init_key, 0), "aesni_init_key"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_AES_KEY_SETUP_FAILED), "AES_KEY_SETUP_FAILED"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_BAD_DECRYPT), "BAD_DECRYPT"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_BAD_KEY_LENGTH), "BAD_KEY_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_BUFFER_TOO_SMALL), "BUFFER_TOO_SMALL"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_CTRL_NOT_IMPLEMENTED), "CTRL_NOT_IMPLEMENTED"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED), "CTRL_OPERATION_NOT_IMPLEMENTED"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_INITIALIZATION_ERROR), "INITIALIZATION_ERROR"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_INPUT_NOT_INITIALIZED), "INPUT_NOT_INITIALIZED"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_INVALID_AD), "INVALID_AD"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_INVALID_AD_SIZE), "INVALID_AD_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_INVALID_KEY_LENGTH), "INVALID_KEY_LENGTH"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_IV_TOO_LARGE), "IV_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_NO_CIPHER_SET), "NO_CIPHER_SET"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_OUTPUT_ALIASES_INPUT), "OUTPUT_ALIASES_INPUT"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_TAG_TOO_LARGE), "TAG_TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_TOO_LARGE), "TOO_LARGE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_UNSUPPORTED_AD_SIZE), "UNSUPPORTED_AD_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_UNSUPPORTED_INPUT_SIZE), "UNSUPPORTED_INPUT_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_UNSUPPORTED_KEY_SIZE), "UNSUPPORTED_KEY_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_UNSUPPORTED_NONCE_SIZE), "UNSUPPORTED_NONCE_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_UNSUPPORTED_TAG_SIZE), "UNSUPPORTED_TAG_SIZE"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_WRAP_MODE_NOT_ALLOWED), "WRAP_MODE_NOT_ALLOWED"},
|
||||
{ERR_PACK(ERR_LIB_CIPHER, 0, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH), "WRONG_FINAL_BLOCK_LENGTH"},
|
||||
{0, NULL},
|
||||
};
|
||||
@@ -55,6 +55,7 @@
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/cipher.h>
|
||||
@@ -67,8 +68,9 @@ static void hexdump(FILE *f, const char *title, const uint8_t *s, int l) {
|
||||
|
||||
fprintf(f, "%s", title);
|
||||
for (; n < l; ++n) {
|
||||
if ((n % 16) == 0)
|
||||
if ((n % 16) == 0) {
|
||||
fprintf(f, "\n%04x", n);
|
||||
}
|
||||
fprintf(f, " %02x", s[n]);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
@@ -387,8 +389,9 @@ int main(int argc, char **argv) {
|
||||
if (p[-1] == '\n') {
|
||||
encdec = -1;
|
||||
p[-1] = '\0';
|
||||
} else
|
||||
} else {
|
||||
encdec = atoi(sstrsep(&p, "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
kn = convert(key);
|
||||
|
||||
+98
-15
@@ -46,6 +46,8 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ==================================================================== */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/cipher.h>
|
||||
@@ -59,6 +61,10 @@
|
||||
#include "internal.h"
|
||||
#include "../modes/internal.h"
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
#include "../arm_arch.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
@@ -103,14 +109,33 @@ static char bsaes_capable(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
|
||||
#elif !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
|
||||
#include "../arm_arch.h"
|
||||
#if __ARM_ARCH__ >= 7
|
||||
|
||||
#if defined(OPENSSL_ARM) && __ARM_ARCH__ >= 7
|
||||
#define BSAES
|
||||
static char bsaes_capable(void) {
|
||||
return CRYPTO_is_NEON_capable();
|
||||
}
|
||||
#endif /* __ARM_ARCH__ >= 7 */
|
||||
#endif
|
||||
|
||||
#define HWAES
|
||||
static char hwaes_capable(void) {
|
||||
return (OPENSSL_armcap_P & ARMV8_AES) != 0;
|
||||
}
|
||||
|
||||
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
|
||||
AES_KEY *key);
|
||||
int aes_v8_set_decrypt_key(const uint8_t *user_key, const int bits,
|
||||
AES_KEY *key);
|
||||
void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, const int enc);
|
||||
void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, const uint8_t ivec[16]);
|
||||
|
||||
#endif /* OPENSSL_ARM */
|
||||
|
||||
#if defined(BSAES)
|
||||
@@ -174,6 +199,41 @@ void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HWAES)
|
||||
/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
|
||||
* functions. */
|
||||
int hwaes_capable(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, int enc) {
|
||||
abort();
|
||||
}
|
||||
|
||||
void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, const uint8_t ivec[16]) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
|
||||
@@ -227,7 +287,14 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
|
||||
mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK;
|
||||
if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
|
||||
if (bsaes_capable() && mode == EVP_CIPH_CBC_MODE) {
|
||||
if (hwaes_capable()) {
|
||||
ret = aes_v8_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
|
||||
dat->block = (block128_f)aes_v8_decrypt;
|
||||
dat->stream.cbc = NULL;
|
||||
if (mode == EVP_CIPH_CBC_MODE) {
|
||||
dat->stream.cbc = (cbc128_f)aes_v8_cbc_encrypt;
|
||||
}
|
||||
} else if (bsaes_capable() && mode == EVP_CIPH_CBC_MODE) {
|
||||
ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
|
||||
dat->block = (block128_f)AES_decrypt;
|
||||
dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
|
||||
@@ -242,6 +309,15 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
dat->stream.cbc =
|
||||
mode == EVP_CIPH_CBC_MODE ? (cbc128_f)AES_cbc_encrypt : NULL;
|
||||
}
|
||||
} else if (hwaes_capable()) {
|
||||
ret = aes_v8_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
|
||||
dat->block = (block128_f)aes_v8_encrypt;
|
||||
dat->stream.cbc = NULL;
|
||||
if (mode == EVP_CIPH_CBC_MODE) {
|
||||
dat->stream.cbc = (cbc128_f)aes_v8_cbc_encrypt;
|
||||
} else if (mode == EVP_CIPH_CTR_MODE) {
|
||||
dat->stream.ctr = (ctr128_f)aes_v8_ctr32_encrypt_blocks;
|
||||
}
|
||||
} else if (bsaes_capable() && mode == EVP_CIPH_CTR_MODE) {
|
||||
ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
|
||||
dat->block = (block128_f)AES_encrypt;
|
||||
@@ -316,6 +392,12 @@ static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
|
||||
static ctr128_f aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
|
||||
const uint8_t *key, size_t key_len) {
|
||||
if (hwaes_capable()) {
|
||||
aes_v8_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_v8_encrypt);
|
||||
return (ctr128_f)aes_v8_ctr32_encrypt_blocks;
|
||||
}
|
||||
|
||||
if (bsaes_capable()) {
|
||||
AES_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
|
||||
@@ -448,8 +530,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
|
||||
if (arg) {
|
||||
memcpy(gctx->iv, ptr, arg);
|
||||
}
|
||||
if (c->encrypt &&
|
||||
RAND_pseudo_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) {
|
||||
if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) {
|
||||
return 0;
|
||||
}
|
||||
gctx->iv_gen = 1;
|
||||
@@ -627,25 +708,25 @@ static const EVP_CIPHER aes_128_gcm = {
|
||||
|
||||
|
||||
static const EVP_CIPHER aes_256_cbc = {
|
||||
NID_aes_128_cbc, 16 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_cbc, 16 /* block_size */, 32 /* key_size */,
|
||||
16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
|
||||
NULL /* app_data */, aes_init_key, aes_cbc_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
|
||||
static const EVP_CIPHER aes_256_ctr = {
|
||||
NID_aes_128_ctr, 1 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_ctr, 1 /* block_size */, 32 /* key_size */,
|
||||
16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
|
||||
NULL /* app_data */, aes_init_key, aes_ctr_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
|
||||
static const EVP_CIPHER aes_256_ecb = {
|
||||
NID_aes_128_ecb, 16 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_ecb, 16 /* block_size */, 32 /* key_size */,
|
||||
0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
|
||||
NULL /* app_data */, aes_init_key, aes_ecb_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
|
||||
static const EVP_CIPHER aes_256_gcm = {
|
||||
NID_aes_128_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
|
||||
NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
|
||||
sizeof(EVP_AES_GCM_CTX),
|
||||
EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
|
||||
@@ -775,19 +856,19 @@ static const EVP_CIPHER aesni_128_gcm = {
|
||||
|
||||
|
||||
static const EVP_CIPHER aesni_256_cbc = {
|
||||
NID_aes_128_cbc, 16 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_cbc, 16 /* block_size */, 32 /* key_size */,
|
||||
16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
|
||||
NULL /* app_data */, aesni_init_key, aesni_cbc_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
|
||||
static const EVP_CIPHER aesni_256_ctr = {
|
||||
NID_aes_128_ctr, 1 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_ctr, 1 /* block_size */, 32 /* key_size */,
|
||||
16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
|
||||
NULL /* app_data */, aesni_init_key, aes_ctr_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
|
||||
static const EVP_CIPHER aesni_256_ecb = {
|
||||
NID_aes_128_ecb, 16 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_ecb, 16 /* block_size */, 32 /* key_size */,
|
||||
0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
|
||||
NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
|
||||
NULL /* cleanup */, NULL /* ctrl */};
|
||||
@@ -1103,7 +1184,7 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
|
||||
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
|
||||
* conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
|
||||
* a comparision is always true. */
|
||||
* a comparison is always true. */
|
||||
if (in_len > 0xfffffff0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
@@ -1198,7 +1279,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
|
||||
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
|
||||
* conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
|
||||
* a comparision is always true. */
|
||||
* a comparison is always true. */
|
||||
if (in_len > 0xfffffff8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
@@ -1275,6 +1356,8 @@ const EVP_AEAD *EVP_aead_aes_256_key_wrap(void) { return &aead_aes_256_key_wrap;
|
||||
int EVP_has_aes_hardware(void) {
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
return aesni_capable() && crypto_gcm_clmul_enabled();
|
||||
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
return hwaes_capable() && (OPENSSL_armcap_P & ARMV8_PMULL);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <openssl/aead.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/chacha.h>
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -81,7 +83,7 @@ static void poly1305_update_with_length(poly1305_state *poly1305,
|
||||
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
|
||||
}
|
||||
|
||||
#if __arm__
|
||||
#if defined(__arm__)
|
||||
#define ALIGNED __attribute__((aligned(16)))
|
||||
#else
|
||||
#define ALIGNED
|
||||
@@ -134,15 +136,9 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
|
||||
poly1305_update_with_length(&poly1305, out, in_len);
|
||||
|
||||
if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
|
||||
uint8_t tag[POLY1305_TAG_LEN];
|
||||
CRYPTO_poly1305_finish(&poly1305, tag);
|
||||
memcpy(out + in_len, tag, c20_ctx->tag_len);
|
||||
*out_len = in_len + c20_ctx->tag_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
CRYPTO_poly1305_finish(&poly1305, out + in_len);
|
||||
uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
|
||||
CRYPTO_poly1305_finish(&poly1305, tag);
|
||||
memcpy(out + in_len, tag, c20_ctx->tag_len);
|
||||
*out_len = in_len + c20_ctx->tag_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/obj.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -279,7 +279,6 @@ static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
l2c(xor0, iv);
|
||||
l2c(xor1, iv);
|
||||
}
|
||||
tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
|
||||
tin[0] = tin[1] = 0;
|
||||
}
|
||||
|
||||
@@ -416,6 +415,6 @@ static const EVP_CIPHER rc2_40_cbc_cipher = {
|
||||
rc2_ctrl,
|
||||
};
|
||||
|
||||
const EVP_CIPHER *EVP_rc2_40_cbc() {
|
||||
const EVP_CIPHER *EVP_rc2_40_cbc(void) {
|
||||
return &rc2_40_cbc_cipher;
|
||||
}
|
||||
|
||||
+17
-2
@@ -57,8 +57,10 @@
|
||||
#include <openssl/aead.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/mem.h>
|
||||
@@ -176,7 +178,6 @@ static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
MD5_CTX md;
|
||||
#if defined(STITCHED_CALL)
|
||||
size_t rc4_off, md5_off, blocks;
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
#else
|
||||
const size_t rc4_off = 0;
|
||||
const size_t md5_off = 0;
|
||||
@@ -208,6 +209,13 @@ static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
|
||||
MD5_Update(&md, ad, ad_len);
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(in_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(in_len & 0xff);
|
||||
MD5_Update(&md, ad_extra, sizeof(ad_extra));
|
||||
|
||||
#if defined(STITCHED_CALL)
|
||||
/* 32 is $MOD from rc4_md5-x86_64.pl. */
|
||||
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
|
||||
@@ -287,7 +295,7 @@ static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
plaintext_len = in_len - rc4_ctx->tag_len;
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -301,6 +309,13 @@ static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
|
||||
MD5_Update(&md, ad, ad_len);
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(plaintext_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(plaintext_len & 0xff);
|
||||
MD5_Update(&md, ad_extra, sizeof(ad_extra));
|
||||
|
||||
#if defined(STITCHED_CALL)
|
||||
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
|
||||
md5_off = MD5_CBLOCK - md.num;
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
/* Copyright (c) 2014, 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 <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
EVP_CIPHER_CTX cipher_ctx;
|
||||
EVP_MD_CTX md_ctx;
|
||||
/* enc_key is the portion of the key used for the stream or block cipher. It
|
||||
* is retained separately to allow the EVP_CIPHER_CTX to be initialized once
|
||||
* the direction is known. */
|
||||
uint8_t enc_key[EVP_MAX_KEY_LENGTH];
|
||||
uint8_t enc_key_len;
|
||||
/* iv is the portion of the key used for the fixed IV. It is retained
|
||||
* separately to allow the EVP_CIPHER_CTX to be initialized once the direction
|
||||
* is known. */
|
||||
uint8_t iv[EVP_MAX_IV_LENGTH];
|
||||
uint8_t iv_len;
|
||||
char initialized;
|
||||
} AEAD_SSL3_CTX;
|
||||
|
||||
static int ssl3_mac(AEAD_SSL3_CTX *ssl3_ctx, uint8_t *out, unsigned *out_len,
|
||||
const uint8_t *ad, size_t ad_len, const uint8_t *in,
|
||||
size_t in_len) {
|
||||
size_t md_size = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
|
||||
size_t pad_len = (md_size == 20) ? 40 : 48;
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(in_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(in_len & 0xff);
|
||||
|
||||
EVP_MD_CTX md_ctx;
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
|
||||
uint8_t pad[48];
|
||||
uint8_t tmp[EVP_MAX_MD_SIZE];
|
||||
memset(pad, 0x36, pad_len);
|
||||
if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) ||
|
||||
!EVP_DigestUpdate(&md_ctx, pad, pad_len) ||
|
||||
!EVP_DigestUpdate(&md_ctx, ad, ad_len) ||
|
||||
!EVP_DigestUpdate(&md_ctx, ad_extra, sizeof(ad_extra)) ||
|
||||
!EVP_DigestUpdate(&md_ctx, in, in_len) ||
|
||||
!EVP_DigestFinal_ex(&md_ctx, tmp, NULL)) {
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(pad, 0x5c, pad_len);
|
||||
if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) ||
|
||||
!EVP_DigestUpdate(&md_ctx, pad, pad_len) ||
|
||||
!EVP_DigestUpdate(&md_ctx, tmp, md_size) ||
|
||||
!EVP_DigestFinal_ex(&md_ctx, out, out_len)) {
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aead_ssl3_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
|
||||
EVP_CIPHER_CTX_cleanup(&ssl3_ctx->cipher_ctx);
|
||||
EVP_MD_CTX_cleanup(&ssl3_ctx->md_ctx);
|
||||
OPENSSL_cleanse(&ssl3_ctx->enc_key, sizeof(ssl3_ctx->enc_key));
|
||||
OPENSSL_cleanse(&ssl3_ctx->iv, sizeof(ssl3_ctx->iv));
|
||||
OPENSSL_free(ssl3_ctx);
|
||||
ctx->aead_state = NULL;
|
||||
}
|
||||
|
||||
static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
|
||||
size_t tag_len, const EVP_CIPHER *cipher,
|
||||
const EVP_MD *md) {
|
||||
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
|
||||
tag_len != EVP_MD_size(md)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t mac_key_len = EVP_MD_size(md);
|
||||
size_t enc_key_len = EVP_CIPHER_key_length(cipher);
|
||||
size_t iv_len = EVP_CIPHER_iv_length(cipher);
|
||||
assert(mac_key_len + enc_key_len + iv_len == key_len);
|
||||
assert(mac_key_len < 256);
|
||||
assert(enc_key_len < 256);
|
||||
assert(iv_len < 256);
|
||||
/* Although EVP_rc4() is a variable-length cipher, the default key size is
|
||||
* correct for SSL3. */
|
||||
|
||||
AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX));
|
||||
if (ssl3_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx);
|
||||
EVP_MD_CTX_init(&ssl3_ctx->md_ctx);
|
||||
memcpy(ssl3_ctx->enc_key, &key[mac_key_len], enc_key_len);
|
||||
ssl3_ctx->enc_key_len = (uint8_t)enc_key_len;
|
||||
memcpy(ssl3_ctx->iv, &key[mac_key_len + enc_key_len], iv_len);
|
||||
ssl3_ctx->iv_len = (uint8_t)iv_len;
|
||||
ssl3_ctx->initialized = 0;
|
||||
|
||||
ctx->aead_state = ssl3_ctx;
|
||||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, NULL, NULL, 0) ||
|
||||
!EVP_DigestInit_ex(&ssl3_ctx->md_ctx, md, NULL) ||
|
||||
!EVP_DigestUpdate(&ssl3_ctx->md_ctx, key, mac_key_len)) {
|
||||
aead_ssl3_cleanup(ctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_CIPHER_CTX_set_padding(&ssl3_ctx->cipher_ctx, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* aead_ssl3_ensure_cipher_init initializes |ssl3_ctx| for encryption (or
|
||||
* decryption, if |encrypt| is zero). If it has already been initialized, it
|
||||
* ensures the direction matches and fails otherwise. It returns one on success
|
||||
* and zero on failure.
|
||||
*
|
||||
* Note that, unlike normal AEADs, legacy SSL3 AEADs may not be used concurrently
|
||||
* due to this (and bulk-cipher-internal) statefulness. */
|
||||
static int aead_ssl3_ensure_cipher_init(AEAD_SSL3_CTX *ssl3_ctx, int encrypt) {
|
||||
if (!ssl3_ctx->initialized) {
|
||||
/* Finish initializing the EVP_CIPHER_CTX now that the direction is
|
||||
* known. */
|
||||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, NULL, NULL, ssl3_ctx->enc_key,
|
||||
ssl3_ctx->iv, encrypt)) {
|
||||
return 0;
|
||||
}
|
||||
ssl3_ctx->initialized = 1;
|
||||
} else if (ssl3_ctx->cipher_ctx.encrypt != encrypt) {
|
||||
/* Unlike a normal AEAD, using an SSL3 AEAD once freezes the direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_ensure_cipher_init,
|
||||
CIPHER_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
|
||||
size_t total = 0;
|
||||
|
||||
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
|
||||
in_len > INT_MAX) {
|
||||
/* EVP_CIPHER takes int as input. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_IV_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ad_len != 11 - 2 /* length bytes */) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!aead_ssl3_ensure_cipher_init(ssl3_ctx, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute the MAC. This must be first in case the operation is being done
|
||||
* in-place. */
|
||||
uint8_t mac[EVP_MAX_MD_SIZE];
|
||||
unsigned mac_len;
|
||||
if (!ssl3_mac(ssl3_ctx, mac, &mac_len, ad, ad_len, in, in_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encrypt the input. */
|
||||
int len;
|
||||
if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in,
|
||||
(int)in_len)) {
|
||||
return 0;
|
||||
}
|
||||
total = len;
|
||||
|
||||
/* Feed the MAC into the cipher. */
|
||||
if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out + total, &len, mac,
|
||||
(int)mac_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
|
||||
unsigned block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx);
|
||||
if (block_size > 1) {
|
||||
assert(block_size <= 256);
|
||||
assert(EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
|
||||
|
||||
/* Compute padding and feed that into the cipher. */
|
||||
uint8_t padding[256];
|
||||
unsigned padding_len = block_size - ((in_len + mac_len) % block_size);
|
||||
memset(padding, 0, padding_len - 1);
|
||||
padding[padding_len - 1] = padding_len - 1;
|
||||
if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out + total, &len, padding,
|
||||
(int)padding_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
if (!EVP_EncryptFinal_ex(&ssl3_ctx->cipher_ctx, out + total, &len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
|
||||
*out_len = total;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
|
||||
|
||||
size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
|
||||
if (in_len < mac_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len) {
|
||||
/* This requires that the caller provide space for the MAC, even though it
|
||||
* will always be removed on return. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ad_len != 11 - 2 /* length bytes */) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len > INT_MAX) {
|
||||
/* EVP_CIPHER takes int as input. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!aead_ssl3_ensure_cipher_init(ssl3_ctx, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decrypt to get the plaintext + MAC + padding. */
|
||||
size_t total = 0;
|
||||
int len;
|
||||
if (!EVP_DecryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, (int)in_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
if (!EVP_DecryptFinal_ex(&ssl3_ctx->cipher_ctx, out + total, &len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
assert(total == in_len);
|
||||
|
||||
/* Remove CBC padding and MAC. This would normally be timing-sensitive, but SSLv3 CBC
|
||||
* ciphers are already broken. Support will be removed eventually.
|
||||
* https://www.openssl.org/~bodo/ssl-poodle.pdf */
|
||||
unsigned data_len;
|
||||
if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
|
||||
unsigned padding_length = out[total - 1];
|
||||
if (total < padding_length + 1 + mac_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
/* The padding must be minimal. */
|
||||
if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
data_len = total - padding_length - 1 - mac_len;
|
||||
} else {
|
||||
data_len = total - mac_len;
|
||||
}
|
||||
|
||||
/* Compute the MAC and compare against the one in the record. */
|
||||
uint8_t mac[EVP_MAX_MD_SIZE];
|
||||
if (!ssl3_mac(ssl3_ctx, mac, NULL, ad, ad_len, out, data_len)) {
|
||||
return 0;
|
||||
}
|
||||
if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_len = data_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_md5_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_md5());
|
||||
}
|
||||
|
||||
static int aead_rc4_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_sha1());
|
||||
}
|
||||
|
||||
static int aead_aes_128_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(),
|
||||
EVP_sha1());
|
||||
}
|
||||
|
||||
static int aead_aes_256_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(),
|
||||
EVP_sha1());
|
||||
}
|
||||
static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(),
|
||||
EVP_sha1());
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_rc4_md5_ssl3 = {
|
||||
MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
|
||||
0, /* nonce len */
|
||||
MD5_DIGEST_LENGTH, /* overhead */
|
||||
MD5_DIGEST_LENGTH, /* max tag length */
|
||||
aead_rc4_md5_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_rc4_sha1_ssl3 = {
|
||||
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
|
||||
0, /* nonce len */
|
||||
SHA_DIGEST_LENGTH, /* overhead */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_rc4_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = {
|
||||
SHA_DIGEST_LENGTH + 16 + 16, /* key len (SHA1 + AES128 + IV) */
|
||||
0, /* nonce len */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_128_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = {
|
||||
SHA_DIGEST_LENGTH + 32 + 16, /* key len (SHA1 + AES256 + IV) */
|
||||
0, /* nonce len */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_256_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
|
||||
SHA_DIGEST_LENGTH + 24 + 8, /* key len (SHA1 + 3DES + IV) */
|
||||
0, /* nonce len */
|
||||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_des_ede3_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void) { return &aead_rc4_md5_ssl3; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void) { return &aead_rc4_sha1_ssl3; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void) {
|
||||
return &aead_aes_128_cbc_sha1_ssl3;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) {
|
||||
return &aead_aes_256_cbc_sha1_ssl3;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) {
|
||||
return &aead_des_ede3_cbc_sha1_ssl3;
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
/* Copyright (c) 2014, 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 <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../crypto/internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
EVP_CIPHER_CTX cipher_ctx;
|
||||
HMAC_CTX hmac_ctx;
|
||||
/* mac_key is the portion of the key used for the MAC. It is retained
|
||||
* separately for the constant-time CBC code. */
|
||||
uint8_t mac_key[EVP_MAX_MD_SIZE];
|
||||
uint8_t mac_key_len;
|
||||
/* enc_key is the portion of the key used for the stream or block
|
||||
* cipher. It is retained separately to allow the EVP_CIPHER_CTX to be
|
||||
* initialized once the direction is known. */
|
||||
uint8_t enc_key[EVP_MAX_KEY_LENGTH];
|
||||
uint8_t enc_key_len;
|
||||
/* iv is the portion of the key used for the fixed IV. It is retained
|
||||
* separately to allow the EVP_CIPHER_CTX to be initialized once the direction
|
||||
* is known. */
|
||||
uint8_t iv[EVP_MAX_IV_LENGTH];
|
||||
uint8_t iv_len;
|
||||
/* implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit
|
||||
* IV. */
|
||||
char implicit_iv;
|
||||
char initialized;
|
||||
} AEAD_TLS_CTX;
|
||||
|
||||
|
||||
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_cleanse(&tls_ctx->enc_key, sizeof(tls_ctx->enc_key));
|
||||
OPENSSL_cleanse(&tls_ctx->iv, sizeof(tls_ctx->iv));
|
||||
OPENSSL_free(tls_ctx);
|
||||
ctx->aead_state = NULL;
|
||||
}
|
||||
|
||||
static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
|
||||
size_t tag_len, const EVP_CIPHER *cipher,
|
||||
const EVP_MD *md, char implicit_iv) {
|
||||
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
|
||||
tag_len != EVP_MD_size(md)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t mac_key_len = EVP_MD_size(md);
|
||||
size_t enc_key_len = EVP_CIPHER_key_length(cipher);
|
||||
size_t iv_len = implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0;
|
||||
assert(mac_key_len + enc_key_len + iv_len == key_len);
|
||||
assert(mac_key_len < 256);
|
||||
assert(enc_key_len < 256);
|
||||
assert(iv_len < 256);
|
||||
/* Although EVP_rc4() is a variable-length cipher, the default key size is
|
||||
* correct for TLS. */
|
||||
|
||||
AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX));
|
||||
if (tls_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
|
||||
HMAC_CTX_init(&tls_ctx->hmac_ctx);
|
||||
memcpy(tls_ctx->mac_key, key, mac_key_len);
|
||||
tls_ctx->mac_key_len = (uint8_t)mac_key_len;
|
||||
memcpy(tls_ctx->enc_key, &key[mac_key_len], enc_key_len);
|
||||
tls_ctx->enc_key_len = (uint8_t)enc_key_len;
|
||||
memcpy(tls_ctx->iv, &key[mac_key_len + enc_key_len], iv_len);
|
||||
tls_ctx->iv_len = (uint8_t)iv_len;
|
||||
tls_ctx->implicit_iv = implicit_iv;
|
||||
tls_ctx->initialized = 0;
|
||||
|
||||
ctx->aead_state = tls_ctx;
|
||||
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, NULL, NULL, 0) ||
|
||||
!HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) {
|
||||
aead_tls_cleanup(ctx);
|
||||
return 0;
|
||||
}
|
||||
EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* aead_tls_ensure_cipher_init initializes |tls_ctx| for encryption (or
|
||||
* decryption, if |encrypt| is zero). If it has already been initialized, it
|
||||
* ensures the direction matches and fails otherwise. It returns one on success
|
||||
* and zero on failure.
|
||||
*
|
||||
* Note that, unlike normal AEADs, legacy TLS AEADs may not be used concurrently
|
||||
* due to this (and bulk-cipher-internal) statefulness. */
|
||||
static int aead_tls_ensure_cipher_init(AEAD_TLS_CTX *tls_ctx, int encrypt) {
|
||||
if (!tls_ctx->initialized) {
|
||||
/* Finish initializing the EVP_CIPHER_CTX now that the direction is
|
||||
* known. */
|
||||
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, tls_ctx->enc_key,
|
||||
tls_ctx->implicit_iv ? tls_ctx->iv : NULL,
|
||||
encrypt)) {
|
||||
return 0;
|
||||
}
|
||||
tls_ctx->initialized = 1;
|
||||
} else if (tls_ctx->cipher_ctx.encrypt != encrypt) {
|
||||
/* Unlike a normal AEAD, using a TLS AEAD once freezes the direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_ensure_cipher_init,
|
||||
CIPHER_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
|
||||
size_t total = 0;
|
||||
|
||||
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
|
||||
in_len > INT_MAX) {
|
||||
/* EVP_CIPHER takes int as input. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ad_len != 13 - 2 /* length bytes */) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!aead_tls_ensure_cipher_init(tls_ctx, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(in_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(in_len & 0xff);
|
||||
|
||||
/* Compute the MAC. This must be first in case the operation is being done
|
||||
* in-place. */
|
||||
uint8_t mac[EVP_MAX_MD_SIZE];
|
||||
unsigned mac_len;
|
||||
HMAC_CTX hmac_ctx;
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
|
||||
!HMAC_Update(&hmac_ctx, ad, ad_len) ||
|
||||
!HMAC_Update(&hmac_ctx, ad_extra, sizeof(ad_extra)) ||
|
||||
!HMAC_Update(&hmac_ctx, in, in_len) ||
|
||||
!HMAC_Final(&hmac_ctx, mac, &mac_len)) {
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
return 0;
|
||||
}
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
|
||||
/* Configure the explicit IV. */
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
|
||||
!tls_ctx->implicit_iv &&
|
||||
!EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encrypt the input. */
|
||||
int len;
|
||||
if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out, &len, in,
|
||||
(int)in_len)) {
|
||||
return 0;
|
||||
}
|
||||
total = len;
|
||||
|
||||
/* Feed the MAC into the cipher. */
|
||||
if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out + total, &len, mac,
|
||||
(int)mac_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
|
||||
unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
|
||||
if (block_size > 1) {
|
||||
assert(block_size <= 256);
|
||||
assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
|
||||
|
||||
/* Compute padding and feed that into the cipher. */
|
||||
uint8_t padding[256];
|
||||
unsigned padding_len = block_size - ((in_len + mac_len) % block_size);
|
||||
memset(padding, padding_len - 1, padding_len);
|
||||
if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out + total, &len, padding,
|
||||
(int)padding_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
|
||||
*out_len = total;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
|
||||
|
||||
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len) {
|
||||
/* This requires that the caller provide space for the MAC, even though it
|
||||
* will always be removed on return. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ad_len != 13 - 2 /* length bytes */) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len > INT_MAX) {
|
||||
/* EVP_CIPHER takes int as input. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!aead_tls_ensure_cipher_init(tls_ctx, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Configure the explicit IV. */
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
|
||||
!tls_ctx->implicit_iv &&
|
||||
!EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decrypt to get the plaintext + MAC + padding. */
|
||||
size_t total = 0;
|
||||
int len;
|
||||
if (!EVP_DecryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
if (!EVP_DecryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) {
|
||||
return 0;
|
||||
}
|
||||
total += len;
|
||||
assert(total == in_len);
|
||||
|
||||
/* Remove CBC padding. Code from here on is timing-sensitive with respect to
|
||||
* |padding_ok| and |data_plus_mac_len| for CBC ciphers. */
|
||||
int padding_ok;
|
||||
unsigned data_plus_mac_len, data_len;
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
|
||||
padding_ok = EVP_tls_cbc_remove_padding(
|
||||
&data_plus_mac_len, out, total,
|
||||
EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
|
||||
(unsigned)HMAC_size(&tls_ctx->hmac_ctx));
|
||||
/* Publicly invalid. This can be rejected in non-constant time. */
|
||||
if (padding_ok == 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
padding_ok = 1;
|
||||
data_plus_mac_len = total;
|
||||
/* |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has
|
||||
* already been checked against the MAC size at the top of the function. */
|
||||
assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx));
|
||||
}
|
||||
data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx);
|
||||
|
||||
/* At this point, |padding_ok| is 1 or -1. If 1, the padding is valid and the
|
||||
* first |data_plus_mac_size| bytes after |out| are the plaintext and
|
||||
* MAC. Either way, |data_plus_mac_size| is large enough to extract a MAC. */
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_fixed[13];
|
||||
memcpy(ad_fixed, ad, 11);
|
||||
ad_fixed[11] = (uint8_t)(data_len >> 8);
|
||||
ad_fixed[12] = (uint8_t)(data_len & 0xff);
|
||||
ad_len += 2;
|
||||
|
||||
/* Compute the MAC and extract the one in the record. */
|
||||
uint8_t mac[EVP_MAX_MD_SIZE];
|
||||
size_t mac_len;
|
||||
uint8_t record_mac_tmp[EVP_MAX_MD_SIZE];
|
||||
uint8_t *record_mac;
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
|
||||
EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) {
|
||||
if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len,
|
||||
ad_fixed, out, data_plus_mac_len, total,
|
||||
tls_ctx->mac_key, tls_ctx->mac_key_len)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
|
||||
|
||||
record_mac = record_mac_tmp;
|
||||
EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
|
||||
} else {
|
||||
/* We should support the constant-time path for all CBC-mode ciphers
|
||||
* implemented. */
|
||||
assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
|
||||
|
||||
HMAC_CTX hmac_ctx;
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
unsigned mac_len_u;
|
||||
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
|
||||
!HMAC_Update(&hmac_ctx, ad_fixed, ad_len) ||
|
||||
!HMAC_Update(&hmac_ctx, out, data_len) ||
|
||||
!HMAC_Final(&hmac_ctx, mac, &mac_len_u)) {
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
return 0;
|
||||
}
|
||||
mac_len = mac_len_u;
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
|
||||
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
|
||||
record_mac = &out[data_len];
|
||||
}
|
||||
|
||||
/* Perform the MAC check and the padding check in constant-time. It should be
|
||||
* safe to simply perform the padding check first, but it would not be under a
|
||||
* different choice of MAC location on padding failure. See
|
||||
* EVP_tls_cbc_remove_padding. */
|
||||
unsigned good = constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len),
|
||||
0);
|
||||
good &= constant_time_eq_int(padding_ok, 1);
|
||||
if (!good) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of timing-sensitive code. */
|
||||
|
||||
*out_len = data_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_sha1(), 0);
|
||||
}
|
||||
|
||||
static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(),
|
||||
EVP_sha1(), 0);
|
||||
}
|
||||
|
||||
static int aead_aes_128_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key,
|
||||
size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(),
|
||||
EVP_sha1(), 1);
|
||||
}
|
||||
|
||||
static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(),
|
||||
EVP_sha256(), 0);
|
||||
}
|
||||
|
||||
static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(),
|
||||
EVP_sha1(), 0);
|
||||
}
|
||||
|
||||
static int aead_aes_256_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key,
|
||||
size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(),
|
||||
EVP_sha1(), 1);
|
||||
}
|
||||
|
||||
static int aead_aes_256_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(),
|
||||
EVP_sha256(), 0);
|
||||
}
|
||||
|
||||
static int aead_aes_256_cbc_sha384_tls_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(),
|
||||
EVP_sha384(), 0);
|
||||
}
|
||||
|
||||
static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(),
|
||||
EVP_sha1(), 0);
|
||||
}
|
||||
|
||||
static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx,
|
||||
const uint8_t *key,
|
||||
size_t key_len,
|
||||
size_t tag_len) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(),
|
||||
EVP_sha1(), 1);
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_rc4_sha1_tls = {
|
||||
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
|
||||
0, /* nonce len */
|
||||
SHA_DIGEST_LENGTH, /* overhead */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_rc4_sha1_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
|
||||
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + AES128) */
|
||||
16, /* nonce len (IV) */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_128_cbc_sha1_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
|
||||
SHA_DIGEST_LENGTH + 16 + 16, /* key len (SHA1 + AES128 + IV) */
|
||||
0, /* nonce len */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_128_cbc_sha1_tls_implicit_iv_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
|
||||
SHA256_DIGEST_LENGTH + 16, /* key len (SHA256 + AES128) */
|
||||
16, /* nonce len (IV) */
|
||||
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_128_cbc_sha256_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
|
||||
SHA_DIGEST_LENGTH + 32, /* key len (SHA1 + AES256) */
|
||||
16, /* nonce len (IV) */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_256_cbc_sha1_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
|
||||
SHA_DIGEST_LENGTH + 32 + 16, /* key len (SHA1 + AES256 + IV) */
|
||||
0, /* nonce len */
|
||||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_256_cbc_sha1_tls_implicit_iv_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
|
||||
SHA256_DIGEST_LENGTH + 32, /* key len (SHA256 + AES256) */
|
||||
16, /* nonce len (IV) */
|
||||
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_256_cbc_sha256_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
|
||||
SHA384_DIGEST_LENGTH + 32, /* key len (SHA384 + AES256) */
|
||||
16, /* nonce len (IV) */
|
||||
16 + SHA384_DIGEST_LENGTH, /* overhead (padding + SHA384) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_aes_256_cbc_sha384_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
|
||||
SHA_DIGEST_LENGTH + 24, /* key len (SHA1 + 3DES) */
|
||||
8, /* nonce len (IV) */
|
||||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_des_ede3_cbc_sha1_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
|
||||
SHA_DIGEST_LENGTH + 24 + 8, /* key len (SHA1 + 3DES + IV) */
|
||||
0, /* nonce len */
|
||||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
aead_des_ede3_cbc_sha1_tls_implicit_iv_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
|
||||
return &aead_aes_128_cbc_sha1_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) {
|
||||
return &aead_aes_128_cbc_sha1_tls_implicit_iv;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) {
|
||||
return &aead_aes_128_cbc_sha256_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) {
|
||||
return &aead_aes_256_cbc_sha1_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void) {
|
||||
return &aead_aes_256_cbc_sha1_tls_implicit_iv;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void) {
|
||||
return &aead_aes_256_cbc_sha256_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void) {
|
||||
return &aead_aes_256_cbc_sha384_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) {
|
||||
return &aead_des_ede3_cbc_sha1_tls;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) {
|
||||
return &aead_des_ede3_cbc_sha1_tls_implicit_iv;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user