Compare commits
357 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f78fa1ea33 | |||
| 40acdaeb86 | |||
| 72f5911a16 | |||
| 4d78718cde | |||
| 89baa72ed8 | |||
| 0e434b9470 | |||
| c0f763b080 | |||
| e631d9679e | |||
| be55790652 | |||
| f8c2c9e9f0 | |||
| a1283f75f1 | |||
| 3db1ded2e7 | |||
| e8261a0100 | |||
| a5974bfae7 | |||
| e12c4378e9 | |||
| 5a3162a521 | |||
| f93d737c86 | |||
| 94e597a51c | |||
| c2b45a164a | |||
| 1d77e56b29 | |||
| 45fb1be33e | |||
| d7c5dfb233 | |||
| c11e13a78b | |||
| 20b64fd19d | |||
| 32ab7b0e74 | |||
| 3e719319be | |||
| e2e13265ff | |||
| 4616bb1e6e | |||
| 87ac295d5d | |||
| 05a5beb35c | |||
| 340d5ed295 | |||
| 0570923ed2 | |||
| 0d4db50a54 | |||
| e5a3ac2cac | |||
| 8056343a58 | |||
| b6d0c6db5e | |||
| 90fa69aaae | |||
| ab2479a08a | |||
| 32156b974d | |||
| 72dc7834af | |||
| 67d1fb59ad | |||
| 642f1498d0 | |||
| 7061e28dc2 | |||
| 3c9746a6d7 | |||
| b85a4c2923 | |||
| cdea40c3e2 | |||
| 4b1510c71e | |||
| 7a8e62dbd9 | |||
| 61c0d4e8b2 | |||
| c12d377e24 | |||
| 7e3b5840c2 | |||
| 078abceb29 | |||
| 8b368412d3 | |||
| 9e13e1a31d | |||
| cfdd6b1aef | |||
| 506fa4f770 | |||
| 42574efaff | |||
| cdcecf546b | |||
| a5a3eeb9cc | |||
| ced555394f | |||
| 34860739de | |||
| 859a04b7ff | |||
| a9c6667cab | |||
| e30f3fb080 | |||
| c02f148fa8 | |||
| 87b2a13a86 | |||
| 2ddba8cd48 | |||
| 3305858342 | |||
| f21645f4e3 | |||
| 067321502d | |||
| 1df63e93f9 | |||
| 0e782a9eb3 | |||
| 52f9f62283 | |||
| 5edc4e2a9b | |||
| ca8feeb301 | |||
| 7282738bad | |||
| 3f92d21094 | |||
| 524e717b87 | |||
| ab2a8e03d9 | |||
| d434f28ef2 | |||
| 1b3a95122d | |||
| 1d1562d9b5 | |||
| a42b4163f8 | |||
| d53b2c3c88 | |||
| 4df48dd30f | |||
| 949b26827a | |||
| 28120a18f6 | |||
| dc3da93899 | |||
| 4f7783eaea | |||
| 7cb0f44d9d | |||
| 165de16c2e | |||
| 1a5c50f3a8 | |||
| 7cc29ab833 | |||
| e0ba4dddf6 | |||
| bc5d8ee0d4 | |||
| e60202797d | |||
| 33c8d60a1f | |||
| b18f024816 | |||
| bcd374570c | |||
| bf0df92964 | |||
| 389939422a | |||
| 5a93342fab | |||
| c4482d65dc | |||
| f298019547 | |||
| 2fa83de3f2 | |||
| 4c31123bfc | |||
| f7f0f3a74b | |||
| ee562b987e | |||
| 8cb7a7c0d5 | |||
| 7538122ca6 | |||
| d03b5eddb9 | |||
| 8a4ab4fc1d | |||
| d216b71f90 | |||
| d27eda00a4 | |||
| f46cea8cd8 | |||
| a4e6d48749 | |||
| 7eaab4cd57 | |||
| 9d102ddbc0 | |||
| e023ad2d83 | |||
| 5f5bf6f210 | |||
| 0685b68216 | |||
| 5ca39fb50c | |||
| b34f510b3b | |||
| fb68d6c901 | |||
| 23721e3705 | |||
| cc239d3903 | |||
| 0d5e080ab9 | |||
| b826c0d670 | |||
| b3323704bc | |||
| 4e581b5378 | |||
| 50073e8c5e | |||
| 5ae21bc02b | |||
| 29b50eab6c | |||
| 114ddebbf6 | |||
| 9a7233cda8 | |||
| a3e894921e | |||
| 03741f61d9 | |||
| 09bdb2a2c3 | |||
| bcb2d91e10 | |||
| 6f5c0f4471 | |||
| 7c21925a10 | |||
| 3ce3c369cb | |||
| 87c8a643e1 | |||
| 6204eba91e | |||
| 2b48d6b7dd | |||
| 3f5917f320 | |||
| 86058a256b | |||
| 2bdb35ccbb | |||
| ce9f0177f8 | |||
| 04c36b5062 | |||
| 3f309aef45 | |||
| 44972944fd | |||
| 5f0efe06e1 | |||
| 93531bd70f | |||
| d3a73360fa | |||
| 97999919bb | |||
| bcc4e23041 | |||
| 40f101b78b | |||
| 16e38b2b8f | |||
| d3459fb2f9 | |||
| 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 |
@@ -2,3 +2,4 @@ build/
|
||||
ssl/test/runner/runner
|
||||
*.swp
|
||||
*.swo
|
||||
doc/*.html
|
||||
|
||||
@@ -1,33 +1,76 @@
|
||||
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. If not found by CMake, it may be configured
|
||||
explicitly by setting PERL_EXECUTABLE.
|
||||
|
||||
* 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. If not found by CMake, it may be
|
||||
configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
|
||||
|
||||
* 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. If not found by CMake, the go executable may be
|
||||
configured explicitly by setting GO_EXECUTABLE.
|
||||
|
||||
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.
|
||||
|
||||
[1] http://www.cmake.org/download/
|
||||
|
||||
[2] https://martine.github.io/ninja/
|
||||
|
||||
[3] https://www.python.org/downloads/
|
||||
|
||||
[4] http://yasm.tortall.net/
|
||||
|
||||
[5] https://golang.org/dl/
|
||||
|
||||
+94
-24
@@ -1,46 +1,116 @@
|
||||
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 -Wshadow -Werror -ggdb -std=c89")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wshadow -Werror -ggdb -std=c++0x")
|
||||
find_package(Perl REQUIRED)
|
||||
|
||||
find_program(GO_EXECUTABLE go)
|
||||
if (NOT GO_EXECUTABLE)
|
||||
message(FATAL_ERROR "Could not find Go")
|
||||
endif()
|
||||
|
||||
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)
|
||||
add_definitions(-DNOMINMAX)
|
||||
endif()
|
||||
|
||||
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.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")
|
||||
# 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.
|
||||
+128
-95
@@ -1,67 +1,88 @@
|
||||
include_directories(. ../include)
|
||||
|
||||
if(APPLE)
|
||||
set(PERLASM_STYLE macosx)
|
||||
set(ASM_EXT S)
|
||||
enable_language(ASM)
|
||||
if (${ARCH} STREQUAL "x86")
|
||||
set(PERLASM_FLAGS "-fPIC -DOPENSSL_IA32_SSE2")
|
||||
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 -DOPENSSL_IA32_SSE2")
|
||||
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)
|
||||
set(PERLASM_FLAGS "-DOPENSSL_IA32_SSE2")
|
||||
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_EXECUTABLE} ${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.
|
||||
@@ -114,67 +135,79 @@ 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
|
||||
thread_pthread.c
|
||||
thread_win.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:hkdf>
|
||||
$<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
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(crypto pthread)
|
||||
endif()
|
||||
|
||||
constant_time_test.c
|
||||
add_executable(
|
||||
constant_time_test
|
||||
|
||||
constant_time_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(constant_time_test crypto)
|
||||
|
||||
add_executable(
|
||||
thread_test
|
||||
|
||||
thread_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(thread_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)
|
||||
|
||||
+16
-34
@@ -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,
|
||||
@@ -1059,17 +1033,25 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
#endif /* ?FULL_UNROLL */
|
||||
/* apply last round and
|
||||
* map cipher state to byte array block: */
|
||||
s0 = (Td4[(t0 >> 24)] << 24) ^ (Td4[(t3 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t2 >> 8) & 0xff] << 8) ^ (Td4[(t1) & 0xff]) ^ rk[0];
|
||||
s0 = ((uint32_t)Td4[(t0 >> 24)] << 24) ^
|
||||
((uint32_t)Td4[(t3 >> 16) & 0xff] << 16) ^
|
||||
((uint32_t)Td4[(t2 >> 8) & 0xff] << 8) ^
|
||||
((uint32_t)Td4[(t1) & 0xff]) ^ rk[0];
|
||||
PUTU32(out, s0);
|
||||
s1 = (Td4[(t1 >> 24)] << 24) ^ (Td4[(t0 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t3 >> 8) & 0xff] << 8) ^ (Td4[(t2) & 0xff]) ^ rk[1];
|
||||
s1 = ((uint32_t)Td4[(t1 >> 24)] << 24) ^
|
||||
((uint32_t)Td4[(t0 >> 16) & 0xff] << 16) ^
|
||||
((uint32_t)Td4[(t3 >> 8) & 0xff] << 8) ^
|
||||
((uint32_t)Td4[(t2) & 0xff]) ^ rk[1];
|
||||
PUTU32(out + 4, s1);
|
||||
s2 = (Td4[(t2 >> 24)] << 24) ^ (Td4[(t1 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t0 >> 8) & 0xff] << 8) ^ (Td4[(t3) & 0xff]) ^ rk[2];
|
||||
s2 = ((uint32_t)Td4[(t2 >> 24)] << 24) ^
|
||||
((uint32_t)Td4[(t1 >> 16) & 0xff] << 16) ^
|
||||
((uint32_t)Td4[(t0 >> 8) & 0xff] << 8) ^
|
||||
((uint32_t)Td4[(t3) & 0xff]) ^ rk[2];
|
||||
PUTU32(out + 8, s2);
|
||||
s3 = (Td4[(t3 >> 24)] << 24) ^ (Td4[(t2 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t1 >> 8) & 0xff] << 8) ^ (Td4[(t0) & 0xff]) ^ rk[3];
|
||||
s3 = ((uint32_t)Td4[(t3 >> 24)] << 24) ^
|
||||
((uint32_t)Td4[(t2 >> 16) & 0xff] << 16) ^
|
||||
((uint32_t)Td4[(t1 >> 8) & 0xff] << 8) ^
|
||||
((uint32_t)Td4[(t0) & 0xff]) ^ rk[3];
|
||||
PUTU32(out + 12, s3);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
+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>
|
||||
|
||||
@@ -194,7 +194,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
|
||||
len-off);
|
||||
if (c.inf & 0x80)
|
||||
{
|
||||
unsigned long e;
|
||||
uint32_t e;
|
||||
|
||||
e=ERR_GET_REASON(ERR_peek_error());
|
||||
if (e != ASN1_R_TOO_LONG)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -125,6 +125,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
|
||||
case V_ASN1_NULL:
|
||||
result = 0; /* They do not have content. */
|
||||
break;
|
||||
case V_ASN1_BOOLEAN:
|
||||
result = a->value.boolean - b->value.boolean;
|
||||
break;
|
||||
case V_ASN1_INTEGER:
|
||||
case V_ASN1_NEG_INTEGER:
|
||||
case V_ASN1_ENUMERATED:
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/time_support.h>
|
||||
@@ -285,7 +287,7 @@ int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
|
||||
if (!OPENSSL_gmtime(&t, &ttm))
|
||||
return -2;
|
||||
|
||||
if (!OPENSSL_gmtime_diff(&day, &sec, &stm, &ttm))
|
||||
if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
|
||||
return -2;
|
||||
|
||||
if (day > 0)
|
||||
|
||||
@@ -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);
|
||||
|
||||
+20
-20
@@ -137,7 +137,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
#endif
|
||||
if (j & 0x80)
|
||||
{
|
||||
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
|
||||
if (BIO_puts(bp, "Error in encoding\n") <= 0)
|
||||
goto end;
|
||||
ret=0;
|
||||
goto end;
|
||||
@@ -165,7 +165,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
if (j & V_ASN1_CONSTRUCTED)
|
||||
{
|
||||
ep=p+len;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, "\n") <= 0) goto end;
|
||||
if (len > length)
|
||||
{
|
||||
BIO_printf(bp,
|
||||
@@ -196,7 +196,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
else if (xclass != 0)
|
||||
{
|
||||
p+=len;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, "\n") <= 0) goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,7 +210,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
(tag == V_ASN1_UTCTIME) ||
|
||||
(tag == V_ASN1_GENERALIZEDTIME))
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, ":") <= 0) goto end;
|
||||
if ((len > 0) &&
|
||||
BIO_write(bp,(const char *)p,(int)len)
|
||||
!= (int)len)
|
||||
@@ -221,12 +221,12 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
opp=op;
|
||||
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, ":") <= 0) goto end;
|
||||
i2a_ASN1_OBJECT(bp,o);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,":BAD OBJECT",11) <= 0)
|
||||
if (BIO_puts(bp, ":BAD OBJECT") <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
|
||||
if (ii < 0)
|
||||
{
|
||||
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
|
||||
if (BIO_puts(bp, "Bad boolean\n") <= 0)
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bp,":%d",ii);
|
||||
@@ -273,7 +273,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
if (printable)
|
||||
/* printable string */
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0)
|
||||
if (BIO_puts(bp, ":") <= 0)
|
||||
goto end;
|
||||
if (BIO_write(bp,(const char *)opp,
|
||||
os->length) <= 0)
|
||||
@@ -283,7 +283,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
/* not printable => print octet string
|
||||
* as hex dump */
|
||||
{
|
||||
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
|
||||
if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
|
||||
goto end;
|
||||
for (i=0; i<os->length; i++)
|
||||
{
|
||||
@@ -297,7 +297,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
{
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0)
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (!BIO_hexdump(bp, opp,
|
||||
@@ -323,9 +323,9 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, ":") <= 0) goto end;
|
||||
if (bs->type == V_ASN1_NEG_INTEGER)
|
||||
if (BIO_write(bp,"-",1) <= 0)
|
||||
if (BIO_puts(bp, "-") <= 0)
|
||||
goto end;
|
||||
for (i=0; i<bs->length; i++)
|
||||
{
|
||||
@@ -335,13 +335,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
}
|
||||
if (bs->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) <= 0)
|
||||
if (BIO_puts(bp, "00") <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,"BAD INTEGER",11) <= 0)
|
||||
if (BIO_puts(bp, "BAD INTEGER") <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_INTEGER_free(bs);
|
||||
@@ -355,9 +355,9 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, ":") <= 0) goto end;
|
||||
if (bs->type == V_ASN1_NEG_ENUMERATED)
|
||||
if (BIO_write(bp,"-",1) <= 0)
|
||||
if (BIO_puts(bp, "-") <= 0)
|
||||
goto end;
|
||||
for (i=0; i<bs->length; i++)
|
||||
{
|
||||
@@ -367,13 +367,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
}
|
||||
if (bs->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) <= 0)
|
||||
if (BIO_puts(bp, "00") <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
|
||||
if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_ENUMERATED_free(bs);
|
||||
@@ -382,7 +382,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
{
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0)
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (!BIO_hexdump(bp,p,
|
||||
@@ -394,7 +394,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
if (BIO_puts(bp, "\n") <= 0) goto end;
|
||||
}
|
||||
p+=len;
|
||||
if ((tag == V_ASN1_EOC) && (xclass == 0))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -170,6 +170,9 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
@@ -235,6 +238,9 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
|
||||
+39
-3
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -302,8 +304,19 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
|
||||
goto auxerr;
|
||||
|
||||
/* Allocate structure */
|
||||
if (!*pval && !ASN1_item_ex_new(pval, it))
|
||||
if (*pval)
|
||||
{
|
||||
/* Free up and zero CHOICE value if initialised */
|
||||
i = asn1_get_choice_selector(pval, it);
|
||||
if ((i >= 0) && (i < it->tcount))
|
||||
{
|
||||
tt = it->templates + i;
|
||||
pchptr = asn1_get_field_ptr(pval, tt);
|
||||
ASN1_template_free(pchptr, tt);
|
||||
asn1_set_choice_selector(pval, -1, it);
|
||||
}
|
||||
}
|
||||
else if (!ASN1_item_ex_new(pval, it))
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
@@ -392,6 +405,19 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
|
||||
goto auxerr;
|
||||
|
||||
/* Free up and zero any ADB found */
|
||||
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
|
||||
{
|
||||
if (tt->flags & ASN1_TFLG_ADB_MASK)
|
||||
{
|
||||
const ASN1_TEMPLATE *seqtt;
|
||||
ASN1_VALUE **pseqval;
|
||||
seqtt = asn1_do_adb(pval, tt, 1);
|
||||
pseqval = asn1_get_field_ptr(pval, seqtt);
|
||||
ASN1_template_free(pseqval, seqtt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get each field entry */
|
||||
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
|
||||
{
|
||||
@@ -835,6 +861,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;
|
||||
@@ -1181,7 +1217,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
|
||||
len = buf->length;
|
||||
if (!BUF_MEM_grow_clean(buf, len + plen))
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_PUT_ERROR(ASN1, collect_data, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(buf->data + len, *p, plen);
|
||||
|
||||
@@ -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
|
||||
@@ -326,14 +329,17 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
ASN1_STRING *str;
|
||||
int utype;
|
||||
|
||||
if (it && it->funcs)
|
||||
if (!it)
|
||||
return 0;
|
||||
|
||||
if (it->funcs)
|
||||
{
|
||||
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
|
||||
if (pf->prim_new)
|
||||
return pf->prim_new(pval, it);
|
||||
}
|
||||
|
||||
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
|
||||
if (it->itype == ASN1_ITYPE_MSTRING)
|
||||
utype = -1;
|
||||
else
|
||||
utype = it->utype;
|
||||
|
||||
@@ -229,6 +229,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
|
||||
if (!asn1_template_print_ctx(out, fld, indent,
|
||||
it->templates, pctx))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
/* fall thru */
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
@@ -309,6 +310,8 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
|
||||
{
|
||||
const ASN1_TEMPLATE *seqtt;
|
||||
seqtt = asn1_do_adb(fld, tt, 1);
|
||||
if (!seqtt)
|
||||
return 0;
|
||||
tmpfld = asn1_get_field_ptr(fld, seqtt);
|
||||
if (!asn1_template_print_ctx(out, tmpfld,
|
||||
indent + 2, seqtt, pctx))
|
||||
|
||||
+25
-40
@@ -61,53 +61,38 @@
|
||||
|
||||
/* Declarations for string types */
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_INTEGER);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER);
|
||||
#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
|
||||
IMPLEMENT_ASN1_TYPE(sname) \
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
|
||||
sname *sname##_new(void) \
|
||||
{ \
|
||||
return ASN1_STRING_type_new(V_##sname); \
|
||||
} \
|
||||
void sname##_free(sname *x) \
|
||||
{ \
|
||||
ASN1_STRING_free(x); \
|
||||
}
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING);
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING)
|
||||
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_NULL);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_OBJECT);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_T61STRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING);
|
||||
|
||||
IMPLEMENT_ASN1_TYPE(ASN1_ANY);
|
||||
|
||||
/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.cc
|
||||
)
|
||||
|
||||
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] =
|
||||
@@ -372,6 +373,10 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
|
||||
rv = 0;
|
||||
goto end;
|
||||
}
|
||||
if (eof > v) {
|
||||
rv = -1;
|
||||
goto end;
|
||||
}
|
||||
ret += (v - eof);
|
||||
} else {
|
||||
eof = 1;
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct TestVector {
|
||||
const char *decoded;
|
||||
const char *encoded;
|
||||
} TEST_VECTOR;
|
||||
};
|
||||
|
||||
/* Test vectors from RFC 4648. */
|
||||
static const TEST_VECTOR test_vectors[] = {
|
||||
// Test vectors from RFC 4648.
|
||||
static const TestVector kTestVectors[] = {
|
||||
{ "", "" },
|
||||
{ "f" , "Zg==" },
|
||||
{ "fo", "Zm8=" },
|
||||
@@ -36,95 +36,90 @@ static const TEST_VECTOR test_vectors[] = {
|
||||
{ "foobar", "Zm9vYmFy" },
|
||||
};
|
||||
|
||||
static const size_t kNumTests = sizeof(test_vectors) / sizeof(test_vectors[0]);
|
||||
static const size_t kNumTests = sizeof(kTestVectors) / sizeof(kTestVectors[0]);
|
||||
|
||||
static int test_encode(void) {
|
||||
uint8_t out[9];
|
||||
size_t i, len;
|
||||
|
||||
for (i = 0; i < kNumTests; i++) {
|
||||
const TEST_VECTOR *t = &test_vectors[i];
|
||||
len = EVP_EncodeBlock(out, (const uint8_t*)t->decoded, strlen(t->decoded));
|
||||
static bool TestEncode() {
|
||||
for (size_t i = 0; i < kNumTests; i++) {
|
||||
const TestVector *t = &kTestVectors[i];
|
||||
uint8_t out[9];
|
||||
size_t len = EVP_EncodeBlock(out, (const uint8_t*)t->decoded,
|
||||
strlen(t->decoded));
|
||||
if (len != strlen(t->encoded) ||
|
||||
memcmp(out, t->encoded, len) != 0) {
|
||||
fprintf(stderr, "encode(\"%s\") = \"%.*s\", want \"%s\"\n",
|
||||
t->decoded, (int)len, (const char*)out, t->encoded);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_decode(void) {
|
||||
static bool TestDecode() {
|
||||
uint8_t out[6];
|
||||
size_t i, len;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < kNumTests; i++) {
|
||||
/* Test the normal API. */
|
||||
const TEST_VECTOR *t = &test_vectors[i];
|
||||
for (size_t i = 0; i < kNumTests; i++) {
|
||||
// Test the normal API.
|
||||
const TestVector *t = &kTestVectors[i];
|
||||
size_t expected_len = strlen(t->decoded);
|
||||
if (!EVP_DecodeBase64(out, &len, sizeof(out),
|
||||
(const uint8_t*)t->encoded, strlen(t->encoded))) {
|
||||
fprintf(stderr, "decode(\"%s\") failed\n", t->encoded);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (len != strlen(t->decoded) ||
|
||||
memcmp(out, t->decoded, len) != 0) {
|
||||
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
|
||||
t->encoded, (int)len, (const char*)out, t->decoded);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Test that the padding behavior of the deprecated API is
|
||||
* preserved. */
|
||||
ret = EVP_DecodeBlock(out, (const uint8_t*)t->encoded, strlen(t->encoded));
|
||||
// Test that the padding behavior of the deprecated API is preserved.
|
||||
int ret = EVP_DecodeBlock(out, (const uint8_t*)t->encoded,
|
||||
strlen(t->encoded));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "decode(\"%s\") failed\n", t->encoded);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (ret % 3 != 0) {
|
||||
fprintf(stderr, "EVP_DecodeBlock did not ignore padding\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (expected_len % 3 != 0) {
|
||||
ret -= 3 - (expected_len % 3);
|
||||
}
|
||||
if (ret != strlen(t->decoded) ||
|
||||
if (static_cast<size_t>(ret) != strlen(t->decoded) ||
|
||||
memcmp(out, t->decoded, ret) != 0) {
|
||||
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
|
||||
t->encoded, ret, (const char*)out, t->decoded);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"a!bc", 4)) {
|
||||
fprintf(stderr, "Failed to reject invalid characters in the middle.\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"a=bc", 4)) {
|
||||
fprintf(stderr, "Failed to reject invalid characters in the middle.\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"abc", 4)) {
|
||||
fprintf(stderr, "Failed to reject invalid input length.\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
CRYPTO_library_init();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
if (!test_encode()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!test_decode()) {
|
||||
if (!TestEncode() ||
|
||||
!TestDecode()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+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.cc
|
||||
)
|
||||
|
||||
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,59 +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_zero_copy_get_read_buf, 0), "BIO_zero_copy_get_read_buf"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_read_buf_done, 0), "BIO_zero_copy_get_read_buf_done"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_write_buf, 0), "BIO_zero_copy_get_write_buf"},
|
||||
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_write_buf_done, 0), "BIO_zero_copy_get_write_buf_done"},
|
||||
{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,103 +27,117 @@
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.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)
|
||||
#include <algorithm>
|
||||
|
||||
#include "../test/scoped_types.h"
|
||||
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
static int closesocket(int sock) {
|
||||
return close(sock);
|
||||
}
|
||||
|
||||
static void print_socket_error(const char *func) {
|
||||
static void PrintSocketError(const char *func) {
|
||||
perror(func);
|
||||
}
|
||||
#else
|
||||
static void print_socket_error(const char *func) {
|
||||
static void PrintSocketError(const char *func) {
|
||||
fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_socket_connect(void) {
|
||||
int listening_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int sock;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sockaddr_len = sizeof(sin);
|
||||
static const char kTestMessage[] = "test";
|
||||
char hostname[80], buf[5];
|
||||
BIO *bio;
|
||||
class ScopedSocket {
|
||||
public:
|
||||
ScopedSocket(int sock) : sock_(sock) {}
|
||||
~ScopedSocket() {
|
||||
closesocket(sock_);
|
||||
}
|
||||
|
||||
private:
|
||||
const int sock_;
|
||||
};
|
||||
|
||||
static bool TestSocketConnect() {
|
||||
static const char kTestMessage[] = "test";
|
||||
|
||||
int listening_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listening_sock == -1) {
|
||||
PrintSocketError("socket");
|
||||
return false;
|
||||
}
|
||||
ScopedSocket listening_sock_closer(listening_sock);
|
||||
|
||||
struct sockaddr_in sin;
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
if (!inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr)) {
|
||||
print_socket_error("inet_pton");
|
||||
return 0;
|
||||
PrintSocketError("inet_pton");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
|
||||
print_socket_error("bind");
|
||||
return 0;
|
||||
PrintSocketError("bind");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (listen(listening_sock, 1)) {
|
||||
print_socket_error("listen");
|
||||
return 0;
|
||||
PrintSocketError("listen");
|
||||
return false;
|
||||
}
|
||||
|
||||
socklen_t sockaddr_len = sizeof(sin);
|
||||
if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
|
||||
sockaddr_len != sizeof(sin)) {
|
||||
print_socket_error("getsockname");
|
||||
return 0;
|
||||
PrintSocketError("getsockname");
|
||||
return false;
|
||||
}
|
||||
|
||||
char hostname[80];
|
||||
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
|
||||
ntohs(sin.sin_port));
|
||||
bio = BIO_new_connect(hostname);
|
||||
ScopedBIO bio(BIO_new_connect(hostname));
|
||||
if (!bio) {
|
||||
fprintf(stderr, "BIO_new_connect failed.\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BIO_write(bio, kTestMessage, sizeof(kTestMessage)) !=
|
||||
if (BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)) !=
|
||||
sizeof(kTestMessage)) {
|
||||
fprintf(stderr, "BIO_write failed.\n");
|
||||
BIO_print_errors_fp(stderr);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
|
||||
if (sock < 0) {
|
||||
print_socket_error("accept");
|
||||
return 0;
|
||||
int sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
|
||||
if (sock == -1) {
|
||||
PrintSocketError("accept");
|
||||
return false;
|
||||
}
|
||||
ScopedSocket sock_closer(sock);
|
||||
|
||||
char buf[5];
|
||||
if (recv(sock, buf, sizeof(buf), 0) != sizeof(kTestMessage)) {
|
||||
print_socket_error("read");
|
||||
return 0;
|
||||
PrintSocketError("read");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
closesocket(sock);
|
||||
closesocket(listening_sock);
|
||||
BIO_free(bio);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* 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) {
|
||||
// BioReadZeroCopyWrapper is a wrapper around the zero-copy APIs to make
|
||||
// testing easier.
|
||||
static size_t BioReadZeroCopyWrapper(BIO *bio, uint8_t *data, size_t len) {
|
||||
uint8_t *read_buf;
|
||||
size_t read_buf_offset;
|
||||
size_t available_bytes;
|
||||
@@ -135,7 +149,7 @@ static size_t bio_read_zero_copy_wrapper(BIO *bio, uint8_t *data, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
available_bytes = MIN(available_bytes, len - len_read);
|
||||
available_bytes = std::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);
|
||||
@@ -146,10 +160,10 @@ static size_t bio_read_zero_copy_wrapper(BIO *bio, uint8_t *data, size_t len) {
|
||||
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) {
|
||||
// BioWriteZeroCopyWrapper is a wrapper around the zero-copy APIs to make
|
||||
// testing easier.
|
||||
static size_t BioWriteZeroCopyWrapper(BIO *bio, const uint8_t *data,
|
||||
size_t len) {
|
||||
uint8_t *write_buf;
|
||||
size_t write_buf_offset;
|
||||
size_t available_bytes;
|
||||
@@ -161,7 +175,7 @@ static size_t bio_write_zero_copy_wrapper(BIO *bio, const uint8_t *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
available_bytes = MIN(available_bytes, len - len_written);
|
||||
available_bytes = std::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);
|
||||
@@ -172,167 +186,157 @@ static size_t bio_write_zero_copy_wrapper(BIO *bio, const uint8_t *data,
|
||||
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;
|
||||
static bool TestZeroCopyBioPairs() {
|
||||
// Test read and write, especially triggering the ring buffer wrap-around.
|
||||
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. */
|
||||
// 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++) {
|
||||
for (size_t 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;
|
||||
// Transfer bytes from bio1_application_send_buffer to
|
||||
// bio2_application_recv_buffer in various ways.
|
||||
for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
|
||||
for (size_t j = 0; j < sizeof(kPartialLengths) / sizeof(kPartialLengths[0]);
|
||||
j++) {
|
||||
size_t total_write = 0;
|
||||
size_t total_read = 0;
|
||||
|
||||
BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize);
|
||||
BIO *bio1, *bio2;
|
||||
if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
|
||||
return false;
|
||||
}
|
||||
ScopedBIO bio1_scoper(bio1);
|
||||
ScopedBIO bio2_scoper(bio2);
|
||||
|
||||
total_write += bio_write_zero_copy_wrapper(
|
||||
total_write += BioWriteZeroCopyWrapper(
|
||||
bio1, bio1_application_send_buffer, kLengths[i]);
|
||||
|
||||
/* This tests interleaved read/write calls. Do a read between zero copy
|
||||
* write calls. */
|
||||
// This tests interleaved read/write calls. Do a read between zero copy
|
||||
// write calls.
|
||||
uint8_t *write_buf;
|
||||
size_t write_buf_offset;
|
||||
size_t available_bytes;
|
||||
if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
|
||||
&available_bytes)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Free kPartialLengths[j] bytes in the beginning of bio1 write buffer.
|
||||
* This enables ring buffer wrap around for the next write. */
|
||||
// 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);
|
||||
size_t interleaved_write_len = std::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. */
|
||||
// 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(
|
||||
// Do another write in case |write_buf_offset| was wrapped.
|
||||
total_write += BioWriteZeroCopyWrapper(
|
||||
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(
|
||||
// Drain the rest.
|
||||
size_t bytes_left = BIO_pending(bio2);
|
||||
total_read += BioReadZeroCopyWrapper(
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
if (total_read > kLengths[i] + kPartialLengths[j]) {
|
||||
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
|
||||
(unsigned)j);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
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 false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
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. */
|
||||
static bool TestPrintf() {
|
||||
// Test a short output, a very long one, and various sizes around
|
||||
// 256 (the size of the buffer) to ensure edge cases are correct.
|
||||
static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };
|
||||
BIO *bio;
|
||||
char string[1024];
|
||||
int ret;
|
||||
const uint8_t *contents;
|
||||
size_t i, len;
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
ScopedBIO bio(BIO_new(BIO_s_mem()));
|
||||
if (!bio) {
|
||||
fprintf(stderr, "BIO_new failed\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
|
||||
for (size_t i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
|
||||
char string[1024];
|
||||
if (kLengths[i] >= sizeof(string)) {
|
||||
fprintf(stderr, "Bad test string length\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
memset(string, 'a', sizeof(string));
|
||||
string[kLengths[i]] = '\0';
|
||||
|
||||
ret = BIO_printf(bio, "test %s", string);
|
||||
if (ret != 5 + kLengths[i]) {
|
||||
int ret = BIO_printf(bio.get(), "test %s", string);
|
||||
if (ret < 0 || static_cast<size_t>(ret) != 5 + kLengths[i]) {
|
||||
fprintf(stderr, "BIO_printf failed: %d\n", ret);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (!BIO_mem_contents(bio, &contents, &len)) {
|
||||
const uint8_t *contents;
|
||||
size_t len;
|
||||
if (!BIO_mem_contents(bio.get(), &contents, &len)) {
|
||||
fprintf(stderr, "BIO_mem_contents failed\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (len != 5 + kLengths[i] ||
|
||||
strncmp((const char *)contents, "test ", 5) != 0 ||
|
||||
strncmp((const char *)contents + 5, string, kLengths[i]) != 0) {
|
||||
fprintf(stderr, "Contents did not match: %.*s\n", (int)len, contents);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!BIO_reset(bio)) {
|
||||
if (!BIO_reset(bio.get())) {
|
||||
fprintf(stderr, "BIO_reset failed\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
WSADATA wsa_data;
|
||||
WORD wsa_version;
|
||||
int wsa_err;
|
||||
#endif
|
||||
|
||||
CRYPTO_library_init();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
/* Initialize Winsock. */
|
||||
wsa_version = MAKEWORD(2, 2);
|
||||
wsa_err = WSAStartup(wsa_version, &wsa_data);
|
||||
// Initialize Winsock.
|
||||
WORD wsa_version = MAKEWORD(2, 2);
|
||||
WSADATA wsa_data;
|
||||
int wsa_err = WSAStartup(wsa_version, &wsa_data);
|
||||
if (wsa_err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
|
||||
return 1;
|
||||
@@ -343,15 +347,9 @@ int main(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!test_socket_connect()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!test_printf()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!test_zero_copy_bio_pairs()) {
|
||||
if (!TestSocketConnect() ||
|
||||
!TestPrintf() ||
|
||||
!TestZeroCopyBioPairs()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+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). */
|
||||
|
||||
+4
-1
@@ -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>
|
||||
#include <Windows.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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
+11
-2
@@ -58,9 +58,16 @@
|
||||
#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)
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
@@ -145,11 +152,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
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
typedef int socklen_t;
|
||||
#pragma warning(push, 3)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#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.cc
|
||||
)
|
||||
|
||||
target_link_libraries(bn_test crypto)
|
||||
|
||||
@@ -661,6 +661,7 @@ $code.=<<___;
|
||||
.align 2
|
||||
#if __ARM_ARCH__>=7
|
||||
.comm OPENSSL_armcap_P,4,4
|
||||
.hidden OPENSSL_armcap_P
|
||||
#endif
|
||||
___
|
||||
|
||||
|
||||
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;
|
||||
|
||||
+46
-26
@@ -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
|
||||
|
||||
|
||||
+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},
|
||||
};
|
||||
-1469
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
+93
-62
@@ -109,6 +109,7 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -171,12 +172,13 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (r != rr) {
|
||||
BN_copy(r, rr);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -684,12 +686,14 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
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. */
|
||||
@@ -703,9 +707,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
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;
|
||||
@@ -877,13 +880,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
|
||||
@@ -892,8 +895,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;
|
||||
@@ -901,8 +905,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;
|
||||
@@ -917,8 +922,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;
|
||||
@@ -931,20 +937,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 */
|
||||
@@ -960,20 +970,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,
|
||||
@@ -1000,16 +1013,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);
|
||||
@@ -1042,8 +1059,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
|
||||
@@ -1055,8 +1073,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);
|
||||
@@ -1100,17 +1119,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)
|
||||
@@ -1118,24 +1138,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.
|
||||
@@ -1145,32 +1167,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);
|
||||
@@ -1237,13 +1265,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;
|
||||
}
|
||||
}
|
||||
@@ -1476,28 +1502,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
|
||||
|
||||
+25
-89
@@ -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++;
|
||||
@@ -749,49 +722,6 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
|
||||
#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)
|
||||
|
||||
/* 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_ULONG lo = ta * tb; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(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) \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b), tt; \
|
||||
BN_ULONG lo = ta * tb; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(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_ULONG lo = ta * ta; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(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 */
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
@@ -1125,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;
|
||||
@@ -1142,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;
|
||||
@@ -1179,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;
|
||||
|
||||
+28
-3
@@ -125,10 +125,18 @@
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
/* Some versions of inttypes.h will not define print macros in C++ unless
|
||||
* __STDC_FORMAT_MACROS is set. */
|
||||
#if !defined(__STDC_FORMAT_MACROS)
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
@@ -142,8 +150,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)
|
||||
@@ -160,9 +174,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)
|
||||
@@ -188,6 +204,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);
|
||||
@@ -213,6 +234,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)
|
||||
@@ -243,6 +266,8 @@ 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
|
||||
# define BN_UMULT_HIGH(a,b) ({ \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+201
-195
@@ -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);
|
||||
@@ -472,7 +659,13 @@ again:
|
||||
/* If bits is so small that it fits into a single word then we
|
||||
* additionally don't want to exceed that many bits. */
|
||||
if (is_single_word) {
|
||||
BN_ULONG size_limit = (((BN_ULONG)1) << bits) - get_word(rnd) - 1;
|
||||
BN_ULONG size_limit;
|
||||
if (bits == BN_BITS2) {
|
||||
/* Avoid undefined behavior. */
|
||||
size_limit = ~((BN_ULONG)0) - get_word(rnd);
|
||||
} else {
|
||||
size_limit = (((BN_ULONG)1) << bits) - get_word(rnd) - 1;
|
||||
}
|
||||
if (size_limit < maxdelta) {
|
||||
maxdelta = size_limit;
|
||||
}
|
||||
@@ -495,8 +688,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 +700,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 +844,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, };
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
@@ -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,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.cc
|
||||
)
|
||||
|
||||
target_link_libraries(bytestring_test crypto)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
|
||||
@@ -14,15 +14,19 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
#include "../test/scoped_types.h"
|
||||
|
||||
|
||||
static int test_skip(void) {
|
||||
static bool TestSkip() {
|
||||
static const uint8_t kData[] = {1, 2, 3};
|
||||
CBS data;
|
||||
|
||||
@@ -35,7 +39,7 @@ static int test_skip(void) {
|
||||
!CBS_skip(&data, 1);
|
||||
}
|
||||
|
||||
static int test_get_u(void) {
|
||||
static bool TestGetUint() {
|
||||
static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
uint8_t u8;
|
||||
uint16_t u16;
|
||||
@@ -54,7 +58,7 @@ static int test_get_u(void) {
|
||||
!CBS_get_u8(&data, &u8);
|
||||
}
|
||||
|
||||
static int test_get_prefixed(void) {
|
||||
static bool TestGetPrefixed() {
|
||||
static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
|
||||
uint8_t u8;
|
||||
uint16_t u16;
|
||||
@@ -76,7 +80,7 @@ static int test_get_prefixed(void) {
|
||||
u32 == 0x30201;
|
||||
}
|
||||
|
||||
static int test_get_prefixed_bad(void) {
|
||||
static bool TestGetPrefixedBad() {
|
||||
static const uint8_t kData1[] = {2, 1};
|
||||
static const uint8_t kData2[] = {0, 2, 1};
|
||||
static const uint8_t kData3[] = {0, 0, 2, 1};
|
||||
@@ -84,23 +88,23 @@ static int test_get_prefixed_bad(void) {
|
||||
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData2, sizeof(kData2));
|
||||
if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData3, sizeof(kData3));
|
||||
if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_get_asn1(void) {
|
||||
static bool TestGetASN1() {
|
||||
static const uint8_t kData1[] = {0x30, 2, 1, 2};
|
||||
static const uint8_t kData2[] = {0x30, 3, 1, 2};
|
||||
static const uint8_t kData3[] = {0x30, 0x80};
|
||||
@@ -118,52 +122,52 @@ static int test_get_asn1(void) {
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
if (CBS_peek_asn1_tag(&data, 0x1) ||
|
||||
!CBS_peek_asn1_tag(&data, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (!CBS_get_asn1(&data, &contents, 0x30) ||
|
||||
CBS_len(&contents) != 2 ||
|
||||
memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData2, sizeof(kData2));
|
||||
/* data is truncated */
|
||||
// data is truncated
|
||||
if (CBS_get_asn1(&data, &contents, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData3, sizeof(kData3));
|
||||
/* zero byte length of length */
|
||||
// zero byte length of length
|
||||
if (CBS_get_asn1(&data, &contents, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData4, sizeof(kData4));
|
||||
/* long form mistakenly used. */
|
||||
// long form mistakenly used.
|
||||
if (CBS_get_asn1(&data, &contents, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData5, sizeof(kData5));
|
||||
/* length takes too many bytes. */
|
||||
// length takes too many bytes.
|
||||
if (CBS_get_asn1(&data, &contents, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
/* wrong tag. */
|
||||
// wrong tag.
|
||||
if (CBS_get_asn1(&data, &contents, 0x31)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, NULL, 0);
|
||||
/* peek at empty data. */
|
||||
// peek at empty data.
|
||||
if (CBS_peek_asn1_tag(&data, 0x30)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, NULL, 0);
|
||||
/* optional elements at empty data. */
|
||||
// optional elements at empty data.
|
||||
if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
|
||||
present ||
|
||||
!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
|
||||
@@ -173,22 +177,22 @@ static int test_get_asn1(void) {
|
||||
CBS_len(&contents) != 0 ||
|
||||
!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
|
||||
value != 42) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData6, sizeof(kData6));
|
||||
/* optional element. */
|
||||
// optional element.
|
||||
if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
|
||||
present ||
|
||||
!CBS_get_optional_asn1(&data, &contents, &present, 0xa1) ||
|
||||
!present ||
|
||||
CBS_len(&contents) != 3 ||
|
||||
memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData6, sizeof(kData6));
|
||||
/* optional octet string. */
|
||||
// optional octet string.
|
||||
if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
|
||||
present ||
|
||||
CBS_len(&contents) != 0 ||
|
||||
@@ -196,97 +200,96 @@ static int test_get_asn1(void) {
|
||||
!present ||
|
||||
CBS_len(&contents) != 1 ||
|
||||
CBS_data(&contents)[0] != 1) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData7, sizeof(kData7));
|
||||
/* invalid optional octet string. */
|
||||
// invalid optional octet string.
|
||||
if (CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData8, sizeof(kData8));
|
||||
/* optional octet string. */
|
||||
// optional octet string.
|
||||
if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
|
||||
value != 42 ||
|
||||
!CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) ||
|
||||
value != 1) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kData9, sizeof(kData9));
|
||||
/* invalid optional integer. */
|
||||
// invalid optional integer.
|
||||
if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_get_optional_asn1_bool(void) {
|
||||
CBS data;
|
||||
int val;
|
||||
|
||||
static bool TestGetOptionalASN1Bool() {
|
||||
static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
|
||||
static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
|
||||
static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01};
|
||||
|
||||
CBS data;
|
||||
CBS_init(&data, NULL, 0);
|
||||
val = 2;
|
||||
int val = 2;
|
||||
if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
|
||||
val != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kTrue, sizeof(kTrue));
|
||||
val = 2;
|
||||
if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
|
||||
val != 1) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kFalse, sizeof(kFalse));
|
||||
val = 2;
|
||||
if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) ||
|
||||
val != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS_init(&data, kInvalid, sizeof(kInvalid));
|
||||
if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_cbb_basic(void) {
|
||||
static bool TestCBBBasic() {
|
||||
static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
int ok;
|
||||
CBB cbb;
|
||||
|
||||
if (!CBB_init(&cbb, 100)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_u8(&cbb, 1) ||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_u8(&cbb, 1) ||
|
||||
!CBB_add_u16(&cbb, 0x203) ||
|
||||
!CBB_add_u24(&cbb, 0x40506) ||
|
||||
!CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
|
||||
free(buf);
|
||||
return ok;
|
||||
ScopedOpenSSLBytes scoper(buf);
|
||||
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
|
||||
}
|
||||
|
||||
static int test_cbb_fixed(void) {
|
||||
static bool TestCBBFixed() {
|
||||
CBB cbb;
|
||||
uint8_t buf[1];
|
||||
uint8_t *out_buf;
|
||||
@@ -297,7 +300,7 @@ static int test_cbb_fixed(void) {
|
||||
!CBB_finish(&cbb, &out_buf, &out_size) ||
|
||||
out_buf != NULL ||
|
||||
out_size != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CBB_init_fixed(&cbb, buf, 1) ||
|
||||
@@ -307,40 +310,41 @@ static int test_cbb_fixed(void) {
|
||||
out_buf != buf ||
|
||||
out_size != 1 ||
|
||||
buf[0] != 1) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_cbb_finish_child(void) {
|
||||
static bool TestCBBFinishChild() {
|
||||
CBB cbb, child;
|
||||
uint8_t *out_buf;
|
||||
size_t out_size;
|
||||
|
||||
if (!CBB_init(&cbb, 16) ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &child) ||
|
||||
CBB_finish(&child, &out_buf, &out_size) ||
|
||||
!CBB_finish(&cbb, &out_buf, &out_size) ||
|
||||
out_size != 1 ||
|
||||
out_buf[0] != 0) {
|
||||
return 0;
|
||||
if (!CBB_init(&cbb, 16)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
free(out_buf);
|
||||
return 1;
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
|
||||
CBB_finish(&child, &out_buf, &out_size) ||
|
||||
!CBB_finish(&cbb, &out_buf, &out_size)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes scoper(out_buf);
|
||||
return out_size == 1 && out_buf[0] == 0;
|
||||
}
|
||||
|
||||
static int test_cbb_prefixed(void) {
|
||||
static bool TestCBBPrefixed() {
|
||||
static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
|
||||
4, 5, 6, 5, 4, 1, 0, 1, 2};
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
CBB cbb, contents, inner_contents, inner_inner_contents;
|
||||
int ok;
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
!CBB_add_u8(&contents, 1) ||
|
||||
!CBB_add_u16_length_prefixed(&cbb, &contents) ||
|
||||
@@ -353,28 +357,31 @@ static int test_cbb_prefixed(void) {
|
||||
!CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
|
||||
!CBB_add_u8(&inner_inner_contents, 2) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
|
||||
free(buf);
|
||||
return ok;
|
||||
ScopedOpenSSLBytes scoper(buf);
|
||||
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
|
||||
}
|
||||
|
||||
static int test_cbb_misuse(void) {
|
||||
static bool TestCBBMisuse() {
|
||||
CBB cbb, child, contents;
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &child) ||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
|
||||
!CBB_add_u8(&child, 1) ||
|
||||
!CBB_add_u8(&cbb, 2)) {
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
|
||||
* it should fail. */
|
||||
// Since we wrote to |cbb|, |child| is now invalid and attempts to write to
|
||||
// it should fail.
|
||||
if (CBB_add_u8(&child, 1) ||
|
||||
CBB_add_u16(&child, 1) ||
|
||||
CBB_add_u24(&child, 1) ||
|
||||
@@ -383,91 +390,104 @@ static int test_cbb_misuse(void) {
|
||||
CBB_add_asn1(&child, &contents, 1) ||
|
||||
CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
|
||||
fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CBB_finish(&cbb, &buf, &buf_len) ||
|
||||
buf_len != 3 ||
|
||||
if (!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes scoper(buf);
|
||||
|
||||
if (buf_len != 3 ||
|
||||
memcmp(buf, "\x01\x01\x02", 3) != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_cbb_asn1(void) {
|
||||
static bool TestCBBASN1() {
|
||||
static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
|
||||
uint8_t *buf, *test_data;
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
CBB cbb, contents, inner_contents;
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes scoper(buf);
|
||||
|
||||
if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
test_data = malloc(100000);
|
||||
memset(test_data, 0x42, 100000);
|
||||
std::vector<uint8_t> test_data(100000, 0x42);
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_bytes(&contents, test_data, 130) ||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_bytes(&contents, bssl::vector_data(&test_data), 130) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
scoper.reset(buf);
|
||||
|
||||
if (buf_len != 3 + 130 ||
|
||||
memcmp(buf, "\x30\x81\x82", 3) != 0 ||
|
||||
memcmp(buf + 3, test_data, 130) != 0) {
|
||||
return 0;
|
||||
memcmp(buf + 3, bssl::vector_data(&test_data), 130) != 0) {
|
||||
return false;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_bytes(&contents, test_data, 1000) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_bytes(&contents, bssl::vector_data(&test_data), 1000) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
scoper.reset(buf);
|
||||
|
||||
if (buf_len != 4 + 1000 ||
|
||||
memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
|
||||
memcmp(buf + 4, test_data, 1000)) {
|
||||
return 0;
|
||||
memcmp(buf + 4, bssl::vector_data(&test_data), 1000)) {
|
||||
return false;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_asn1(&contents, &inner_contents, 0x30) ||
|
||||
!CBB_add_bytes(&inner_contents, test_data, 100000) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
return 0;
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
|
||||
!CBB_add_asn1(&contents, &inner_contents, 0x30) ||
|
||||
!CBB_add_bytes(&inner_contents, bssl::vector_data(&test_data), 100000) ||
|
||||
!CBB_finish(&cbb, &buf, &buf_len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
scoper.reset(buf);
|
||||
|
||||
if (buf_len != 5 + 5 + 100000 ||
|
||||
memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
|
||||
memcmp(buf + 10, test_data, 100000)) {
|
||||
return 0;
|
||||
memcmp(buf + 10, bssl::vector_data(&test_data), 100000)) {
|
||||
return false;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
free(test_data);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int do_ber_convert(const char *name,
|
||||
const uint8_t *der_expected, size_t der_len,
|
||||
const uint8_t *ber, size_t ber_len) {
|
||||
static bool DoBerConvert(const char *name,
|
||||
const uint8_t *der_expected, size_t der_len,
|
||||
const uint8_t *ber, size_t ber_len) {
|
||||
CBS in;
|
||||
uint8_t *out;
|
||||
size_t out_len;
|
||||
@@ -475,44 +495,44 @@ static int do_ber_convert(const char *name,
|
||||
CBS_init(&in, ber, ber_len);
|
||||
if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
|
||||
fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes scoper(out);
|
||||
|
||||
if (out == NULL) {
|
||||
if (ber_len != der_len ||
|
||||
memcmp(der_expected, ber, ber_len) != 0) {
|
||||
fprintf(stderr, "%s: incorrect unconverted result.\n", name);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (out_len != der_len ||
|
||||
memcmp(out, der_expected, der_len) != 0) {
|
||||
fprintf(stderr, "%s: incorrect converted result.\n", name);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
free(out);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int test_ber_convert(void) {
|
||||
static bool TestBerConvert() {
|
||||
static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
|
||||
|
||||
/* kIndefBER contains a SEQUENCE with an indefinite length. */
|
||||
// kIndefBER contains a SEQUENCE with an indefinite length.
|
||||
static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
|
||||
static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
|
||||
|
||||
/* kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
|
||||
* These parts need to be concatenated in DER form. */
|
||||
// kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
|
||||
// These parts need to be concatenated in DER form.
|
||||
static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
|
||||
0x04, 0x02, 2, 3, 0x00, 0x00};
|
||||
static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
|
||||
|
||||
/* kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite
|
||||
* length elements extensively. */
|
||||
// kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite
|
||||
// length elements extensively.
|
||||
static const uint8_t kNSSBER[] = {
|
||||
0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48,
|
||||
0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04,
|
||||
@@ -535,56 +555,55 @@ static int test_ber_convert(void) {
|
||||
0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
|
||||
};
|
||||
|
||||
return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
|
||||
kSimpleBER, sizeof(kSimpleBER)) &&
|
||||
do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
|
||||
sizeof(kIndefBER)) &&
|
||||
do_ber_convert("kOctetStringBER", kOctetStringDER,
|
||||
sizeof(kOctetStringDER), kOctetStringBER,
|
||||
sizeof(kOctetStringBER)) &&
|
||||
do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
|
||||
sizeof(kNSSBER));
|
||||
return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
|
||||
kSimpleBER, sizeof(kSimpleBER)) &&
|
||||
DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
|
||||
sizeof(kIndefBER)) &&
|
||||
DoBerConvert("kOctetStringBER", kOctetStringDER,
|
||||
sizeof(kOctetStringDER), kOctetStringBER,
|
||||
sizeof(kOctetStringBER)) &&
|
||||
DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
|
||||
sizeof(kNSSBER));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct ASN1Uint64Test {
|
||||
uint64_t value;
|
||||
const char *encoding;
|
||||
size_t encoding_len;
|
||||
} ASN1_UINT64_TEST;
|
||||
|
||||
static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = {
|
||||
{0, "\x02\x01\x00", 3},
|
||||
{1, "\x02\x01\x01", 3},
|
||||
{127, "\x02\x01\x7f", 3},
|
||||
{128, "\x02\x02\x00\x80", 4},
|
||||
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
|
||||
{OPENSSL_U64(0x0102030405060708),
|
||||
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
|
||||
{OPENSSL_U64(0xffffffffffffffff),
|
||||
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
static const ASN1Uint64Test kASN1Uint64Tests[] = {
|
||||
{0, "\x02\x01\x00", 3},
|
||||
{1, "\x02\x01\x01", 3},
|
||||
{127, "\x02\x01\x7f", 3},
|
||||
{128, "\x02\x02\x00\x80", 4},
|
||||
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
|
||||
{OPENSSL_U64(0x0102030405060708),
|
||||
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
|
||||
{OPENSSL_U64(0xffffffffffffffff),
|
||||
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
|
||||
};
|
||||
|
||||
struct ASN1InvalidUint64Test {
|
||||
const char *encoding;
|
||||
size_t encoding_len;
|
||||
} ASN1_INVALID_UINT64_TEST;
|
||||
|
||||
static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = {
|
||||
/* Bad tag. */
|
||||
{"\x03\x01\x00", 3},
|
||||
/* Empty contents. */
|
||||
{"\x02\x00", 2},
|
||||
/* Negative number. */
|
||||
{"\x02\x01\x80", 3},
|
||||
/* Overflow */
|
||||
{"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
|
||||
};
|
||||
|
||||
static int test_asn1_uint64(void) {
|
||||
size_t i;
|
||||
static const ASN1InvalidUint64Test kASN1InvalidUint64Tests[] = {
|
||||
// Bad tag.
|
||||
{"\x03\x01\x00", 3},
|
||||
// Empty contents.
|
||||
{"\x02\x00", 2},
|
||||
// Negative number.
|
||||
{"\x02\x01\x80", 3},
|
||||
// Overflow
|
||||
{"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); i++) {
|
||||
const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i];
|
||||
static bool TestASN1Uint64() {
|
||||
for (size_t i = 0; i < sizeof(kASN1Uint64Tests) / sizeof(kASN1Uint64Tests[0]);
|
||||
i++) {
|
||||
const ASN1Uint64Test *test = &kASN1Uint64Tests[i];
|
||||
CBS cbs;
|
||||
uint64_t value;
|
||||
CBB cbb;
|
||||
@@ -595,57 +614,56 @@ static int test_asn1_uint64(void) {
|
||||
if (!CBS_get_asn1_uint64(&cbs, &value) ||
|
||||
CBS_len(&cbs) != 0 ||
|
||||
value != test->value) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_asn1_uint64(&cbb, test->value) ||
|
||||
!CBB_finish(&cbb, &out, &len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes scoper(out);
|
||||
if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) {
|
||||
free(out);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
free(out);
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(kAsn1InvalidUint64Tests) / sizeof(kAsn1InvalidUint64Tests[0]);
|
||||
for (size_t i = 0;
|
||||
i < sizeof(kASN1InvalidUint64Tests) / sizeof(kASN1InvalidUint64Tests[0]);
|
||||
i++) {
|
||||
const ASN1_INVALID_UINT64_TEST *test = &kAsn1InvalidUint64Tests[i];
|
||||
const ASN1InvalidUint64Test *test = &kASN1InvalidUint64Tests[i];
|
||||
CBS cbs;
|
||||
uint64_t value;
|
||||
|
||||
CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
|
||||
if (CBS_get_asn1_uint64(&cbs, &value)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
CRYPTO_library_init();
|
||||
|
||||
if (!test_skip() ||
|
||||
!test_get_u() ||
|
||||
!test_get_prefixed() ||
|
||||
!test_get_prefixed_bad() ||
|
||||
!test_get_asn1() ||
|
||||
!test_cbb_basic() ||
|
||||
!test_cbb_fixed() ||
|
||||
!test_cbb_finish_child() ||
|
||||
!test_cbb_misuse() ||
|
||||
!test_cbb_prefixed() ||
|
||||
!test_cbb_asn1() ||
|
||||
!test_ber_convert() ||
|
||||
!test_asn1_uint64() ||
|
||||
!test_get_optional_asn1_bool()) {
|
||||
if (!TestSkip() ||
|
||||
!TestGetUint() ||
|
||||
!TestGetPrefixed() ||
|
||||
!TestGetPrefixedBad() ||
|
||||
!TestGetASN1() ||
|
||||
!TestCBBBasic() ||
|
||||
!TestCBBFixed() ||
|
||||
!TestCBBFinishChild() ||
|
||||
!TestCBBMisuse() ||
|
||||
!TestCBBPrefixed() ||
|
||||
!TestCBBASN1() ||
|
||||
!TestBerConvert() ||
|
||||
!TestASN1Uint64() ||
|
||||
!TestGetOptionalASN1Bool()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+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)
|
||||
|
||||
+29
-4
@@ -33,12 +33,29 @@ size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }
|
||||
int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
|
||||
const uint8_t *key, size_t key_len, size_t tag_len,
|
||||
ENGINE *impl) {
|
||||
ctx->aead = aead;
|
||||
if (key_len != aead->key_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_UNSUPPORTED_KEY_SIZE);
|
||||
if (!aead->init) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_NO_DIRECTION_SET);
|
||||
return 0;
|
||||
}
|
||||
return aead->init(ctx, key, key_len, tag_len);
|
||||
return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len,
|
||||
evp_aead_open);
|
||||
}
|
||||
|
||||
int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
|
||||
const uint8_t *key, size_t key_len,
|
||||
size_t tag_len,
|
||||
enum evp_aead_direction_t dir) {
|
||||
ctx->aead = aead;
|
||||
if (key_len != aead->key_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init_with_direction,
|
||||
CIPHER_R_UNSUPPORTED_KEY_SIZE);
|
||||
return 0;
|
||||
}
|
||||
if (aead->init) {
|
||||
return aead->init(ctx, key, key_len, tag_len);
|
||||
} else {
|
||||
return aead->init_with_direction(ctx, key, key_len, tag_len, dir);
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
@@ -117,3 +134,11 @@ error:
|
||||
*out_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key) {
|
||||
if (ctx->aead->get_rc4_state == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ctx->aead->get_rc4_state(ctx, out_key);
|
||||
}
|
||||
|
||||
+133
-52
@@ -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,79 +74,119 @@ 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)) {
|
||||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY],
|
||||
lengths[TAG], evp_aead_seal)) {
|
||||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no);
|
||||
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
|
||||
* reset after each operation. */
|
||||
EVP_AEAD_CTX_cleanup(&ctx);
|
||||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG],
|
||||
NULL)) {
|
||||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY],
|
||||
lengths[TAG], evp_aead_open)) {
|
||||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no);
|
||||
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_with_direction(&ctx, aead, bufs[KEY], lengths[KEY],
|
||||
lengths[TAG], evp_aead_open)) {
|
||||
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_with_direction(&ctx, aead, bufs[KEY], lengths[KEY],
|
||||
lengths[TAG], evp_aead_open)) {
|
||||
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,12 +215,46 @@ 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) {
|
||||
aead = EVP_aead_aes_256_key_wrap();
|
||||
} else if (strcmp(argv[1], "aes-128-ctr-hmac-sha256") == 0) {
|
||||
aead = EVP_aead_aes_128_ctr_hmac_sha256();
|
||||
} else if (strcmp(argv[1], "aes-256-ctr-hmac-sha256") == 0) {
|
||||
aead = EVP_aead_aes_256_ctr_hmac_sha256();
|
||||
} else {
|
||||
fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
|
||||
return 2;
|
||||
@@ -218,6 +298,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@ EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) {
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) {
|
||||
if (c->cipher != NULL && c->cipher->cleanup && !c->cipher->cleanup(c)) {
|
||||
return 0;
|
||||
if (c->cipher != NULL && c->cipher->cleanup) {
|
||||
c->cipher->cleanup(c);
|
||||
}
|
||||
|
||||
if (c->cipher_data) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
+444
-38
@@ -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>
|
||||
@@ -55,10 +57,16 @@
|
||||
#include <openssl/modes.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
#include "../modes/internal.h"
|
||||
|
||||
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
#include "../arm_arch.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
@@ -103,14 +111,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 +201,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 +289,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 +311,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;
|
||||
@@ -314,22 +392,62 @@ static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ctr128_f aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
|
||||
const uint8_t *key, size_t key_len) {
|
||||
static char aesni_capable(void);
|
||||
|
||||
static ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
|
||||
block128_f *out_block, const uint8_t *key,
|
||||
size_t key_len) {
|
||||
if (aesni_capable()) {
|
||||
aesni_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
if (gcm_ctx != NULL) {
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aesni_encrypt);
|
||||
}
|
||||
if (out_block) {
|
||||
*out_block = (block128_f) aesni_encrypt;
|
||||
}
|
||||
return (ctr128_f)aesni_ctr32_encrypt_blocks;
|
||||
}
|
||||
|
||||
if (hwaes_capable()) {
|
||||
aes_v8_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
if (gcm_ctx != NULL) {
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_v8_encrypt);
|
||||
}
|
||||
if (out_block) {
|
||||
*out_block = (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);
|
||||
if (gcm_ctx != NULL) {
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
|
||||
}
|
||||
if (out_block) {
|
||||
*out_block = (block128_f) AES_encrypt;
|
||||
}
|
||||
return (ctr128_f)bsaes_ctr32_encrypt_blocks;
|
||||
}
|
||||
|
||||
if (vpaes_capable()) {
|
||||
vpaes_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt);
|
||||
if (out_block) {
|
||||
*out_block = (block128_f) vpaes_encrypt;
|
||||
}
|
||||
if (gcm_ctx != NULL) {
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AES_set_encrypt_key(key, key_len * 8, aes_key);
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
|
||||
if (gcm_ctx != NULL) {
|
||||
CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
|
||||
}
|
||||
if (out_block) {
|
||||
*out_block = (block128_f) AES_encrypt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -340,7 +458,8 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
return 1;
|
||||
}
|
||||
if (key) {
|
||||
gctx->ctr = aes_gcm_set_key(&gctx->ks.ks, &gctx->gcm, key, ctx->key_len);
|
||||
gctx->ctr =
|
||||
aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm, NULL, key, ctx->key_len);
|
||||
/* If we have an iv can set it directly, otherwise use saved IV. */
|
||||
if (iv == NULL && gctx->iv_set) {
|
||||
iv = gctx->iv;
|
||||
@@ -363,13 +482,12 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
|
||||
static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
|
||||
EVP_AES_GCM_CTX *gctx = c->cipher_data;
|
||||
OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
|
||||
if (gctx->iv != c->iv) {
|
||||
OPENSSL_free(gctx->iv);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* increment counter (64-bit int) by 1 */
|
||||
@@ -626,25 +744,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 |
|
||||
@@ -774,19 +892,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 */};
|
||||
@@ -869,15 +987,8 @@ static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aesni_capable()) {
|
||||
aesni_set_encrypt_key(key, key_len * 8, &gcm_ctx->ks.ks);
|
||||
CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
|
||||
(block128_f)aesni_encrypt);
|
||||
gcm_ctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
|
||||
} else {
|
||||
gcm_ctx->ctr =
|
||||
aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, key, key_len);
|
||||
}
|
||||
gcm_ctx->ctr =
|
||||
aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len);
|
||||
gcm_ctx->tag_len = tag_len;
|
||||
ctx->aead_state = gcm_ctx;
|
||||
|
||||
@@ -990,8 +1101,12 @@ static const EVP_AEAD aead_aes_128_gcm = {
|
||||
12, /* nonce len */
|
||||
EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
|
||||
EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
|
||||
aead_aes_gcm_init, aead_aes_gcm_cleanup,
|
||||
aead_aes_gcm_seal, aead_aes_gcm_open,
|
||||
aead_aes_gcm_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_gcm_cleanup,
|
||||
aead_aes_gcm_seal,
|
||||
aead_aes_gcm_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_gcm = {
|
||||
@@ -999,8 +1114,12 @@ static const EVP_AEAD aead_aes_256_gcm = {
|
||||
12, /* nonce len */
|
||||
EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
|
||||
EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
|
||||
aead_aes_gcm_init, aead_aes_gcm_cleanup,
|
||||
aead_aes_gcm_seal, aead_aes_gcm_open,
|
||||
aead_aes_gcm_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_gcm_cleanup,
|
||||
aead_aes_gcm_seal,
|
||||
aead_aes_gcm_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
|
||||
@@ -1204,7 +1323,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
}
|
||||
|
||||
if (in_len < 24) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1241,7 +1360,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
}
|
||||
|
||||
if (CRYPTO_memcmp(A, nonce, 8) != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1254,8 +1373,12 @@ static const EVP_AEAD aead_aes_128_key_wrap = {
|
||||
8, /* nonce len */
|
||||
8, /* overhead */
|
||||
8, /* max tag length */
|
||||
aead_aes_key_wrap_init, aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal, aead_aes_key_wrap_open,
|
||||
aead_aes_key_wrap_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal,
|
||||
aead_aes_key_wrap_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_key_wrap = {
|
||||
@@ -1263,17 +1386,300 @@ static const EVP_AEAD aead_aes_256_key_wrap = {
|
||||
8, /* nonce len */
|
||||
8, /* overhead */
|
||||
8, /* max tag length */
|
||||
aead_aes_key_wrap_init, aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal, aead_aes_key_wrap_open,
|
||||
aead_aes_key_wrap_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal,
|
||||
aead_aes_key_wrap_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_key_wrap(void) { return &aead_aes_128_key_wrap; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_key_wrap(void) { return &aead_aes_256_key_wrap; }
|
||||
|
||||
|
||||
#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
|
||||
#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12
|
||||
|
||||
struct aead_aes_ctr_hmac_sha256_ctx {
|
||||
union {
|
||||
double align;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
ctr128_f ctr;
|
||||
block128_f block;
|
||||
SHA256_CTX inner_init_state;
|
||||
SHA256_CTX outer_init_state;
|
||||
uint8_t tag_len;
|
||||
};
|
||||
|
||||
static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
|
||||
const uint8_t hmac_key[32]) {
|
||||
static const size_t hmac_key_len = 32;
|
||||
uint8_t block[SHA256_CBLOCK];
|
||||
memcpy(block, hmac_key, hmac_key_len);
|
||||
memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < hmac_key_len; i++) {
|
||||
block[i] ^= 0x36;
|
||||
}
|
||||
|
||||
SHA256_Init(out_inner);
|
||||
SHA256_Update(out_inner, block, sizeof(block));
|
||||
|
||||
memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
|
||||
for (i = 0; i < hmac_key_len; i++) {
|
||||
block[i] ^= (0x36 ^ 0x5c);
|
||||
}
|
||||
|
||||
SHA256_Init(out_outer);
|
||||
SHA256_Update(out_outer, block, sizeof(block));
|
||||
}
|
||||
|
||||
static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx;
|
||||
static const size_t hmac_key_len = 32;
|
||||
|
||||
if (key_len < hmac_key_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
|
||||
CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0; /* EVP_AEAD_CTX_init should catch this. */
|
||||
}
|
||||
|
||||
const size_t aes_key_len = key_len - hmac_key_len;
|
||||
if (aes_key_len != 16 && aes_key_len != 32) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
|
||||
CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0; /* EVP_AEAD_CTX_init should catch this. */
|
||||
}
|
||||
|
||||
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
|
||||
tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN;
|
||||
}
|
||||
|
||||
if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
|
||||
CIPHER_R_TAG_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
|
||||
if (aes_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aes_ctx->ctr =
|
||||
aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len);
|
||||
aes_ctx->tag_len = tag_len;
|
||||
hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state,
|
||||
key + aes_key_len);
|
||||
|
||||
ctx->aead_state = aes_ctx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(aes_ctx, sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
|
||||
OPENSSL_free(aes_ctx);
|
||||
}
|
||||
|
||||
static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) {
|
||||
unsigned i;
|
||||
uint8_t bytes[8];
|
||||
|
||||
for (i = 0; i < sizeof(bytes); i++) {
|
||||
bytes[i] = value & 0xff;
|
||||
value >>= 8;
|
||||
}
|
||||
SHA256_Update(sha256, bytes, sizeof(bytes));
|
||||
}
|
||||
|
||||
static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
|
||||
const SHA256_CTX *inner_init_state,
|
||||
const SHA256_CTX *outer_init_state,
|
||||
const uint8_t *ad, size_t ad_len,
|
||||
const uint8_t *nonce, const uint8_t *ciphertext,
|
||||
size_t ciphertext_len) {
|
||||
SHA256_CTX sha256;
|
||||
memcpy(&sha256, inner_init_state, sizeof(sha256));
|
||||
hmac_update_uint64(&sha256, ad_len);
|
||||
hmac_update_uint64(&sha256, ciphertext_len);
|
||||
SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
|
||||
SHA256_Update(&sha256, ad, ad_len);
|
||||
|
||||
/* Pad with zeros to the end of the SHA-256 block. */
|
||||
const unsigned num_padding =
|
||||
(SHA256_CBLOCK - ((sizeof(uint64_t)*2 +
|
||||
EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) %
|
||||
SHA256_CBLOCK)) %
|
||||
SHA256_CBLOCK;
|
||||
uint8_t padding[SHA256_CBLOCK];
|
||||
memset(padding, 0, num_padding);
|
||||
SHA256_Update(&sha256, padding, num_padding);
|
||||
|
||||
SHA256_Update(&sha256, ciphertext, ciphertext_len);
|
||||
|
||||
uint8_t inner_digest[SHA256_DIGEST_LENGTH];
|
||||
SHA256_Final(inner_digest, &sha256);
|
||||
|
||||
memcpy(&sha256, outer_init_state, sizeof(sha256));
|
||||
SHA256_Update(&sha256, inner_digest, sizeof(inner_digest));
|
||||
SHA256_Final(out, &sha256);
|
||||
}
|
||||
|
||||
static void aead_aes_ctr_hmac_sha256_crypt(
|
||||
const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out,
|
||||
const uint8_t *in, size_t len, const uint8_t *nonce) {
|
||||
/* Since the AEAD operation is one-shot, keeping a buffer of unused keystream
|
||||
* bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. */
|
||||
uint8_t partial_block_buffer[AES_BLOCK_SIZE];
|
||||
unsigned partial_block_offset = 0;
|
||||
memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
|
||||
|
||||
uint8_t counter[AES_BLOCK_SIZE];
|
||||
memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
|
||||
memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4);
|
||||
|
||||
if (aes_ctx->ctr) {
|
||||
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter,
|
||||
partial_block_buffer, &partial_block_offset,
|
||||
aes_ctx->ctr);
|
||||
} else {
|
||||
CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter,
|
||||
partial_block_buffer, &partial_block_offset,
|
||||
aes_ctx->block);
|
||||
}
|
||||
}
|
||||
|
||||
static int aead_aes_ctr_hmac_sha256_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) {
|
||||
const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
|
||||
const uint64_t in_len_64 = in_len;
|
||||
|
||||
if (in_len + aes_ctx->tag_len < in_len ||
|
||||
/* This input is so large it would overflow the 32-bit block counter. */
|
||||
in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
|
||||
CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len + aes_ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
|
||||
CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
|
||||
CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce);
|
||||
|
||||
uint8_t hmac_result[SHA256_DIGEST_LENGTH];
|
||||
hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
|
||||
&aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len);
|
||||
memcpy(out + in_len, hmac_result, aes_ctx->tag_len);
|
||||
*out_len = in_len + aes_ctx->tag_len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_aes_ctr_hmac_sha256_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) {
|
||||
const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
|
||||
size_t plaintext_len;
|
||||
|
||||
if (in_len < aes_ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
|
||||
CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
plaintext_len = in_len - aes_ctx->tag_len;
|
||||
|
||||
if (max_out_len < plaintext_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
|
||||
CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
|
||||
CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t hmac_result[SHA256_DIGEST_LENGTH];
|
||||
hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
|
||||
&aes_ctx->outer_init_state, ad, ad_len, nonce, in,
|
||||
plaintext_len);
|
||||
if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
|
||||
CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, plaintext_len, nonce);
|
||||
|
||||
*out_len = plaintext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = {
|
||||
16 /* AES key */ + 32 /* HMAC key */,
|
||||
12, /* nonce length */
|
||||
EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* overhead */
|
||||
EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* max tag length */
|
||||
|
||||
aead_aes_ctr_hmac_sha256_init,
|
||||
NULL /* init_with_direction */,
|
||||
aead_aes_ctr_hmac_sha256_cleanup,
|
||||
aead_aes_ctr_hmac_sha256_seal,
|
||||
aead_aes_ctr_hmac_sha256_open,
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
|
||||
32 /* AES key */ + 32 /* HMAC key */,
|
||||
12, /* nonce length */
|
||||
EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* overhead */
|
||||
EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* max tag length */
|
||||
|
||||
aead_aes_ctr_hmac_sha256_init,
|
||||
NULL /* init_with_direction */,
|
||||
aead_aes_ctr_hmac_sha256_cleanup,
|
||||
aead_aes_ctr_hmac_sha256_seal,
|
||||
aead_aes_ctr_hmac_sha256_open,
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
|
||||
return &aead_aes_128_ctr_hmac_sha256;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) {
|
||||
return &aead_aes_256_ctr_hmac_sha256;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -213,8 +209,12 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
|
||||
CHACHA20_NONCE_LEN, /* nonce len */
|
||||
POLY1305_TAG_LEN, /* overhead */
|
||||
POLY1305_TAG_LEN, /* max tag length */
|
||||
aead_chacha20_poly1305_init, aead_chacha20_poly1305_cleanup,
|
||||
aead_chacha20_poly1305_seal, aead_chacha20_poly1305_open,
|
||||
aead_chacha20_poly1305_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_chacha20_poly1305_cleanup,
|
||||
aead_chacha20_poly1305_seal,
|
||||
aead_chacha20_poly1305_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
|
||||
|
||||
+4
-26
@@ -61,8 +61,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#define EVP_MAXCHUNK (1<<30)
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
@@ -83,18 +81,8 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
|
||||
size_t in_len) {
|
||||
EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
|
||||
|
||||
while (in_len >= EVP_MAXCHUNK) {
|
||||
DES_ncbc_encrypt(in, out, EVP_MAXCHUNK, &dat->ks.ks, (DES_cblock *)ctx->iv,
|
||||
ctx->encrypt);
|
||||
in_len -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
DES_ncbc_encrypt(in, out, (long)in_len, &dat->ks.ks,
|
||||
(DES_cblock *)ctx->iv, ctx->encrypt);
|
||||
}
|
||||
DES_ncbc_encrypt(in, out, in_len, &dat->ks.ks, (DES_cblock *)ctx->iv,
|
||||
ctx->encrypt);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -132,18 +120,8 @@ static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
|
||||
const uint8_t *in, size_t in_len) {
|
||||
DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data;
|
||||
|
||||
while (in_len >= EVP_MAXCHUNK) {
|
||||
DES_ede3_cbc_encrypt(in, out, EVP_MAXCHUNK, &dat->ks.ks[0], &dat->ks.ks[1],
|
||||
&dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt);
|
||||
in_len -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1],
|
||||
&dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt);
|
||||
}
|
||||
DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1],
|
||||
&dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/obj.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -415,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;
|
||||
}
|
||||
|
||||
+29
-3
@@ -57,6 +57,7 @@
|
||||
#include <openssl/aead.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/cpu.h>
|
||||
@@ -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;
|
||||
@@ -357,13 +372,24 @@ static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_md5_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
|
||||
const RC4_KEY **out_key) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
|
||||
*out_key = &rc4_ctx->rc4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_rc4_md5_tls = {
|
||||
16 + MD5_DIGEST_LENGTH, /* key len (RC4 + MD5) */
|
||||
0, /* nonce len */
|
||||
MD5_DIGEST_LENGTH, /* overhead */
|
||||
MD5_DIGEST_LENGTH, /* max tag length */
|
||||
aead_rc4_md5_tls_init, aead_rc4_md5_tls_cleanup,
|
||||
aead_rc4_md5_tls_seal, aead_rc4_md5_tls_open,
|
||||
aead_rc4_md5_tls_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_rc4_md5_tls_cleanup,
|
||||
aead_rc4_md5_tls_seal,
|
||||
aead_rc4_md5_tls_open,
|
||||
aead_rc4_md5_tls_get_rc4_state,
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
/* 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;
|
||||
} 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_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, enum evp_aead_direction_t dir,
|
||||
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);
|
||||
assert(mac_key_len + enc_key_len + EVP_CIPHER_iv_length(cipher) == key_len);
|
||||
/* 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);
|
||||
|
||||
ctx->aead_state = ssl3_ctx;
|
||||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len],
|
||||
&key[mac_key_len + enc_key_len],
|
||||
dir == evp_aead_seal) ||
|
||||
!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;
|
||||
}
|
||||
|
||||
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 (!ssl3_ctx->cipher_ctx.encrypt) {
|
||||
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_OPERATION);
|
||||
return 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if (ssl3_ctx->cipher_ctx.encrypt) {
|
||||
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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_ssl3_get_rc4_state(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key) {
|
||||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state;
|
||||
if (EVP_CIPHER_CTX_cipher(&ssl3_ctx->cipher_ctx) != EVP_rc4()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_key = (RC4_KEY*) ssl3_ctx->cipher_ctx.cipher_data;
|
||||
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,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, 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,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, 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,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, 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,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, 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,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, 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 */
|
||||
NULL, /* init */
|
||||
aead_rc4_md5_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
aead_ssl3_get_rc4_state,
|
||||
};
|
||||
|
||||
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 */
|
||||
NULL, /* init */
|
||||
aead_rc4_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
aead_ssl3_get_rc4_state,
|
||||
};
|
||||
|
||||
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 */
|
||||
NULL, /* init */
|
||||
aead_aes_128_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
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 */
|
||||
NULL, /* init */
|
||||
aead_aes_256_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
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 */
|
||||
NULL, /* init */
|
||||
aead_des_ede3_cbc_sha1_ssl3_init,
|
||||
aead_ssl3_cleanup,
|
||||
aead_ssl3_seal,
|
||||
aead_ssl3_open,
|
||||
NULL, /* get_rc4_state */
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user