Compare commits

..

3 Commits

Author SHA1 Message Date
David Benjamin 345b735e31 Import RSAEphemeralKey tests from master.
This is a cherry-pick of https://boringssl-review.googlesource.com/#/c/2232/
and https://boringssl-review.googlesource.com/#/c/3650/ from master.

Change-Id: Ia488e629f20a92121beefcf7e106292030b41f67
Reviewed-on: https://boringssl-review.googlesource.com/3660
Reviewed-by: Adam Langley <agl@google.com>
2015-02-26 21:39:53 +00:00
Adam Langley 3fbc298104 Only allow ephemeral RSA keys in export ciphersuites.
OpenSSL clients would tolerate temporary RSA keys in non-export ciphersuites.
It also had an option SSL_OP_EPHEMERAL_RSA which enabled this server side.
Remove both options as they are a protocol violation.

Thanks to Karthikeyan Bhargavan for reporting this issue. (CVE-2015-0204)

(This is a backport of upstream's
37580f43b5a39f5f4e920d17273fab9713d3a744 to the M40 branch. In BoringSSL
master we fixed this with
https://boringssl.googlesource.com/boringssl/+/525a0fe315282ca1840f8f9f170c8a26ce5fab2a,
but that's a larger patch than we really want to be backporting.)

Change-Id: Ibfb0c46648bbecffb9d3b1a4ebdf10a5a79523b3
Reviewed-on: https://boringssl-review.googlesource.com/3640
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-02-26 21:35:29 +00:00
Eric Roman 54e455157a Set output EC_KEY to NULL when d2i_ECPrivateKey() fails.
BUG=crbug.com/445679

Change-Id: Ia012d806964bd7240148779797eccd326484f364
Reviewed-on: https://boringssl-review.googlesource.com/2722
Reviewed-by: Adam Langley <agl@google.com>
(cherry picked from commit 517073cd4b)
2015-01-06 14:52:10 -08:00
1284 changed files with 68161 additions and 127597 deletions
-2
View File
@@ -2,5 +2,3 @@ build/
ssl/test/runner/runner
*.swp
*.swo
doc/*.html
doc/doc.css
+33
View File
@@ -0,0 +1,33 @@
mkdir build
cd build
cmake ..
make
Note that the default build flags in the top-leve 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 ..
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.
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.
[1] http://martine.github.io/ninja/
[2] http://yasm.tortall.net/
-143
View File
@@ -1,143 +0,0 @@
# Building BoringSSL
## Build Prerequisites
* [CMake](http://www.cmake.org/download/) 2.8.8 or later is required.
* Perl 5.6.1 or later is required. On Windows,
[Strawberry Perl](http://strawberryperl.com/) 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](https://martine.github.io/ninja/)
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](https://www.python.org/downloads/) is required (Python 2.7.5 works).
* On Windows only, [Yasm](http://yasm.tortall.net/) 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](https://golang.org/dl/) is required. If not found by CMake, the go
executable may be configured explicitly by setting `GO_EXECUTABLE`.
* If you change crypto/chacha/chacha\_vec.c, you will need the
arm-linux-gnueabihf-gcc compiler:
```
wget https://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
echo bc4ca2ced084d2dc12424815a4442e19cb1422db87068830305d90075feb1a3b gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz | sha256sum -c && \
tar xf gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz && \
sudo mv gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf /opt/
```
## Building
Using Ninja (note the 'N' is capitalized in the cmake invocation):
mkdir build
cd build
cmake -GNinja ..
ninja
Using Make (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 want to cross-compile then there is an example toolchain file for 32-bit
Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
this:
cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
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 `#include`s
the BoringSSL headers.
In order to serve environments where code-size is important as well as those
where performance is the overriding concern, `OPENSSL_SMALL` can be defined to
remove some code that is especially large.
### Building for Android
It's possible to build BoringSSL with the Android NDK using CMake. This has
been tested with version 10d of the NDK.
Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
directory. Clone https://github.com/taka-no-me/android-cmake into `util/`. Then
make a build directory as above and run CMake *twice* like this:
cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
-DANDROID_ABI=armeabi-v7a \
-DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
-DANDROID_NATIVE_API_LEVEL=16 \
-GNinja ..
Once you've run that twice, Ninja should produce Android-compatible binaries.
You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
binaries.
## Known Limitations on Windows
* 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.
## Embedded ARM
ARM, unlike Intel, does not have an instruction that allows applications to
discover the capabilities of the processor. Instead, the capability information
has to be provided by the operating system somehow.
BoringSSL will try to use `getauxval` to discover the capabilities and, failing
that, will probe for NEON support by executing a NEON instruction and handling
any illegal-instruction signal. But some environments don't support that sort
of thing and, for them, it's possible to configure the CPU capabilities
at compile time.
If you define `OPENSSL_STATIC_ARMCAP` then you can define any of the following
to enabling the corresponding ARM feature.
* `OPENSSL_STATIC_ARMCAP_NEON` or `__ARM_NEON__` (note that the latter is set by compilers when NEON support is enabled).
* `OPENSSL_STATIC_ARMCAP_AES`
* `OPENSSL_STATIC_ARMCAP_SHA1`
* `OPENSSL_STATIC_ARMCAP_SHA256`
* `OPENSSL_STATIC_ARMCAP_PMULL`
Note that if a feature is enabled in this way, but not actually supported at
run-time, BoringSSL will likely crash.
# Running tests
There are two sets of tests: the C/C++ tests and the blackbox tests. For former
are built by Ninja and can be run from the top-level directory with `go run
util/all_tests.go`. The latter have to be run separately by running `go test`
from within `ssl/test/runner`.
Both sets of tests may also be run with `ninja -C build run_tests`, but CMake
3.2 or later is required to avoid Ninja's output buffering.
+20 -156
View File
@@ -1,178 +1,42 @@
cmake_minimum_required (VERSION 2.8.10)
cmake_minimum_required (VERSION 2.8.8)
project (BoringSSL)
if(ANDROID)
# Android-NDK CMake files reconfigure the path and so Go and Perl won't be
# found. However, ninja will still find them in $PATH if we just name them.
set(PERL_EXECUTABLE "perl")
set(GO_EXECUTABLE "go")
else()
find_package(Perl REQUIRED)
find_program(GO_EXECUTABLE go)
endif()
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 -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wsign-compare -Wmissing-field-initializers -ggdb -std=c++0x -fvisibility=hidden")
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -std=c89")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x")
elseif(MSVC)
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.
"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
"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
"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()
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_XOPEN_SOURCE=700")
endif()
if(FUZZ)
if(!CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message("You need to build with Clang for fuzzing to work")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
link_directories(.)
# Disable warnings for implicit integer narrowing.
set(CMAKE_C_FLAGS "/wd4267")
set(CMAKE_CXX_FLAGS "/wd4267")
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")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv6")
set(ARCH "arm")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a")
set(ARCH "arm")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(ARCH "aarch64")
set(ARCH "arm")
else()
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
endif()
if (ANDROID AND ${ARCH} STREQUAL "arm")
# The Android-NDK CMake files somehow fail to set the -march flag for
# assembly files. Without this flag, the compiler believes that it's
# building for ARMv5.
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=${CMAKE_SYSTEM_PROCESSOR}")
endif()
if (${ARCH} STREQUAL "x86" AND APPLE)
# With CMake 2.8.x, ${CMAKE_SYSTEM_PROCESSOR} evalutes to i386 on OS X,
# but clang defaults to 64-bit builds on OS X unless otherwise told.
# Set ARCH to x86_64 so clang and CMake agree. This is fixed in CMake 3.
set(ARCH "x86_64")
endif()
if (OPENSSL_NO_ASM)
add_definitions(-DOPENSSL_NO_ASM)
set(ARCH "generic")
endif()
# Declare a dummy target to build all unit tests. Test targets should inject
# themselves as dependencies next to the target definition.
add_custom_target(all_tests)
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(ssl/test)
add_subdirectory(tool)
add_subdirectory(decrepit)
if(FUZZ)
add_subdirectory(fuzz)
endif()
if (NOT ${CMAKE_VERSION} VERSION_LESS "3.2")
# USES_TERMINAL is only available in CMake 3.2 or later.
set(MAYBE_USES_TERMINAL USES_TERMINAL)
endif()
add_custom_target(
run_tests
COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir
${CMAKE_BINARY_DIR}
COMMAND cd ssl/test/runner
COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS all_tests bssl_shim
${MAYBE_USES_TERMINAL})
-40
View File
@@ -1,40 +0,0 @@
# Fuzz testing
Modern fuzz testers are very effective and we wish to use them to ensure that no silly bugs creep into BoringSSL.
We primarily use Clang's [libFuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz testing and there are a number of fuzz testing functions in `fuzz/`. They are not built by default because they require libFuzzer at build time.
In order to build the fuzz tests you will need at least Clang 3.7. Pass `-DFUZZ=1` on the CMake command line to enable building BoringSSL with coverage and AddressSanitizer, and to build the fuzz test binaries. You'll probably need to set the `CC` and `CXX` environment variables too, like this:
```
CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 ..
```
In order for the fuzz tests to link, the linker needs to find libFuzzer. This is not commonly provided and you may need to download the [Clang source code](http://llvm.org/releases/download.html) and do the following:
```
cd llvm-3.7.0.src/lib
clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
ar q libFuzzer.a *.o
```
Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
From the `build/` directory, you can then run the fuzzers. For example:
```
./fuzz/cert -max_len=4000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
```
The `max_len` argument is often important because, without it, libFuzzer defaults to limiting all test cases to 64 bytes, which is often insufficient for the formats that we wish to fuzz. The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing.
There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
Here are the recommended values of `max_len` for each test.
| Test | `max_len` value |
|-----------|-----------------|
| `privkey` | 2048 |
| `cert` | 3072 |
| `server` | 1024 |
| `client` | 4096 |
-164
View File
@@ -1,164 +0,0 @@
# Porting from OpenSSL to BoringSSL
BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
subset of OpenSSL retained. Libraries ideally need little to no changes for
BoringSSL support, provided they do not use removed APIs. In general, see if the
library compiles and, on failure, consult the documentation in the header files
and see if problematic features can be removed.
In some cases, BoringSSL-specific code may be necessary. In that case, the
`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
should also be used in lieu of the presence of any particular function to detect
OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
corresponding to removed features. These may also be used to disable code which
uses a removed feature.
Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
consumers. It is not suitable for, say, a system library in a traditional Linux
distribution. For instance, Chromium statically links the specific revision of
BoringSSL it was built against. Likewise, Android's system-internal copy of
BoringSSL is not exposed by the NDK and must not be used by third-party
applications.
## Major API changes
### Integer types
Some APIs have been converted to use `size_t` for consistency and to avoid
integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
`long`, and `unsigned`.) For the most part, implicit casts mean that existing
code continues to compile. In some cases, this may require BoringSSL-specific
code, particularly to avoid compiler warnings.
Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
instead of `int` for indices and lengths.
### Reference counts
Some external consumers increment reference counts directly by calling
`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
These APIs no longer exist in BoringSSL. Instead, code which increments
reference counts should call the corresponding `FOO_up_ref` function, such as
`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
may require `#ifdef`s.
### Error codes
OpenSSL's errors are extremely specific, leaking internals of the library,
including even a function code for the function which emitted the error! As some
logic in BoringSSL has been rewritten, code which conditions on the error may
break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
when upgrading OpenSSL versions.
Where possible, avoid conditioning on the exact error reason. Otherwise, a
BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
still being determined. It's possible some new APIs will be added in the future.
Function codes have been completely removed. Remove code which conditions on
these as it will break with the slightest change in the library, OpenSSL or
BoringSSL.
### `*_ctrl` functions
Some OpenSSL APIs are implemented with `ioctl`-style functions such as
`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
# define SSL_CTX_set_mode(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
In BoringSSL, these macros have been replaced with proper functions. The
underlying `_ctrl` functions have been removed.
For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
existing code which uses them (or the wrapper macros) in `#ifdef` expressions
will continue to function. However, the macros themselves will not work.
Switch any `*_ctrl` callers to the macro/function versions. This works in both
OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
type-checked and may require more care with types.
### HMAC `EVP_PKEY`s
`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
is compatible with OpenSSL.
### DSA `EVP_PKEY`s
`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
### DES
The `DES_cblock` type has been switched from an array to a struct to avoid the
pitfalls around array types in C. Where features which require DES cannot be
disabled, BoringSSL-specific codepaths may be necessary.
### TLS renegotiation
OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
from the peer transparently. Renegotiation is an extremely problematic protocol
feature, so BoringSSL rejects peer renegotiations by default.
To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to
`ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only
supported as a client in SSL3/TLS and the HelloRequest must be received at a
quiet point in the application protocol. This is sufficient to support the
common use of requesting a new client certificate between an HTTP request and
response in (unpipelined) HTTP/1.1.
Things which do not work:
* There is no support for renegotiation as a server.
* There is no support for renegotiation in DTLS.
* There is no support for initiating renegotiation; `SSL_renegotiate` always
fails and `SSL_set_state` does nothing.
* Interleaving application data with the new handshake is forbidden.
* If a HelloRequest is received while `SSL_write` has unsent application data,
the renegotiation is rejected.
### Lowercase hexadecimal
BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
uppercase. Some code may require changes to avoid being sensitive to this
difference.
## Optional BoringSSL-specific simplifications
BoringSSL makes some changes to OpenSSL which simplify the API but remain
compatible with OpenSSL consumers. In general, consult the BoringSSL
documentation for any functions in new BoringSSL-only code.
### Return values
Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
code may take advantage of the less error-prone APIs and use `!` to check for
errors.
### Initialization
OpenSSL has a number of different initialization functions for setting up error
strings and loading algorithms, etc. All of these functions still exist in
BoringSSL for convenience, but they do nothing and are not necessary.
The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER`
builds, it must be called to query CPU capabitilies before the rest of the
library. In the default configuration, this is done with a static initializer
and is also unnecessary.
### Threading
OpenSSL provides a number of APIs to configure threading callbacks and set up
locks. Without initializing these, the library is not thread-safe. Configuring
these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
corresponding Windows APIs internally and is always thread-safe where the API
guarantees it.
-30
View File
@@ -1,30 +0,0 @@
# BoringSSL
BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
Although BoringSSL is an open source project, it is not intended for general
use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing
so is likely to be frustrating because there are no guarantees of API or ABI
stability.
Programs ship their own copies of BoringSSL when they use it and we update
everything as needed when deciding to make API changes. This allows us to
mostly avoid compromises in the name of compatibility. It works for us, but it
may not work for you.
BoringSSL arose because Google used OpenSSL for many years in various ways and,
over time, built up a large number of patches that were maintained while
tracking upstream OpenSSL. As Google's product portfolio became more complex,
more copies of OpenSSL sprung up and the effort involved in maintaining all
these patches in multiple places was growing steadily.
Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's
not part of the NDK) and a number of other apps/programs.
There are other files in this directory which might be helpful:
* [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
* [BUILDING.md](/BUILDING.md): how to build BoringSSL
* [STYLE.md](/STYLE.md): rules and guidelines for coding style.
* include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
* [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
-197
View File
@@ -1,197 +0,0 @@
# BoringSSL Style Guide
BoringSSL usually follows the
[Google C++ style guide](https://google.github.io/styleguide/cppguide.html),
The rest of this document describes differences and clarifications on
top of the base guide.
## 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 `#define`s,
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. All `TYPE_NAME_free`
functions must do nothing on `NULL` input.
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 `enum 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.
-4
View File
@@ -1,4 +0,0 @@
# This file is used by gcl to get repository specific information.
GERRIT_HOST: True
GERRIT_PORT: True
CODE_REVIEW_SERVER: https://boringssl-review.googlesource.com
+94 -159
View File
@@ -1,89 +1,67 @@
include_directories(../include)
include_directories(. ../include)
if(APPLE)
if (${ARCH} STREQUAL "x86")
set(PERLASM_FLAGS "-fPIC -DOPENSSL_IA32_SSE2")
endif()
set(PERLASM_STYLE macosx)
set(ASM_EXT S)
enable_language(ASM)
set(PERLASM_STYLE macosx)
set(ASM_EXT S)
enable_language(ASM)
elseif(UNIX)
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 "arm")
set(PERLASM_STYLE linux32)
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)
set(PERLASM_STYLE elf)
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)
set(PERLASM_FLAGS "-DOPENSSL_IA32_SSE2")
endif()
if (CMAKE_CL_64)
message("Using nasm")
set(PERLASM_STYLE nasm)
else()
message("Using win32n")
set(PERLASM_STYLE win32n)
endif()
# On Windows, we use the NASM output, specifically built with Yasm.
set(ASM_EXT asm)
enable_language(ASM_NASM)
# On Windows, we use the NASM output, specifically built with Yasm.
set(ASM_EXT asm)
enable_language(ASM_NASM)
endif()
function(perlasm dest src)
add_custom_command(
OUTPUT ${dest}
COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${PERLASM_STYLE} ${PERLASM_FLAGS} ${ARGN} > ${dest}
DEPENDS
${src}
${PROJECT_SOURCE_DIR}/crypto/perlasm/arm-xlate.pl
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86_64-xlate.pl
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86asm.pl
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86gas.pl
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86masm.pl
${PROJECT_SOURCE_DIR}/crypto/perlasm/x86nasm.pl
WORKING_DIRECTORY .
)
add_custom_command(
OUTPUT ${dest}
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${PERLASM_STYLE} ${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-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-intel.c
)
cpu-x86-asm.${ASM_EXT}
cpu-intel.c
)
endif()
if (${ARCH} STREQUAL "arm")
set(
CRYPTO_ARCH_SOURCES
set(
CRYPTO_ARCH_SOURCES
cpu-arm.c
cpu-arm-asm.S
)
endif()
if (${ARCH} STREQUAL "aarch64")
set(
CRYPTO_ARCH_SOURCES
cpu-arm.c
)
cpu-x86-asm.${ASM_EXT}
cpu-arm.c
)
endif()
# Level 0.1 - depends on nothing outside this set.
@@ -105,7 +83,6 @@ add_subdirectory(rc4)
add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
add_subdirectory(curve25519)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -127,9 +104,7 @@ add_subdirectory(ecdsa)
add_subdirectory(hmac)
# Level 3
add_subdirectory(cmac)
add_subdirectory(evp)
add_subdirectory(hkdf)
add_subdirectory(pem)
add_subdirectory(x509)
add_subdirectory(x509v3)
@@ -137,99 +112,59 @@ add_subdirectory(x509v3)
# Level 4
add_subdirectory(pkcs8)
# Test support code
add_subdirectory(test)
add_library(
crypto
crypto
STATIC
crypto.c
directory_posix.c
directory_win.c
ex_data.c
mem.c
refcount_c11.c
refcount_lock.c
thread.c
thread_none.c
thread_pthread.c
thread_win.c
time_support.c
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_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:curve25519>
$<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:cmac>
$<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:pem>
$<TARGET_OBJECTS:x509>
$<TARGET_OBJECTS:x509v3>
$<TARGET_OBJECTS:pkcs8>
)
if(NOT MSVC AND NOT ANDROID)
target_link_libraries(crypto pthread)
endif()
add_executable(
constant_time_test
constant_time_test.c
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(constant_time_test crypto)
add_dependencies(all_tests constant_time_test)
add_executable(
thread_test
thread_test.c
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(thread_test crypto)
add_dependencies(all_tests thread_test)
add_executable(
refcount_test
refcount_test.c
)
target_link_libraries(refcount_test crypto)
add_dependencies(all_tests refcount_test)
perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
+24 -44
View File
@@ -1,53 +1,44 @@
include_directories(../../include)
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}
aesv8-armx.${ASM_EXT}
)
endif()
if (${ARCH} STREQUAL "aarch64")
set(
AES_ARCH_SOURCES
aesv8-armx.${ASM_EXT}
)
aes-armv4.${ASM_EXT}
bsaes-armv7.${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)
@@ -59,14 +50,3 @@ 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)
add_executable(
aes_test
aes_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(aes_test crypto)
add_dependencies(all_tests aes_test)
+38 -77
View File
@@ -49,9 +49,6 @@
#include <openssl/aes.h>
#include <assert.h>
#include <stdlib.h>
#include <openssl/cpu.h>
#include "internal.h"
@@ -528,6 +525,32 @@ 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,
@@ -1036,68 +1059,22 @@ 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 = ((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];
s0 = (Td4[(t0 >> 24)] << 24) ^ (Td4[(t3 >> 16) & 0xff] << 16) ^
(Td4[(t2 >> 8) & 0xff] << 8) ^ (Td4[(t1) & 0xff]) ^ rk[0];
PUTU32(out, s0);
s1 = ((uint32_t)Td4[(t1 >> 24)] << 24) ^
((uint32_t)Td4[(t0 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t3 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t2) & 0xff]) ^ rk[1];
s1 = (Td4[(t1 >> 24)] << 24) ^ (Td4[(t0 >> 16) & 0xff] << 16) ^
(Td4[(t3 >> 8) & 0xff] << 8) ^ (Td4[(t2) & 0xff]) ^ rk[1];
PUTU32(out + 4, s1);
s2 = ((uint32_t)Td4[(t2 >> 24)] << 24) ^
((uint32_t)Td4[(t1 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t0 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t3) & 0xff]) ^ rk[2];
s2 = (Td4[(t2 >> 24)] << 24) ^ (Td4[(t1 >> 16) & 0xff] << 16) ^
(Td4[(t0 >> 8) & 0xff] << 8) ^ (Td4[(t3) & 0xff]) ^ rk[2];
PUTU32(out + 8, s2);
s3 = ((uint32_t)Td4[(t3 >> 24)] << 24) ^
((uint32_t)Td4[(t2 >> 16) & 0xff] << 16) ^
((uint32_t)Td4[(t1 >> 8) & 0xff] << 8) ^
((uint32_t)Td4[(t0) & 0xff]) ^ rk[3];
s3 = (Td4[(t3 >> 24)] << 24) ^ (Td4[(t2 >> 16) & 0xff] << 16) ^
(Td4[(t1 >> 8) & 0xff] << 8) ^ (Td4[(t0) & 0xff]) ^ rk[3];
PUTU32(out + 12, s3);
}
#else
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
static int hwaes_capable(void) {
return CRYPTO_is_ARMv8_AES_capable();
}
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);
#else
static int hwaes_capable(void) {
return 0;
}
static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
abort();
}
static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
abort();
}
static void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
#endif
/* In this case several functions are provided by asm code. However, one cannot
* control asm symbol visibility with command line flags and such so they are
* always hidden and wrapped by these C functions, which can be so
@@ -1105,38 +1082,22 @@ static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key)
void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
if (hwaes_capable()) {
aes_v8_encrypt(in, out, key);
} else {
asm_AES_encrypt(in, out, key);
}
asm_AES_encrypt(in, out, key);
}
void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
if (hwaes_capable()) {
aes_v8_decrypt(in, out, key);
} else {
asm_AES_decrypt(in, out, key);
}
asm_AES_decrypt(in, out, key);
}
int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
if (hwaes_capable()) {
return aes_v8_set_encrypt_key(key, bits, aeskey);
} else {
return asm_AES_set_encrypt_key(key, bits, aeskey);
}
return asm_AES_set_encrypt_key(key, bits, aeskey);
}
int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
if (hwaes_capable()) {
return aes_v8_set_decrypt_key(key, bits, aeskey);
} else {
return asm_AES_set_decrypt_key(key, bits, aeskey);
}
return asm_AES_set_decrypt_key(key, bits, aeskey);
}
#endif /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */
-102
View File
@@ -1,102 +0,0 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>
static bool TestAES(const uint8_t *key, size_t key_len,
const uint8_t plaintext[AES_BLOCK_SIZE],
const uint8_t ciphertext[AES_BLOCK_SIZE]) {
AES_KEY aes_key;
if (AES_set_encrypt_key(key, key_len * 8, &aes_key) != 0) {
fprintf(stderr, "AES_set_encrypt_key failed\n");
return false;
}
// Test encryption.
uint8_t block[AES_BLOCK_SIZE];
AES_encrypt(plaintext, block, &aes_key);
if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
fprintf(stderr, "AES_encrypt gave the wrong output\n");
return false;
}
// Test in-place encryption.
memcpy(block, plaintext, AES_BLOCK_SIZE);
AES_encrypt(block, block, &aes_key);
if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
fprintf(stderr, "AES_encrypt gave the wrong output\n");
return false;
}
if (AES_set_decrypt_key(key, key_len * 8, &aes_key) != 0) {
fprintf(stderr, "AES_set_decrypt_key failed\n");
return false;
}
// Test decryption.
AES_decrypt(ciphertext, block, &aes_key);
if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
fprintf(stderr, "AES_decrypt gave the wrong output\n");
return false;
}
// Test in-place decryption.
memcpy(block, ciphertext, AES_BLOCK_SIZE);
AES_decrypt(block, block, &aes_key);
if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
fprintf(stderr, "AES_decrypt gave the wrong output\n");
return false;
}
return true;
}
int main() {
CRYPTO_library_init();
// Test vectors from FIPS-197, Appendix C.
if (!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
128 / 8,
(const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
"\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
(const uint8_t *)"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
"\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a") ||
!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17",
192 / 8,
(const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
"\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
(const uint8_t *)"\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
"\x6e\xaf\x70\xa0\xec\x0d\x71\x91") ||
!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17"
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
256 / 8,
(const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
"\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
(const uint8_t *)"\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
"\xea\xfc\x49\x90\x4b\x49\x60\x89")) {
return false;
}
printf("PASS\n");
return 0;
}
+3 -3
View File
@@ -45,7 +45,7 @@
# the undertaken effort was that it appeared that in tight IA-32
# register window little-endian flavor could achieve slightly higher
# Instruction Level Parallelism, and it indeed resulted in up to 15%
# better performance on most recent µ-archs...
# better performance on most recent µ-archs...
#
# Third version adds AES_cbc_encrypt implementation, which resulted in
# up to 40% performance imrovement of CBC benchmark results. 40% was
@@ -224,7 +224,7 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
$speed_limit=512; # chunks smaller than $speed_limit are
# processed with compact routine in CBC mode
$small_footprint=1; # $small_footprint=1 code is ~5% slower [on
# recent µ-archs], but ~5 times smaller!
# recent µ-archs], but ~5 times smaller!
# I favor compact code to minimize cache
# contention and in hope to "collect" 5% back
# in real-life applications...
@@ -565,7 +565,7 @@ sub enctransform()
# Performance is not actually extraordinary in comparison to pure
# x86 code. In particular encrypt performance is virtually the same.
# Decrypt performance on the other hand is 15-20% better on newer
# µ-archs [but we're thankful for *any* improvement here], and ~50%
# µ-archs [but we're thankful for *any* improvement here], and ~50%
# better on PIII:-) And additionally on the pros side this code
# eliminates redundant references to stack and thus relieves/
# minimizes the pressure on the memory bus.
+10 -35
View File
@@ -32,20 +32,8 @@
# Profiler-assisted and platform-specific optimization resulted in 16%
# improvement on Cortex A8 core and ~21.5 cycles per byte.
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$s0="r0";
$s1="r1";
@@ -65,7 +53,7 @@ $rounds="r12";
$code=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
# include <openssl/arm_arch.h>
# include "arm_arch.h"
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
#endif
@@ -75,7 +63,7 @@ $code=<<___;
.code 32
#else
.syntax unified
# if defined(__thumb2__) && !defined(__APPLE__)
# ifdef __thumb2__
.thumb
# else
.code 32
@@ -201,13 +189,9 @@ asm_AES_encrypt:
adr r3,asm_AES_encrypt
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
adr $tbl,AES_Te
#else
sub $tbl,r3,#asm_AES_encrypt-AES_Te @ Te
#endif
mov $rounds,r0 @ inp
mov $key,r2
sub $tbl,r3,#asm_AES_encrypt-AES_Te @ Te
#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
@@ -476,16 +460,12 @@ _armv4_AES_set_encrypt_key:
bne .Labrt
.Lok: stmdb sp!,{r4-r12,lr}
sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
mov $rounds,r0 @ inp
mov lr,r1 @ bits
mov $key,r2 @ key
#ifdef __APPLE__
adr $tbl,AES_Te+1024 @ Te4
#else
sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
#endif
#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
@@ -738,8 +718,8 @@ _armv4_AES_set_encrypt_key:
.Ldone: mov r0,#0
ldmia sp!,{r4-r12,lr}
.Labrt:
#if __ARM_ARCH__>=5
ret @ bx lr
#if defined(__thumb2__) && __ARM_ARCH__>=7
.short 0x4770 @ bx lr in Thumb2 encoding
#else
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
@@ -981,13 +961,9 @@ asm_AES_decrypt:
adr r3,asm_AES_decrypt
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
adr $tbl,AES_Td
#else
sub $tbl,r3,#asm_AES_decrypt-AES_Td @ Td
#endif
mov $rounds,r0 @ inp
mov $key,r2
sub $tbl,r3,#asm_AES_decrypt-AES_Td @ Td
#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
@@ -1235,7 +1211,6 @@ _armv4_AES_decrypt:
___
$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
$code =~ s/\bret\b/bx\tlr/gm;
open SELF,$0;
while(<SELF>) {
+14 -307
View File
@@ -51,7 +51,7 @@
# Westmere 3.77/1.37 1.37 1.52 1.27
# * Bridge 5.07/0.98 0.99 1.09 0.91
# Haswell 4.44/0.80 0.97 1.03 0.72
# Silvermont 5.77/3.56 3.67 4.03 3.46
# Atom 5.77/3.56 3.67 4.03 3.46
# Bulldozer 5.80/0.98 1.05 1.24 0.93
$PREFIX="aesni"; # if $PREFIX is set to "AES", the script
@@ -65,9 +65,6 @@ require "x86asm.pl";
&asm_init($ARGV[0],$0);
&external_label("OPENSSL_ia32cap_P");
&static_label("key_const");
if ($PREFIX eq "aesni") { $movekey=\&movups; }
else { $movekey=\&movups; }
@@ -88,7 +85,7 @@ $inout3="xmm5"; $in1="xmm5";
$inout4="xmm6"; $in0="xmm6";
$inout5="xmm7"; $ivec="xmm7";
# AESNI extension
# AESNI extenstion
sub aeskeygenassist
{ my($dst,$src,$imm)=@_;
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
@@ -184,10 +181,7 @@ sub aesni_generate1 # fully unrolled loop
{ &aesni_inline_generate1("enc"); }
else
{ &call ("_aesni_encrypt1"); }
&pxor ($rndkey0,$rndkey0); # clear register bank
&pxor ($rndkey1,$rndkey1);
&movups (&QWP(0,"eax"),$inout0);
&pxor ($inout0,$inout0);
&ret ();
&function_end_B("${PREFIX}_encrypt");
@@ -203,10 +197,7 @@ sub aesni_generate1 # fully unrolled loop
{ &aesni_inline_generate1("dec"); }
else
{ &call ("_aesni_decrypt1"); }
&pxor ($rndkey0,$rndkey0); # clear register bank
&pxor ($rndkey1,$rndkey1);
&movups (&QWP(0,"eax"),$inout0);
&pxor ($inout0,$inout0);
&ret ();
&function_end_B("${PREFIX}_decrypt");
@@ -358,15 +349,17 @@ sub aesni_generate6
&neg ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
&pxor ($inout5,$rndkey0);
&$movekey ($rndkey0,&QWP(0,$key,$rounds));
&add ($rounds,16);
&jmp (&label("_aesni_${p}rypt6_inner"));
eval"&aes${p} ($inout3,$rndkey1)";
eval"&aes${p} ($inout4,$rndkey1)";
eval"&aes${p} ($inout5,$rndkey1)";
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jmp (&label("_aesni_${p}rypt6_enter"));
&set_label("${p}6_loop",16);
eval"&aes${p} ($inout0,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
eval"&aes${p} ($inout2,$rndkey1)";
&set_label("_aesni_${p}rypt6_inner");
eval"&aes${p} ($inout3,$rndkey1)";
eval"&aes${p} ($inout4,$rndkey1)";
eval"&aes${p} ($inout5,$rndkey1)";
@@ -622,14 +615,6 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0x30,$out),$inout3);
&set_label("ecb_ret");
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&pxor ("xmm3","xmm3");
&pxor ("xmm4","xmm4");
&pxor ("xmm5","xmm5");
&pxor ("xmm6","xmm6");
&pxor ("xmm7","xmm7");
&function_end("aesni_ecb_encrypt");
######################################################################
@@ -719,15 +704,6 @@ if ($PREFIX eq "aesni") {
&mov ("esp",&DWP(48,"esp"));
&mov ($out,&wparam(5));
&movups (&QWP(0,$out),$cmac);
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&pxor ("xmm3","xmm3");
&pxor ("xmm4","xmm4");
&pxor ("xmm5","xmm5");
&pxor ("xmm6","xmm6");
&pxor ("xmm7","xmm7");
&function_end("aesni_ccm64_encrypt_blocks");
&function_begin("aesni_ccm64_decrypt_blocks");
@@ -828,15 +804,6 @@ if ($PREFIX eq "aesni") {
&mov ("esp",&DWP(48,"esp"));
&mov ($out,&wparam(5));
&movups (&QWP(0,$out),$cmac);
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&pxor ("xmm3","xmm3");
&pxor ("xmm4","xmm4");
&pxor ("xmm5","xmm5");
&pxor ("xmm6","xmm6");
&pxor ("xmm7","xmm7");
&function_end("aesni_ccm64_decrypt_blocks");
}
@@ -1086,17 +1053,6 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0x30,$out),$inout3);
&set_label("ctr32_ret");
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&pxor ("xmm3","xmm3");
&pxor ("xmm4","xmm4");
&movdqa (&QWP(32,"esp"),"xmm0"); # clear stack
&pxor ("xmm5","xmm5");
&movdqa (&QWP(48,"esp"),"xmm0");
&pxor ("xmm6","xmm6");
&movdqa (&QWP(64,"esp"),"xmm0");
&pxor ("xmm7","xmm7");
&mov ("esp",&DWP(80,"esp"));
&function_end("aesni_ctr32_encrypt_blocks");
@@ -1438,20 +1394,6 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(-16,$out),$inout0); # write output
&set_label("xts_enc_ret");
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&movdqa (&QWP(16*0,"esp"),"xmm0"); # clear stack
&pxor ("xmm3","xmm3");
&movdqa (&QWP(16*1,"esp"),"xmm0");
&pxor ("xmm4","xmm4");
&movdqa (&QWP(16*2,"esp"),"xmm0");
&pxor ("xmm5","xmm5");
&movdqa (&QWP(16*3,"esp"),"xmm0");
&pxor ("xmm6","xmm6");
&movdqa (&QWP(16*4,"esp"),"xmm0");
&pxor ("xmm7","xmm7");
&movdqa (&QWP(16*5,"esp"),"xmm0");
&mov ("esp",&DWP(16*7+4,"esp")); # restore %esp
&function_end("aesni_xts_encrypt");
@@ -1814,20 +1756,6 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0,$out),$inout0); # write output
&set_label("xts_dec_ret");
&pxor ("xmm0","xmm0"); # clear register bank
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&movdqa (&QWP(16*0,"esp"),"xmm0"); # clear stack
&pxor ("xmm3","xmm3");
&movdqa (&QWP(16*1,"esp"),"xmm0");
&pxor ("xmm4","xmm4");
&movdqa (&QWP(16*2,"esp"),"xmm0");
&pxor ("xmm5","xmm5");
&movdqa (&QWP(16*3,"esp"),"xmm0");
&pxor ("xmm6","xmm6");
&movdqa (&QWP(16*4,"esp"),"xmm0");
&pxor ("xmm7","xmm7");
&movdqa (&QWP(16*5,"esp"),"xmm0");
&mov ("esp",&DWP(16*7+4,"esp")); # restore %esp
&function_end("aesni_xts_decrypt");
}
@@ -1880,7 +1808,6 @@ if ($PREFIX eq "aesni") {
&add ($len,16);
&jnz (&label("cbc_enc_tail"));
&movaps ($ivec,$inout0);
&pxor ($inout0,$inout0);
&jmp (&label("cbc_ret"));
&set_label("cbc_enc_tail");
@@ -1944,7 +1871,7 @@ if ($PREFIX eq "aesni") {
&movaps ($inout0,$inout5);
&movaps ($ivec,$rndkey0);
&add ($len,0x50);
&jle (&label("cbc_dec_clear_tail_collected"));
&jle (&label("cbc_dec_tail_collected"));
&movups (&QWP(0,$out),$inout0);
&lea ($out,&DWP(0x10,$out));
&set_label("cbc_dec_tail");
@@ -1983,14 +1910,10 @@ if ($PREFIX eq "aesni") {
&xorps ($inout4,$rndkey0);
&movups (&QWP(0,$out),$inout0);
&movups (&QWP(0x10,$out),$inout1);
&pxor ($inout1,$inout1);
&movups (&QWP(0x20,$out),$inout2);
&pxor ($inout2,$inout2);
&movups (&QWP(0x30,$out),$inout3);
&pxor ($inout3,$inout3);
&lea ($out,&DWP(0x40,$out));
&movaps ($inout0,$inout4);
&pxor ($inout4,$inout4);
&sub ($len,0x50);
&jmp (&label("cbc_dec_tail_collected"));
@@ -2010,7 +1933,6 @@ if ($PREFIX eq "aesni") {
&xorps ($inout1,$in0);
&movups (&QWP(0,$out),$inout0);
&movaps ($inout0,$inout1);
&pxor ($inout1,$inout1);
&lea ($out,&DWP(0x10,$out));
&movaps ($ivec,$in1);
&sub ($len,0x20);
@@ -2023,9 +1945,7 @@ if ($PREFIX eq "aesni") {
&xorps ($inout2,$in1);
&movups (&QWP(0,$out),$inout0);
&movaps ($inout0,$inout2);
&pxor ($inout2,$inout2);
&movups (&QWP(0x10,$out),$inout1);
&pxor ($inout1,$inout1);
&lea ($out,&DWP(0x20,$out));
&movups ($ivec,&QWP(0x20,$inp));
&sub ($len,0x30);
@@ -2041,44 +1961,29 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0,$out),$inout0);
&xorps ($inout2,$rndkey1);
&movups (&QWP(0x10,$out),$inout1);
&pxor ($inout1,$inout1);
&xorps ($inout3,$rndkey0);
&movups (&QWP(0x20,$out),$inout2);
&pxor ($inout2,$inout2);
&lea ($out,&DWP(0x30,$out));
&movaps ($inout0,$inout3);
&pxor ($inout3,$inout3);
&sub ($len,0x40);
&jmp (&label("cbc_dec_tail_collected"));
&set_label("cbc_dec_clear_tail_collected",16);
&pxor ($inout1,$inout1);
&pxor ($inout2,$inout2);
&pxor ($inout3,$inout3);
&pxor ($inout4,$inout4);
&set_label("cbc_dec_tail_collected");
&and ($len,15);
&jnz (&label("cbc_dec_tail_partial"));
&movups (&QWP(0,$out),$inout0);
&pxor ($rndkey0,$rndkey0);
&jmp (&label("cbc_ret"));
&set_label("cbc_dec_tail_partial",16);
&movaps (&QWP(0,"esp"),$inout0);
&pxor ($rndkey0,$rndkey0);
&mov ("ecx",16);
&mov ($inp,"esp");
&sub ("ecx",$len);
&data_word(0xA4F3F689); # rep movsb
&movdqa (&QWP(0,"esp"),$inout0);
&set_label("cbc_ret");
&mov ("esp",&DWP(16,"esp")); # pull original %esp
&mov ($key_,&wparam(4));
&pxor ($inout0,$inout0);
&pxor ($rndkey1,$rndkey1);
&movups (&QWP(0,$key_),$ivec); # output IV
&pxor ($ivec,$ivec);
&set_label("cbc_abort");
&function_end("${PREFIX}_cbc_encrypt");
@@ -2095,24 +2000,14 @@ if ($PREFIX eq "aesni") {
# $round rounds
&function_begin_B("_aesni_set_encrypt_key");
&push ("ebp");
&push ("ebx");
&test ("eax","eax");
&jz (&label("bad_pointer"));
&test ($key,$key);
&jz (&label("bad_pointer"));
&call (&label("pic"));
&set_label("pic");
&blindpop("ebx");
&lea ("ebx",&DWP(&label("key_const")."-".&label("pic"),"ebx"));
&picmeup("ebp","OPENSSL_ia32cap_P","ebx",&label("key_const"));
&movups ("xmm0",&QWP(0,"eax")); # pull first 128 bits of *userKey
&xorps ("xmm4","xmm4"); # low dword of xmm4 is assumed 0
&mov ("ebp",&DWP(4,"ebp"));
&lea ($key,&DWP(16,$key));
&and ("ebp",1<<28|1<<11); # AVX and XOP bits
&cmp ($rounds,256);
&je (&label("14rounds"));
&cmp ($rounds,192);
@@ -2121,9 +2016,6 @@ if ($PREFIX eq "aesni") {
&jne (&label("bad_keybits"));
&set_label("10rounds",16);
&cmp ("ebp",1<<28);
&je (&label("10rounds_alt"));
&mov ($rounds,9);
&$movekey (&QWP(-16,$key),"xmm0"); # round 0
&aeskeygenassist("xmm1","xmm0",0x01); # round 1
@@ -2148,8 +2040,8 @@ if ($PREFIX eq "aesni") {
&call (&label("key_128"));
&$movekey (&QWP(0,$key),"xmm0");
&mov (&DWP(80,$key),$rounds);
&jmp (&label("good_key"));
&xor ("eax","eax");
&ret();
&set_label("key_128",16);
&$movekey (&QWP(0,$key),"xmm0");
@@ -2163,76 +2055,8 @@ if ($PREFIX eq "aesni") {
&xorps ("xmm0","xmm1");
&ret();
&set_label("10rounds_alt",16);
&movdqa ("xmm5",&QWP(0x00,"ebx"));
&mov ($rounds,8);
&movdqa ("xmm4",&QWP(0x20,"ebx"));
&movdqa ("xmm2","xmm0");
&movdqu (&QWP(-16,$key),"xmm0");
&set_label("loop_key128");
&pshufb ("xmm0","xmm5");
&aesenclast ("xmm0","xmm4");
&pslld ("xmm4",1);
&lea ($key,&DWP(16,$key));
&movdqa ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm2","xmm3");
&pxor ("xmm0","xmm2");
&movdqu (&QWP(-16,$key),"xmm0");
&movdqa ("xmm2","xmm0");
&dec ($rounds);
&jnz (&label("loop_key128"));
&movdqa ("xmm4",&QWP(0x30,"ebx"));
&pshufb ("xmm0","xmm5");
&aesenclast ("xmm0","xmm4");
&pslld ("xmm4",1);
&movdqa ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm2","xmm3");
&pxor ("xmm0","xmm2");
&movdqu (&QWP(0,$key),"xmm0");
&movdqa ("xmm2","xmm0");
&pshufb ("xmm0","xmm5");
&aesenclast ("xmm0","xmm4");
&movdqa ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm3","xmm2");
&pslldq ("xmm2",4);
&pxor ("xmm2","xmm3");
&pxor ("xmm0","xmm2");
&movdqu (&QWP(16,$key),"xmm0");
&mov ($rounds,9);
&mov (&DWP(96,$key),$rounds);
&jmp (&label("good_key"));
&set_label("12rounds",16);
&movq ("xmm2",&QWP(16,"eax")); # remaining 1/3 of *userKey
&cmp ("ebp",1<<28);
&je (&label("12rounds_alt"));
&mov ($rounds,11);
&$movekey (&QWP(-16,$key),"xmm0"); # round 0
&aeskeygenassist("xmm1","xmm2",0x01); # round 1,2
@@ -2253,8 +2077,8 @@ if ($PREFIX eq "aesni") {
&call (&label("key_192b"));
&$movekey (&QWP(0,$key),"xmm0");
&mov (&DWP(48,$key),$rounds);
&jmp (&label("good_key"));
&xor ("eax","eax");
&ret();
&set_label("key_192a",16);
&$movekey (&QWP(0,$key),"xmm0");
@@ -2284,52 +2108,10 @@ if ($PREFIX eq "aesni") {
&lea ($key,&DWP(32,$key));
&jmp (&label("key_192b_warm"));
&set_label("12rounds_alt",16);
&movdqa ("xmm5",&QWP(0x10,"ebx"));
&movdqa ("xmm4",&QWP(0x20,"ebx"));
&mov ($rounds,8);
&movdqu (&QWP(-16,$key),"xmm0");
&set_label("loop_key192");
&movq (&QWP(0,$key),"xmm2");
&movdqa ("xmm1","xmm2");
&pshufb ("xmm2","xmm5");
&aesenclast ("xmm2","xmm4");
&pslld ("xmm4",1);
&lea ($key,&DWP(24,$key));
&movdqa ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm0","xmm3");
&pshufd ("xmm3","xmm0",0xff);
&pxor ("xmm3","xmm1");
&pslldq ("xmm1",4);
&pxor ("xmm3","xmm1");
&pxor ("xmm0","xmm2");
&pxor ("xmm2","xmm3");
&movdqu (&QWP(-16,$key),"xmm0");
&dec ($rounds);
&jnz (&label("loop_key192"));
&mov ($rounds,11);
&mov (&DWP(32,$key),$rounds);
&jmp (&label("good_key"));
&set_label("14rounds",16);
&movups ("xmm2",&QWP(16,"eax")); # remaining half of *userKey
&lea ($key,&DWP(16,$key));
&cmp ("ebp",1<<28);
&je (&label("14rounds_alt"));
&mov ($rounds,13);
&lea ($key,&DWP(16,$key));
&$movekey (&QWP(-32,$key),"xmm0"); # round 0
&$movekey (&QWP(-16,$key),"xmm2"); # round 1
&aeskeygenassist("xmm1","xmm2",0x01); # round 2
@@ -2361,8 +2143,7 @@ if ($PREFIX eq "aesni") {
&$movekey (&QWP(0,$key),"xmm0");
&mov (&DWP(16,$key),$rounds);
&xor ("eax","eax");
&jmp (&label("good_key"));
&ret();
&set_label("key_256a",16);
&$movekey (&QWP(0,$key),"xmm2");
@@ -2388,77 +2169,11 @@ if ($PREFIX eq "aesni") {
&xorps ("xmm2","xmm1");
&ret();
&set_label("14rounds_alt",16);
&movdqa ("xmm5",&QWP(0x00,"ebx"));
&movdqa ("xmm4",&QWP(0x20,"ebx"));
&mov ($rounds,7);
&movdqu (&QWP(-32,$key),"xmm0");
&movdqa ("xmm1","xmm2");
&movdqu (&QWP(-16,$key),"xmm2");
&set_label("loop_key256");
&pshufb ("xmm2","xmm5");
&aesenclast ("xmm2","xmm4");
&movdqa ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm3","xmm0");
&pslldq ("xmm0",4);
&pxor ("xmm0","xmm3");
&pslld ("xmm4",1);
&pxor ("xmm0","xmm2");
&movdqu (&QWP(0,$key),"xmm0");
&dec ($rounds);
&jz (&label("done_key256"));
&pshufd ("xmm2","xmm0",0xff);
&pxor ("xmm3","xmm3");
&aesenclast ("xmm2","xmm3");
&movdqa ("xmm3","xmm1")
&pslldq ("xmm1",4);
&pxor ("xmm3","xmm1");
&pslldq ("xmm1",4);
&pxor ("xmm3","xmm1");
&pslldq ("xmm1",4);
&pxor ("xmm1","xmm3");
&pxor ("xmm2","xmm1");
&movdqu (&QWP(16,$key),"xmm2");
&lea ($key,&DWP(32,$key));
&movdqa ("xmm1","xmm2");
&jmp (&label("loop_key256"));
&set_label("done_key256");
&mov ($rounds,13);
&mov (&DWP(16,$key),$rounds);
&set_label("good_key");
&pxor ("xmm0","xmm0");
&pxor ("xmm1","xmm1");
&pxor ("xmm2","xmm2");
&pxor ("xmm3","xmm3");
&pxor ("xmm4","xmm4");
&pxor ("xmm5","xmm5");
&xor ("eax","eax");
&pop ("ebx");
&pop ("ebp");
&ret ();
&set_label("bad_pointer",4);
&mov ("eax",-1);
&pop ("ebx");
&pop ("ebp");
&ret ();
&set_label("bad_keybits",4);
&pxor ("xmm0","xmm0");
&mov ("eax",-2);
&pop ("ebx");
&pop ("ebp");
&ret ();
&function_end_B("_aesni_set_encrypt_key");
@@ -2508,18 +2223,10 @@ if ($PREFIX eq "aesni") {
&aesimc ("xmm0","xmm0");
&$movekey (&QWP(0,$key),"xmm0");
&pxor ("xmm0","xmm0");
&pxor ("xmm1","xmm1");
&xor ("eax","eax"); # return success
&set_label("dec_key_ret");
&ret ();
&function_end_B("${PREFIX}_set_decrypt_key");
&set_label("key_const",64);
&data_word(0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d);
&data_word(0x04070605,0x04070605,0x04070605,0x04070605);
&data_word(1,1,1,1);
&data_word(0x1b,0x1b,0x1b,0x1b);
&asciz("AES for Intel AES-NI, CRYPTOGAMS by <appro\@openssl.org>");
&asm_finish();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+11 -47
View File
@@ -47,20 +47,8 @@
#
# <ard.biesheuvel@linaro.org>
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
my @XMM=map("q$_",(0..15));
@@ -701,8 +689,9 @@ ___
}
$code.=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
# include <openssl/arm_arch.h>
# include "arm_arch.h"
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
@@ -714,35 +703,29 @@ $code.=<<___;
# define BSAES_ASM_EXTENDED_KEY
# define XTS_CHAIN_TWEAK
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
# define __ARM_MAX_ARCH__ 7
#endif
#ifdef __thumb__
# define adrl adr
#endif
#if __ARM_MAX_ARCH__>=7
.arch armv7-a
.fpu neon
#if __ARM_ARCH__>=7
.text
.syntax unified @ ARMv7-capable assembler is expected to handle this
#if defined(__thumb2__) && !defined(__APPLE__)
#ifdef __thumb2__
.thumb
#else
.code 32
#endif
.fpu neon
.type _bsaes_decrypt8,%function
.align 4
_bsaes_decrypt8:
adr $const,_bsaes_decrypt8
vldmia $key!, {@XMM[9]} @ round 0 key
#ifdef __APPLE__
adr $const,.LM0ISR
#else
add $const,$const,#.LM0ISR-_bsaes_decrypt8
#endif
vldmia $const!, {@XMM[8]} @ .LM0ISR
veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key
@@ -837,11 +820,7 @@ _bsaes_const:
_bsaes_encrypt8:
adr $const,_bsaes_encrypt8
vldmia $key!, {@XMM[9]} @ round 0 key
#ifdef __APPLE__
adr $const,.LM0SR
#else
sub $const,$const,#_bsaes_encrypt8-.LM0SR
#endif
vldmia $const!, {@XMM[8]} @ .LM0SR
_bsaes_encrypt8_alt:
@@ -945,11 +924,7 @@ $code.=<<___;
_bsaes_key_convert:
adr $const,_bsaes_key_convert
vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key
#ifdef __APPLE__
adr $const,.LM0
#else
sub $const,$const,#_bsaes_key_convert-.LM0
#endif
vld1.8 {@XMM[15]}, [$inp]! @ load round 1 key
vmov.i8 @XMM[8], #0x01 @ bit masks
@@ -1422,12 +1397,7 @@ bsaes_ctr32_encrypt_blocks:
vstmia r12, {@XMM[7]} @ save last round key
vld1.8 {@XMM[0]}, [$ctr] @ load counter
#ifdef __APPLE__
mov $ctr, #:lower16:(.LREVM0SR-.LM0)
add $ctr, $const, $ctr
#else
add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr
#endif
vldmia $keysched, {@XMM[4]} @ load round0 key
#else
ldr r12, [$key, #244]
@@ -1484,12 +1454,7 @@ bsaes_ctr32_encrypt_blocks:
vldmia $ctr, {@XMM[8]} @ .LREVM0SR
mov r5, $rounds @ pass rounds
vstmia $fp, {@XMM[10]} @ save next counter
#ifdef __APPLE__
mov $const, #:lower16:(.LREVM0SR-.LSR)
sub $const, $ctr, $const
#else
sub $const, $ctr, #.LREVM0SR-.LSR @ pass constants
#endif
bl _bsaes_encrypt8_alt
@@ -1590,7 +1555,7 @@ bsaes_ctr32_encrypt_blocks:
rev r8, r8
#endif
sub sp, sp, #0x10
vst1.8 {@XMM[1]}, [sp] @ copy counter value
vst1.8 {@XMM[1]}, [sp,:64] @ copy counter value
sub sp, sp, #0x10
.Lctr_enc_short_loop:
@@ -1601,7 +1566,7 @@ bsaes_ctr32_encrypt_blocks:
bl AES_encrypt
vld1.8 {@XMM[0]}, [r4]! @ load input
vld1.8 {@XMM[1]}, [sp] @ load encrypted counter
vld1.8 {@XMM[1]}, [sp,:64] @ load encrypted counter
add r8, r8, #1
#ifdef __ARMEL__
rev r0, r8
@@ -2120,11 +2085,9 @@ bsaes_xts_decrypt:
vld1.8 {@XMM[8]}, [r0] @ initial tweak
adr $magic, .Lxts_magic
#ifndef XTS_CHAIN_TWEAK
tst $len, #0xf @ if not multiple of 16
it ne @ Thumb2 thing, sanity check in ARM
subne $len, #0x10 @ subtract another 16 bytes
#endif
subs $len, #0x80
blo .Lxts_dec_short
@@ -2496,6 +2459,7 @@ ___
}
$code.=<<___;
#endif
#endif
___
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-2
View File
@@ -40,7 +40,6 @@
# Core 2 9.30 8.69 +7%
# Nehalem(**) 7.63 6.88 +11%
# Atom 17.1 16.4 +4%
# Silvermont - 12.9
#
# (*) Comparison is not completely fair, because "this" is ECB,
# i.e. no extra processing such as counter values calculation
@@ -79,7 +78,6 @@
# Core 2 9.98
# Nehalem 7.80
# Atom 17.9
# Silvermont 14.0
#
# November 2011.
#
-1
View File
@@ -30,7 +30,6 @@
# Core 2(**) 28.1/41.4/18.3 21.9/25.2(***)
# Nehalem 27.9/40.4/18.1 10.2/11.9
# Atom 70.7/92.1/60.1 61.1/75.4(***)
# Silvermont 45.4/62.9/24.1 49.2/61.1(***)
#
# (*) "Hyper-threading" in the context refers rather to cache shared
# among multiple cores, than to specifically Intel HTT. As vast
-1
View File
@@ -30,7 +30,6 @@
# Core 2(**) 29.6/41.1/14.3 21.9/25.2(***)
# Nehalem 29.6/40.3/14.6 10.0/11.8
# Atom 57.3/74.2/32.1 60.9/77.2(***)
# Silvermont 52.7/64.0/19.5 48.8/60.8(***)
#
# (*) "Hyper-threading" in the context refers rather to cache shared
# among multiple cores, than to specifically Intel HTT. As vast
+2 -2
View File
@@ -48,9 +48,9 @@
#include <openssl/aes.h>
#include <assert.h>
#include "assert.h"
#include "../modes/internal.h"
#include <openssl/modes.h>
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
@@ -62,22 +62,11 @@
# 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. */
# 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__) || \
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH__ 7
@@ -98,9 +87,12 @@
# 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
* is easy for assembly code to acesss. For C code, see the functions in
* |cpu.h|. */
extern uint32_t OPENSSL_armcap_P;
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
#define ARMV7_NEON (1 << 0)
@@ -109,19 +101,9 @@
* 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 << 10)
#define ARMV7_NEON_FUNCTIONAL (1 << 1)
/* 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 /* !__ASSEMBLER__ */
#endif /* OPENSSL_HEADER_ARM_ARCH_H */
#endif /* OPENSSL_HEADER_THREAD_H */
+41 -51
View File
@@ -1,56 +1,46 @@
include_directories(../../include)
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_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_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
)
add_executable(
asn1_test
asn1_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(asn1_test crypto)
add_dependencies(all_tests asn1_test)
+8 -16
View File
@@ -56,12 +56,9 @@
#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); }
@@ -121,11 +118,11 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
ASN1_BIT_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
int padding;
int i;
if (len < 1)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
i=ASN1_R_STRING_TOO_SHORT;
goto err;
}
@@ -137,29 +134,23 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
ret=(*a);
p= *pp;
padding = *(p++);
if (padding > 7)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
i= *(p++);
/* 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|padding); /* set */
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
s=(unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
i=ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s,p,(int)len);
s[len-1]&=(0xff<<padding);
s[len-1]&=(0xff<<i);
p+=len;
}
else
@@ -173,6 +164,7 @@ 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);
@@ -206,7 +198,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
w+1);
if (c == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_BIT_STRING_set_bit, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
+1 -1
View File
@@ -107,6 +107,6 @@ int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_BOOLEAN, i);
return(ret);
}
+3 -5
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -125,7 +123,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return(NULL);
@@ -243,7 +241,7 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_bytes, i);
return(NULL);
}
@@ -309,7 +307,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
if (os != NULL) ASN1_STRING_free(os);
return(1);
err:
OPENSSL_PUT_ERROR(ASN1, c->error);
OPENSSL_PUT_ERROR(ASN1, asn1_collate_primitive, c->error);
if (os != NULL) ASN1_STRING_free(os);
if (b.data != NULL) OPENSSL_free(b.data);
return(0);
+13 -13
View File
@@ -75,7 +75,7 @@ void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_d2i_fp, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -129,7 +129,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_d2i_fp, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -154,7 +154,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
b=BUF_MEM_new();
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
return -1;
}
@@ -167,20 +167,20 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
{
if (len+i < len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
goto err;
}
len+=i;
@@ -194,7 +194,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
len-off);
if (c.inf & 0x80)
{
uint32_t e;
unsigned long e;
e=ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
@@ -211,7 +211,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
eos++;
if (eos < 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE;
@@ -235,12 +235,12 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0)
@@ -248,7 +248,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
i=BIO_read(in,&(b->data[len]),want);
if (i <= 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/* This can't overflow because
@@ -259,7 +259,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
}
if (off + c.slen < off)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
@@ -274,7 +274,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (off > INT_MAX)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
goto err;
}
+2 -2
View File
@@ -72,7 +72,7 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
i=i2d(x,NULL);
b=OPENSSL_malloc(i+10);
if (b == NULL)
{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
{ OPENSSL_PUT_ERROR(ASN1, ASN1_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
i=i2d(x,&p);
p2= b;
@@ -95,7 +95,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
{ OPENSSL_PUT_ERROR(ASN1, ASN1_item_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
OPENSSL_free(b);
+4 -6
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -84,7 +82,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
}
if (a->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_set, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -147,7 +145,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
ret=ai;
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
@@ -159,7 +157,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -177,7 +175,7 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_to_BN, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
}
+1 -4
View File
@@ -56,9 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <time.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/time_support.h>
@@ -239,7 +236,7 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
p=OPENSSL_malloc(len);
if (p == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_GENERALIZEDTIME_adj, ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
+5 -5
View File
@@ -67,7 +67,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_fp, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -76,7 +76,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
return(ret);
}
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
{
char *b;
unsigned char *p;
@@ -86,7 +86,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
b=(char *)OPENSSL_malloc(n);
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_bio, ERR_R_MALLOC_FAILURE);
return(0);
}
@@ -116,7 +116,7 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_fp, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -133,7 +133,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
n = ASN1_item_i2d(x, &b, it);
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_bio, ERR_R_MALLOC_FAILURE);
return(0);
}
+8 -12
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -125,8 +123,6 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
ret=a->length;
i=a->data[0];
if (ret == 1 && i == 0)
neg = 0;
if (!neg && (i > 127)) {
pad=1;
pb=0;
@@ -160,7 +156,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while(!*n && i > 1) {
while(!*n) {
*(p--) = 0;
n--;
i--;
@@ -259,7 +255,7 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=pend;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_INTEGER, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -329,7 +325,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_UINTEGER, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -352,7 +348,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
}
if (a->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_set, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -415,10 +411,10 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
ret=ai;
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn) && !BN_is_zero(bn))
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_INTEGER;
else ret->type=V_ASN1_INTEGER;
j=BN_num_bits(bn);
@@ -428,7 +424,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -451,7 +447,7 @@ BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_to_BN, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
+10 -12
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -108,7 +106,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_BMP:
if(len & 1) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
@@ -116,7 +114,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_UNIV:
if(len & 3) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
@@ -127,7 +125,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
@@ -137,19 +135,19 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
break;
default:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if((minsize > 0) && (nchar < minsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if((maxsize > 0) && (nchar > maxsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
@@ -157,7 +155,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
@@ -191,7 +189,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
@@ -199,7 +197,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
@@ -230,7 +228,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
}
if(!(p = OPENSSL_malloc(outlen + 1))) {
if(free_out) ASN1_STRING_free(dest);
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
+11 -12
View File
@@ -57,7 +57,6 @@
#include <openssl/asn1.h>
#include <limits.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -106,13 +105,13 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
}
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c= *(p++);
@@ -122,7 +121,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
if (num <= 0) break;
if ((c != '.') && (c != ' '))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
goto err;
}
l=0;
@@ -136,7 +135,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
break;
if ((c < '0') || (c > '9'))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
@@ -160,7 +159,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if ((first < 2) && (l >= 40))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn)
@@ -204,7 +203,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if (len+i > olen)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
@@ -280,7 +279,7 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if(ret) *pp = p;
return ret;
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i);
return(NULL);
}
@@ -300,7 +299,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
@@ -309,7 +308,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
{
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
}
@@ -350,7 +349,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
@@ -363,7 +362,7 @@ ASN1_OBJECT *ASN1_OBJECT_new(void)
ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_OBJECT_new, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
+2 -3
View File
@@ -57,7 +57,6 @@
#include <openssl/asn1.h>
#include <stdlib.h> /* For bsearch */
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -215,13 +214,13 @@ int ASN1_STRING_TABLE_add(int nid,
flags &= ~STABLE_FLAGS_MALLOC;
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if(!stable) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
return 0;
}
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if(!tmp) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
+2 -5
View File
@@ -56,9 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <time.h>
#include <openssl/asn1t.h>
#include <openssl/buf.h>
#include <openssl/err.h>
@@ -85,7 +82,7 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_EXPECTING_A_TIME);
return -1;
}
#endif
@@ -105,7 +102,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
OPENSSL_PUT_ERROR(ASN1, ASN1_TIME_adj, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
if (offset_day || offset_sec)
+1 -4
View File
@@ -111,7 +111,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
}
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
{
int result = -1;
@@ -125,9 +125,6 @@ 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:
+4 -7
View File
@@ -56,9 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <time.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/time_support.h>
@@ -81,12 +78,12 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_NESTED_ASN1_ERROR);
return(NULL);
}
if (!ASN1_UTCTIME_check(ret))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_INVALID_TIME_FORMAT);
goto err;
}
@@ -257,7 +254,7 @@ ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
p=OPENSSL_malloc(len);
if (p == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_UTCTIME_adj, ERR_R_MALLOC_FAILURE);
goto err;
}
if (s->data != NULL)
@@ -288,7 +285,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, &ttm, &stm))
if (!OPENSSL_gmtime_diff(&day, &sec, &stm, &ttm))
return -2;
if (day > 0)
+201
View File
@@ -0,0 +1,201 @@
/* 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},
};
+13 -41
View File
@@ -57,45 +57,13 @@
#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_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_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);
@@ -161,11 +129,6 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
p++;
if (--max == 0) goto err;
}
/* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
goto err;
*ptag=tag;
*pclass=xclass;
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
@@ -181,7 +144,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
#endif
if (*plength > (omax - (p - *pp)))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret|=0x80;
@@ -189,7 +152,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
*pp=p;
return(ret|inf);
err:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_HEADER_TOO_LONG);
return(0x80);
}
@@ -431,7 +394,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
if (str->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_set, ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
}
@@ -467,7 +430,7 @@ ASN1_STRING *ASN1_STRING_type_new(int type)
ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_type_new, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
@@ -502,6 +465,15 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
return(i);
}
void asn1_add_error(const unsigned char *address, int offset)
{
char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
BIO_snprintf(buf2,sizeof buf2,"%d",offset);
ERR_add_error_data(4,"address=",buf1," offset=",buf2);
}
int ASN1_STRING_length(const ASN1_STRING *x)
{ return M_ASN1_STRING_length(x); }
+20 -29
View File
@@ -61,8 +61,6 @@
#include <openssl/mem.h>
#define ASN1_PARSE_MAXDEPTH 128
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
@@ -127,13 +125,6 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
if (depth > ASN1_PARSE_MAXDEPTH)
{
BIO_puts(bp, "BAD RECURSION DEPTH\n");
return 0;
}
p= *pp;
tot=p+length;
op=p-1;
@@ -146,7 +137,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
#endif
if (j & 0x80)
{
if (BIO_puts(bp, "Error in encoding\n") <= 0)
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
goto end;
ret=0;
goto end;
@@ -174,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_puts(bp, "\n") <= 0) goto end;
if (BIO_write(bp,"\n",1) <= 0) goto end;
if (len > length)
{
BIO_printf(bp,
@@ -205,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_puts(bp, "\n") <= 0) goto end;
if (BIO_write(bp,"\n",1) <= 0) goto end;
}
else
{
@@ -219,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_puts(bp, ":") <= 0) goto end;
if (BIO_write(bp,":",1) <= 0) goto end;
if ((len > 0) &&
BIO_write(bp,(const char *)p,(int)len)
!= (int)len)
@@ -230,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_puts(bp, ":") <= 0) goto end;
if (BIO_write(bp,":",1) <= 0) goto end;
i2a_ASN1_OBJECT(bp,o);
}
else
{
if (BIO_puts(bp, ":BAD OBJECT") <= 0)
if (BIO_write(bp,":BAD OBJECT",11) <= 0)
goto end;
}
}
@@ -247,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_puts(bp, "Bad boolean\n") <= 0)
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
goto end;
}
BIO_printf(bp,":%d",ii);
@@ -282,7 +273,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
if (printable)
/* printable string */
{
if (BIO_puts(bp, ":") <= 0)
if (BIO_write(bp,":",1) <= 0)
goto end;
if (BIO_write(bp,(const char *)opp,
os->length) <= 0)
@@ -292,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_puts(bp, "[HEX DUMP]:") <= 0)
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
goto end;
for (i=0; i<os->length; i++)
{
@@ -306,7 +297,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
{
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0)
if (BIO_write(bp,"\n",1) <= 0)
goto end;
}
if (!BIO_hexdump(bp, opp,
@@ -332,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_puts(bp, ":") <= 0) goto end;
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_puts(bp, "-") <= 0)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
{
@@ -344,13 +335,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
}
if (bs->length == 0)
{
if (BIO_puts(bp, "00") <= 0)
if (BIO_write(bp,"00",2) <= 0)
goto end;
}
}
else
{
if (BIO_puts(bp, "BAD INTEGER") <= 0)
if (BIO_write(bp,"BAD INTEGER",11) <= 0)
goto end;
}
M_ASN1_INTEGER_free(bs);
@@ -364,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_puts(bp, ":") <= 0) goto end;
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_puts(bp, "-") <= 0)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
{
@@ -376,13 +367,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
}
if (bs->length == 0)
{
if (BIO_puts(bp, "00") <= 0)
if (BIO_write(bp,"00",2) <= 0)
goto end;
}
}
else
{
if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
goto end;
}
M_ASN1_ENUMERATED_free(bs);
@@ -391,7 +382,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
{
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0)
if (BIO_write(bp,"\n",1) <= 0)
goto end;
}
if (!BIO_hexdump(bp,p,
@@ -403,7 +394,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0) goto end;
if (BIO_write(bp,"\n",1) <= 0) goto end;
}
p+=len;
if ((tag == V_ASN1_EOC) && (xclass == 0))
-51
View File
@@ -1,51 +0,0 @@
/* Copyright (c) 2016, 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include "../test/scoped_types.h"
// kTag258 is an ASN.1 structure with a universal tag with number 258.
static const uint8_t kTag258[] = {
0x1f, 0x82, 0x02, 0x01, 0x00,
};
static_assert(V_ASN1_NEG_INTEGER == 258,
"V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it.");
bool TestLargeTags() {
const uint8_t *p = kTag258;
ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
if (obj) {
fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
return false;
}
return true;
}
int main() {
CRYPTO_library_init();
if (!TestLargeTags()) {
return 1;
}
printf("PASS\n");
return 0;
}
+4 -4
View File
@@ -68,7 +68,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
@@ -80,11 +80,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
@@ -99,6 +99,6 @@ void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
p = oct->data;
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_unpack, ASN1_R_DECODE_ERROR);
return ret;
}
+2 -3
View File
@@ -57,7 +57,6 @@
#include <openssl/asn1.h>
#include <assert.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/mem.h>
@@ -125,7 +124,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 const BIO_METHOD methods_asn1=
static BIO_METHOD methods_asn1=
{
BIO_TYPE_ASN1,
"asn1",
@@ -139,7 +138,7 @@ static const BIO_METHOD methods_asn1=
asn1_bio_callback_ctrl,
};
const BIO_METHOD *BIO_f_asn1(void)
BIO_METHOD *BIO_f_asn1(void)
{
return(&methods_asn1);
}
+1 -7
View File
@@ -112,7 +112,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
if (!aux || !aux->asn1_cb)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
OPENSSL_PUT_ERROR(ASN1, BIO_new_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
@@ -170,9 +170,6 @@ 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);
@@ -238,9 +235,6 @@ 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);
+1 -1
View File
@@ -123,7 +123,7 @@ print <<EOF;
* Mask of various character properties
*/
static const unsigned char char_type[] = {
static unsigned char char_type[] = {
EOF
for($i = 0; $i < 128; $i++) {
+5 -6
View File
@@ -144,7 +144,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -158,7 +158,8 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -177,7 +178,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -197,10 +198,8 @@ err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
+5 -6
View File
@@ -149,7 +149,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -162,7 +162,8 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -181,7 +182,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -201,10 +202,8 @@ err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
+5 -6
View File
@@ -142,7 +142,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -156,7 +156,8 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -175,7 +176,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -195,10 +196,8 @@ err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
-2
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/mem.h>
+63 -102
View File
@@ -56,15 +56,11 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
static int asn1_check_eoc(const unsigned char **in, long len);
static int asn1_find_end(const unsigned char **in, long len, char inf);
@@ -170,7 +166,6 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
int otag;
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
int combine = aclass & ASN1_TFLG_COMBINE;
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -190,7 +185,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
*/
if ((tag != -1) || opt)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
goto err;
}
return asn1_template_ex_d2i(pval, in, len,
@@ -207,7 +202,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, -1, 0, 1, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -216,7 +211,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
/* If OPTIONAL, assume this is OK */
if (opt) return -1;
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
}
/* Check tag matches bit map */
@@ -225,7 +220,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* If OPTIONAL, assume this is OK */
if (opt)
return -1;
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_WRONG_TAG);
goto err;
}
return asn1_d2i_ex_primitive(pval, in, len,
@@ -256,7 +251,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, exptag, aclass, 1, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (ret == -1)
@@ -284,7 +279,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
imphack = *wp;
if (p == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
@@ -299,7 +294,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
if (ptmpval)
return 1;
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
@@ -307,21 +302,10 @@ 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;
if (*pval)
/* Allocate structure */
if (!*pval && !ASN1_item_ex_new(pval, it))
{
/* 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_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
/* CHOICE type, try each possibility in turn */
@@ -341,7 +325,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
break;
/* Otherwise must be an ASN1 parsing error */
errtt = tt;
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -355,14 +339,14 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
ASN1_item_ex_free(pval, it);
return -1;
}
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NO_MATCHING_CHOICE_TYPE);
goto err;
}
asn1_set_choice_selector(pval, i, it);
*in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
*in = p;
return 1;
case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -381,7 +365,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, tag, aclass, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -395,32 +379,19 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else seq_nolen = seq_eoc;
if (!cst)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
goto err;
}
if (!*pval && !ASN1_item_ex_new(pval, it))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
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++)
{
@@ -438,7 +409,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
if (!seq_eoc)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -480,13 +451,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* Check for EOC if expecting one */
if (seq_eoc && !asn1_check_eoc(&p, len))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MISSING_EOC);
goto err;
}
/* Check all data read */
if (!seq_nolen && len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
goto err;
}
@@ -509,26 +480,25 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else
{
errtt = seqtt;
OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_FIELD_MISSING);
goto err;
}
}
/* Save encoding */
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
*in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
*in = p;
return 1;
default:
return 0;
}
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_AUX_ERROR);
err:
if (combine == 0)
ASN1_item_ex_free(pval, it);
ASN1_item_ex_free(pval, it);
if (errtt)
ERR_add_error_data(4, "Field=", errtt->field_name,
", Type=", it->sname);
@@ -571,21 +541,21 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
q = p;
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
return -1;
if (!cst)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
return 0;
}
/* We've found the field so it can't be OPTIONAL now */
ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
/* We read the field in OK so update length */
@@ -595,7 +565,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
/* If NDEF we must have an EOC here */
if (!asn1_check_eoc(&p, len))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -605,7 +575,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
* an error */
if (len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
goto err;
}
}
@@ -629,13 +599,14 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
int flags, aclass;
int ret;
const unsigned char *p;
const unsigned char *p, *q;
if (!val)
return 0;
flags = tt->flags;
aclass = flags & ASN1_TFLG_TAG_CLASS;
p = *in;
q = p;
if (flags & ASN1_TFLG_SK_MASK)
{
@@ -661,7 +632,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
&p, len, sktag, skaclass, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -684,7 +655,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
if (!*val)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -692,13 +663,13 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
while(len > 0)
{
ASN1_VALUE *skfield;
const unsigned char *q = p;
q = p;
/* See if EOC found */
if (asn1_check_eoc(&p, len))
{
if (!sk_eoc)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -710,20 +681,20 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item),
-1, 0, 0, ctx))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
skfield))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (sk_eoc)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -734,7 +705,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -744,10 +715,10 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
-1, 0, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -766,7 +737,6 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
const unsigned char **in, long inlen,
const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx)
OPENSSL_SUPPRESS_POTENTIALLY_UNINITIALIZED_WARNINGS
{
int ret = 0, utype;
long plen;
@@ -777,7 +747,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
long len;
if (!pval)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_NULL);
return 0; /* Should never happen */
}
@@ -795,12 +765,12 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
unsigned char oclass;
if (tag >= 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_TAGGED_ANY);
return 0;
}
if (opt)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_OPTIONAL_ANY);
return 0;
}
p = *in;
@@ -808,7 +778,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, -1, 0, 0, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (oclass != V_ASN1_UNIVERSAL)
@@ -825,7 +795,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, tag, aclass, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -845,7 +815,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* SEQUENCE and SET must be constructed */
else if (!cst)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
}
@@ -866,15 +836,6 @@ 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_R_TYPE_NOT_PRIMITIVE);
return 0;
}
buf.length = 0;
buf.max = 0;
buf.data = NULL;
@@ -893,7 +854,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ERR_R_MALLOC_FAILURE);
return 0;
}
buf.data[len] = 0;
@@ -961,7 +922,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_NULL:
if (len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_NULL_IS_WRONG_LENGTH);
goto err;
}
*pval = (ASN1_VALUE *)1;
@@ -970,7 +931,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_BOOLEAN:
if (len != 1)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
goto err;
}
else
@@ -1017,12 +978,12 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
default:
if (utype == V_ASN1_BMPSTRING && (len & 1))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
goto err;
}
if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
goto err;
}
/* All based on ASN1_STRING and handled the same */
@@ -1031,7 +992,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
stmp = ASN1_STRING_type_new(utype);
if (!stmp)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
goto err;
}
*pval = (ASN1_VALUE *)stmp;
@@ -1054,7 +1015,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
{
if (!ASN1_STRING_set(stmp, cont, len))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
@@ -1116,7 +1077,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-1, 0, 0, NULL))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (inf)
@@ -1127,7 +1088,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
}
if (expected_eoc)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1174,7 +1135,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
* constructed form */
if (!inf)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_UNEXPECTED_EOC);
return 0;
}
inf = 0;
@@ -1184,7 +1145,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
len, tag, aclass, 0, NULL))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
@@ -1193,7 +1154,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
{
if (depth >= ASN1_MAX_STRING_NEST)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_STRING);
return 0;
}
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
@@ -1206,7 +1167,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
}
if (inf)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1221,7 +1182,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, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, asn1_collect, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
@@ -1289,7 +1250,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1298,7 +1259,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
if (i & 0x80)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1311,7 +1272,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (opt) return -1;
asn1_tlc_clear(ctx);
OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_WRONG_TAG);
return 0;
}
/* We have a tag and class match:
-2
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/mem.h>
+1 -1
View File
@@ -143,7 +143,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (!asn1_refcount_dec_and_test_zero(pval, it))
if (asn1_do_lock(pval, -1, it) > 0)
return;
if (asn1_cb)
{
+8 -12
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -100,6 +98,8 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
else
asn1_cb = 0;
if (!combine) *pval = NULL;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
@@ -190,7 +190,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
asn1_refcount_set_one(pval, it);
asn1_do_lock(pval, 0, it);
asn1_enc_init(pval, it);
}
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
@@ -209,15 +209,14 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 1;
memerr:
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
#endif
return 0;
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
@@ -289,7 +288,7 @@ int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
skval = sk_ASN1_VALUE_new_null();
if (!skval)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_template_new, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
@@ -327,17 +326,14 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
ASN1_STRING *str;
int utype;
if (!it)
return 0;
if (it->funcs)
if (it && it->funcs)
{
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
}
if (it->itype == ASN1_ITYPE_MSTRING)
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
utype = it->utype;
+2 -5
View File
@@ -72,7 +72,7 @@
/* ASN1_PCTX routines */
static ASN1_PCTX default_pctx =
ASN1_PCTX default_pctx =
{
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
@@ -88,7 +88,7 @@ ASN1_PCTX *ASN1_PCTX_new(void)
ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(ASN1, ASN1_PCTX_new, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
@@ -229,7 +229,6 @@ 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:
@@ -310,8 +309,6 @@ 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))
+40 -25
View File
@@ -61,38 +61,53 @@
/* Declarations for string types */
#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_INTEGER);
IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER);
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_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_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 */;
+18 -26
View File
@@ -56,15 +56,10 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/err.h>
#include <openssl/thread.h>
#include "../internal.h"
/* Utility functions for manipulating fields and offsets */
@@ -88,32 +83,28 @@ int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
return ret;
}
static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval,
const ASN1_ITEM *it) {
/* Do reference counting. The value 'op' decides what to do. if it is +1 then
* the count is incremented. If op is 0 count is set to 1. If op is -1 count is
* decremented and the return value is the current refrence count or 0 if no
* reference count exists. */
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) {
const ASN1_AUX *aux;
int *lck, ret;
if (it->itype != ASN1_ITYPE_SEQUENCE &&
it->itype != ASN1_ITYPE_NDEF_SEQUENCE) {
return NULL;
return 0;
}
const ASN1_AUX *aux = it->funcs;
aux = it->funcs;
if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) {
return NULL;
return 0;
}
return offset2ptr(*pval, aux->ref_offset);
}
void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) {
CRYPTO_refcount_t *references = asn1_get_references(pval, it);
if (references != NULL) {
*references = 1;
lck = offset2ptr(*pval, aux->ref_offset);
if (op == 0) {
*lck = 1;
return 1;
}
}
int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) {
CRYPTO_refcount_t *references = asn1_get_references(pval, it);
if (references != NULL) {
return CRYPTO_refcount_dec_and_test_zero(references);
}
return 1;
ret = CRYPTO_add(lck, op, aux->ref_lock);
return ret;
}
static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) {
@@ -260,7 +251,8 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
OPENSSL_PUT_ERROR(ASN1, asn1_do_adb,
ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
}
return NULL;
}
+3 -10
View File
@@ -74,14 +74,13 @@ 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 const ASN1_PRIMITIVE_FUNCS bignum_pf = {
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
bn_new,
bn_free,
0,
bn_c2i,
bn_i2c,
NULL /* prim_print */,
bn_i2c
};
ASN1_ITEM_start(BIGNUM)
@@ -127,13 +126,7 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
if(!*pval)
{
if (!bn_new(pval, it))
{
return 0;
}
}
if(!*pval) bn_new(pval, it);
bn = (BIGNUM *)*pval;
if(!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
+3 -5
View File
@@ -56,8 +56,6 @@
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/err.h>
@@ -76,7 +74,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 const ASN1_PRIMITIVE_FUNCS long_pf = {
static ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
@@ -150,7 +148,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
unsigned long utmp = 0;
char *cp = (char *)pval;
if(len > (int)sizeof(long)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
@@ -168,7 +166,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
ltmp = -ltmp;
}
if(ltmp == it->size) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
+6 -9
View File
@@ -1,20 +1,17 @@
include_directories(../../include)
include_directories(. .. ../../include)
add_library(
base64
base64
OBJECT
OBJECT
base64.c
base64.c
)
add_executable(
base64_test
base64_test
base64_test.cc
$<TARGET_OBJECTS:test_support>
base64_test.c
)
target_link_libraries(base64_test crypto)
add_dependencies(all_tests base64_test)
-5
View File
@@ -58,7 +58,6 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
static const unsigned char data_bin2ascii[65] =
@@ -373,10 +372,6 @@ 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>
struct TestVector {
typedef struct {
const char *decoded;
const char *encoded;
};
} TEST_VECTOR;
// Test vectors from RFC 4648.
static const TestVector kTestVectors[] = {
/* Test vectors from RFC 4648. */
static const TEST_VECTOR test_vectors[] = {
{ "", "" },
{ "f" , "Zg==" },
{ "fo", "Zm8=" },
@@ -36,90 +36,95 @@ static const TestVector kTestVectors[] = {
{ "foobar", "Zm9vYmFy" },
};
static const size_t kNumTests = sizeof(kTestVectors) / sizeof(kTestVectors[0]);
static const size_t kNumTests = sizeof(test_vectors) / sizeof(test_vectors[0]);
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));
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));
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 false;
return 0;
}
}
return true;
return 1;
}
static bool TestDecode() {
static int test_decode(void) {
uint8_t out[6];
size_t len;
size_t i, len;
int ret;
for (size_t i = 0; i < kNumTests; i++) {
// Test the normal API.
const TestVector *t = &kTestVectors[i];
for (i = 0; i < kNumTests; i++) {
/* Test the normal API. */
const TEST_VECTOR *t = &test_vectors[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 false;
return 0;
}
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 false;
return 0;
}
// Test that the padding behavior of the deprecated API is preserved.
int ret = EVP_DecodeBlock(out, (const uint8_t*)t->encoded,
strlen(t->encoded));
/* Test that the padding behavior of the deprecated API is
* preserved. */
ret = EVP_DecodeBlock(out, (const uint8_t*)t->encoded, strlen(t->encoded));
if (ret < 0) {
fprintf(stderr, "decode(\"%s\") failed\n", t->encoded);
return false;
return 0;
}
if (ret % 3 != 0) {
fprintf(stderr, "EVP_DecodeBlock did not ignore padding\n");
return false;
return 0;
}
if (expected_len % 3 != 0) {
ret -= 3 - (expected_len % 3);
}
if (static_cast<size_t>(ret) != strlen(t->decoded) ||
if (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 false;
return 0;
}
}
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 false;
return 0;
}
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 false;
return 0;
}
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"abc", 4)) {
fprintf(stderr, "Failed to reject invalid input length.\n");
return false;
return 0;
}
return true;
return 1;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
if (!TestEncode() ||
!TestDecode()) {
if (!test_encode()) {
return 1;
}
if (!test_decode()) {
return 1;
}
+18 -20
View File
@@ -1,33 +1,31 @@
include_directories(../../include)
include_directories(. .. ../../include)
add_library(
bio
bio
OBJECT
OBJECT
bio.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_error.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.cc
$<TARGET_OBJECTS:test_support>
bio_test.c
)
target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
target_link_libraries(bio_test ws2_32)
endif()
add_dependencies(all_tests bio_test)
+29 -161
View File
@@ -56,17 +56,14 @@
#include <openssl/bio.h>
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <limits.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
#include "../internal.h"
/* BIO_set initialises a BIO structure to have the given type and sets the
* reference count to one. It returns one on success or zero on error. */
@@ -80,17 +77,24 @@ static int bio_set(BIO *bio, const BIO_METHOD *method) {
bio->shutdown = 1;
bio->references = 1;
if (method->create != NULL && !method->create(bio)) {
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) {
return 0;
}
if (method->create != NULL) {
if (!method->create(bio)) {
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
return 0;
}
}
return 1;
}
BIO *BIO_new(const BIO_METHOD *method) {
BIO *ret = OPENSSL_malloc(sizeof(BIO));
if (ret == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BIO, BIO_new, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -106,7 +110,8 @@ int BIO_free(BIO *bio) {
BIO *next_bio;
for (; bio != NULL; bio = next_bio) {
if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
int refs = CRYPTO_add(&bio->references, -1, CRYPTO_LOCK_BIO);
if (refs > 0) {
return 0;
}
@@ -119,6 +124,8 @@ int BIO_free(BIO *bio) {
next_bio = BIO_pop(bio);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
if (bio->method != NULL && bio->method->destroy != NULL) {
bio->method->destroy(bio);
}
@@ -128,11 +135,6 @@ int BIO_free(BIO *bio) {
return 1;
}
BIO *BIO_up_ref(BIO *bio) {
CRYPTO_refcount_inc(&bio->references);
return bio;
}
void BIO_vfree(BIO *bio) {
BIO_free(bio);
}
@@ -153,7 +155,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (io_func == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -165,7 +167,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNINITIALIZED);
return -2;
}
@@ -217,7 +219,7 @@ long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
}
if (bio->method == NULL || bio->method->ctrl == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
OPENSSL_PUT_ERROR(BIO, BIO_ctrl, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -323,7 +325,7 @@ long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
}
if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
OPENSSL_PUT_ERROR(BIO, BIO_callback_ctrl, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
@@ -394,6 +396,10 @@ BIO *BIO_push(BIO *bio, BIO *appended_bio) {
}
last_bio->next_bio = appended_bio;
/* TODO(fork): this seems very suspect. If we got rid of BIO SSL, we could
* get rid of this. */
BIO_ctrl(bio, BIO_CTRL_PUSH, 0, bio);
return bio;
}
@@ -404,6 +410,7 @@ BIO *BIO_pop(BIO *bio) {
return NULL;
}
ret = bio->next_bio;
BIO_ctrl(bio, BIO_CTRL_POP, 0, bio);
bio->next_bio = NULL;
return ret;
}
@@ -454,6 +461,12 @@ int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) {
return 1;
}
void BIO_print_errors_fp(FILE *out) {
BIO *bio = BIO_new_fp(out, BIO_NOCLOSE);
BIO_print_errors(bio);
BIO_free(bio);
}
static int print_bio(const char *str, size_t len, void *bio) {
return BIO_write((BIO *)bio, str, len);
}
@@ -461,148 +474,3 @@ static int print_bio(const char *str, size_t len, void *bio) {
void BIO_print_errors(BIO *bio) {
ERR_print_errors_cb(print_bio, bio);
}
void ERR_print_errors(BIO *bio) {
BIO_print_errors(bio);
}
/* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
* success, |*out| is set to an allocated buffer (which should be freed with
* |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
* buffer will contain |prefix| followed by the contents of |bio|. On failure,
* zero is returned.
*
* The function will fail if the size of the output would equal or exceed
* |max_len|. */
static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
const uint8_t *prefix, size_t prefix_len,
size_t max_len) {
static const size_t kChunkSize = 4096;
size_t len = prefix_len + kChunkSize;
if (len > max_len) {
len = max_len;
}
if (len < prefix_len) {
return 0;
}
*out = OPENSSL_malloc(len);
if (*out == NULL) {
return 0;
}
memcpy(*out, prefix, prefix_len);
size_t done = prefix_len;
for (;;) {
if (done == len) {
OPENSSL_free(*out);
return 0;
}
const size_t todo = len - done;
assert(todo < INT_MAX);
const int n = BIO_read(bio, *out + done, todo);
if (n == 0) {
*out_len = done;
return 1;
} else if (n == -1) {
OPENSSL_free(*out);
return 0;
}
done += n;
if (len < max_len && len - done < kChunkSize / 2) {
len += kChunkSize;
if (len < kChunkSize || len > max_len) {
len = max_len;
}
uint8_t *new_buf = OPENSSL_realloc(*out, len);
if (new_buf == NULL) {
OPENSSL_free(*out);
return 0;
}
*out = new_buf;
}
}
}
int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
uint8_t header[6];
static const size_t kInitialHeaderLen = 2;
if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) {
return 0;
}
const uint8_t tag = header[0];
const uint8_t length_byte = header[1];
if ((tag & 0x1f) == 0x1f) {
/* Long form tags are not supported. */
return 0;
}
size_t len, header_len;
if ((length_byte & 0x80) == 0) {
/* Short form length. */
len = length_byte;
header_len = kInitialHeaderLen;
} else {
const size_t num_bytes = length_byte & 0x7f;
if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) {
/* indefinite length. */
return bio_read_all(bio, out, out_len, header, kInitialHeaderLen,
max_len);
}
if (num_bytes == 0 || num_bytes > 4) {
return 0;
}
if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) !=
(int)num_bytes) {
return 0;
}
header_len = kInitialHeaderLen + num_bytes;
uint32_t len32 = 0;
unsigned i;
for (i = 0; i < num_bytes; i++) {
len32 <<= 8;
len32 |= header[kInitialHeaderLen + i];
}
if (len32 < 128) {
/* Length should have used short-form encoding. */
return 0;
}
if ((len32 >> ((num_bytes-1)*8)) == 0) {
/* Length should have been at least one byte shorter. */
return 0;
}
len = len32;
}
if (len + header_len < len ||
len + header_len > max_len ||
len > INT_MAX) {
return 0;
}
len += header_len;
*out_len = len;
*out = OPENSSL_malloc(len);
if (*out == NULL) {
return 0;
}
memcpy(*out, header, header_len);
if (BIO_read(bio, (*out) + header_len, len - header_len) !=
(int) (len - header_len)) {
OPENSSL_free(*out);
return 0;
}
return 1;
}
+55
View File
@@ -0,0 +1,55 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/err.h>
#include <openssl/bio.h>
const ERR_STRING_DATA BIO_error_string_data[] = {
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_callback_ctrl, 0), "BIO_callback_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ctrl, 0), "BIO_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new, 0), "BIO_new"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_file, 0), "BIO_new_file"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_mem_buf, 0), "BIO_new_mem_buf"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ctrl, 0), "bio_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_io, 0), "bio_io"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ip_and_port_to_socket_and_addr, 0), "bio_ip_and_port_to_socket_and_addr"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_make_pair, 0), "bio_make_pair"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_write, 0), "bio_write"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_buffer_ctrl, 0), "buffer_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_conn_ctrl, 0), "conn_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_conn_state, 0), "conn_state"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_file_ctrl, 0), "file_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_file_read, 0), "file_read"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_mem_write, 0), "mem_write"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ASN1_OBJECT_TOO_LONG), "ASN1_OBJECT_TOO_LONG"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "BAD_FOPEN_MODE"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "BROKEN_PIPE"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "CONNECT_ERROR"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ERROR_SETTING_NBIO), "ERROR_SETTING_NBIO"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_ARGUMENT), "INVALID_ARGUMENT"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_IN_USE), "IN_USE"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_KEEPALIVE), "KEEPALIVE"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NBIO_CONNECT_ERROR), "NBIO_CONNECT_ERROR"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_HOSTNAME_SPECIFIED), "NO_HOSTNAME_SPECIFIED"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_SPECIFIED), "NO_PORT_SPECIFIED"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "NO_SUCH_FILE"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "NULL_PARAMETER"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_SYS_LIB), "SYS_LIB"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET), "UNABLE_TO_CREATE_SOCKET"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "UNINITIALIZED"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_METHOD), "UNSUPPORTED_METHOD"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO), "WRITE_TO_READ_ONLY_BIO"},
{0, NULL},
};
+3 -4
View File
@@ -57,7 +57,6 @@
#include <openssl/bio.h>
#include <limits.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
@@ -70,7 +69,7 @@ BIO *BIO_new_mem_buf(void *buf, int len) {
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
if (!buf && len != 0) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER);
OPENSSL_PUT_ERROR(BIO, BIO_new_mem_buf, BIO_R_NULL_PARAMETER);
return NULL;
}
@@ -167,7 +166,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
b = (BUF_MEM *)bio->ptr;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
OPENSSL_PUT_ERROR(BIO, mem_write, BIO_R_WRITE_TO_READ_ONLY_BIO);
goto err;
}
@@ -176,7 +175,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
if (INT_MAX - blen < inl) {
goto err;
}
if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
if (BUF_MEM_grow_clean(b, blen + inl) != (blen + inl)) {
goto err;
}
memcpy(&b->data[blen], in, inl);
+206
View File
@@ -0,0 +1,206 @@
/* 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. */
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201410L
#endif
#include <openssl/base.h>
#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#else
#include <io.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
}
static void print_socket_error(const char *func) {
perror(func);
}
#else
static void print_socket_error(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;
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;
}
if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
print_socket_error("bind");
return 0;
}
if (listen(listening_sock, 1)) {
print_socket_error("listen");
return 0;
}
if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
sockaddr_len != sizeof(sin)) {
print_socket_error("getsockname");
return 0;
}
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
ntohs(sin.sin_port));
bio = BIO_new_connect(hostname);
if (!bio) {
fprintf(stderr, "BIO_new_connect failed.\n");
return 0;
}
if (BIO_write(bio, kTestMessage, sizeof(kTestMessage)) !=
sizeof(kTestMessage)) {
fprintf(stderr, "BIO_write failed.\n");
BIO_print_errors_fp(stderr);
return 0;
}
sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
if (sock < 0) {
print_socket_error("accept");
return 0;
}
if (recv(sock, buf, sizeof(buf), 0) != sizeof(kTestMessage)) {
print_socket_error("read");
return 0;
}
if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
return 0;
}
closesocket(sock);
closesocket(listening_sock);
BIO_free(bio);
return 1;
}
static int test_printf(void) {
/* Test a short output, a very long one, and various sizes around
* 256 (the size of the buffer) to ensure edge cases are correct. */
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());
if (!bio) {
fprintf(stderr, "BIO_new failed\n");
return 0;
}
for (i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
if (kLengths[i] >= sizeof(string)) {
fprintf(stderr, "Bad test string length\n");
return 0;
}
memset(string, 'a', sizeof(string));
string[kLengths[i]] = '\0';
ret = BIO_printf(bio, "test %s", string);
if (ret != 5 + kLengths[i]) {
fprintf(stderr, "BIO_printf failed: %d\n", ret);
return 0;
}
if (!BIO_mem_contents(bio, &contents, &len)) {
fprintf(stderr, "BIO_mem_contents failed\n");
return 0;
}
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;
}
if (!BIO_reset(bio)) {
fprintf(stderr, "BIO_reset failed\n");
return 0;
}
}
BIO_free(bio);
return 1;
}
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);
if (wsa_err != 0) {
fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
return 1;
}
if (wsa_data.wVersion != wsa_version) {
fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
return 1;
}
#endif
if (!test_socket_connect()) {
return 1;
}
if (!test_printf()) {
return 1;
}
printf("PASS\n");
return 0;
}
-441
View File
@@ -1,441 +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. */
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201410L
#endif
#include <openssl/base.h>
#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#else
#include <io.h>
#pragma warning(push, 3)
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma warning(pop)
#endif
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <algorithm>
#include "../test/scoped_types.h"
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
}
static void PrintSocketError(const char *func) {
perror(func);
}
#else
static void PrintSocketError(const char *func) {
fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
}
#endif
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)) {
PrintSocketError("inet_pton");
return false;
}
if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
PrintSocketError("bind");
return false;
}
if (listen(listening_sock, 1)) {
PrintSocketError("listen");
return false;
}
socklen_t sockaddr_len = sizeof(sin);
if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
sockaddr_len != sizeof(sin)) {
PrintSocketError("getsockname");
return false;
}
char hostname[80];
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
ntohs(sin.sin_port));
ScopedBIO bio(BIO_new_connect(hostname));
if (!bio) {
fprintf(stderr, "BIO_new_connect failed.\n");
return false;
}
if (BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)) !=
sizeof(kTestMessage)) {
fprintf(stderr, "BIO_write failed.\n");
ERR_print_errors_fp(stderr);
return false;
}
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)) {
PrintSocketError("read");
return false;
}
if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
return false;
}
return true;
}
// 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;
size_t len_read = 0;
do {
if (!BIO_zero_copy_get_read_buf(bio, &read_buf, &read_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = 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);
len_read += available_bytes;
} while (len - len_read > 0 && available_bytes > 0);
return len_read;
}
// 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;
size_t len_written = 0;
do {
if (!BIO_zero_copy_get_write_buf(bio, &write_buf, &write_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = 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);
len_written += available_bytes;
} while (len - len_written > 0 && available_bytes > 0);
return len_written;
}
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];
const size_t kLengths[] = {254, 255, 256, 257, 510, 511, 512, 513};
// These trigger ring buffer wrap around.
const size_t kPartialLengths[] = {0, 1, 2, 3, 128, 255, 256, 257, 511, 512};
static const size_t kBufferSize = 512;
srand(1);
for (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 (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 *bio1, *bio2;
if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
return false;
}
ScopedBIO bio1_scoper(bio1);
ScopedBIO bio2_scoper(bio2);
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer, kLengths[i]);
// 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 false;
}
// 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 = 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.
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 += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer + total_write,
kPartialLengths[j] - interleaved_write_len);
// Drain the rest.
size_t bytes_left = BIO_pending(bio2);
total_read += BioReadZeroCopyWrapper(
bio2, bio2_application_recv_buffer + total_read, bytes_left);
if (total_read != total_write) {
fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
if (total_read > kLengths[i] + kPartialLengths[j]) {
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
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 false;
}
}
}
return true;
}
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 };
ScopedBIO bio(BIO_new(BIO_s_mem()));
if (!bio) {
fprintf(stderr, "BIO_new failed\n");
return false;
}
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 false;
}
memset(string, 'a', sizeof(string));
string[kLengths[i]] = '\0';
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 false;
}
const uint8_t *contents;
size_t len;
if (!BIO_mem_contents(bio.get(), &contents, &len)) {
fprintf(stderr, "BIO_mem_contents failed\n");
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 false;
}
if (!BIO_reset(bio.get())) {
fprintf(stderr, "BIO_reset failed\n");
return false;
}
}
return true;
}
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(data), data_len));
uint8_t *out;
size_t out_len;
int ok = BIO_read_asn1(bio.get(), &out, &out_len, max_len);
if (!ok) {
out = nullptr;
}
ScopedOpenSSLBytes out_storage(out);
if (should_succeed != (ok == 1)) {
return false;
}
if (should_succeed &&
(out_len != expected_len || memcmp(data, out, expected_len) != 0)) {
return false;
}
return true;
}
static bool TestASN1() {
static const uint8_t kData1[] = {0x30, 2, 1, 2, 0, 0};
static const uint8_t kData2[] = {0x30, 3, 1, 2}; /* truncated */
static const uint8_t kData3[] = {0x30, 0x81, 1, 1}; /* should be short len */
static const uint8_t kData4[] = {0x30, 0x82, 0, 1, 1}; /* zero padded. */
if (!ReadASN1(true, kData1, sizeof(kData1), 4, 100) ||
!ReadASN1(false, kData2, sizeof(kData2), 0, 100) ||
!ReadASN1(false, kData3, sizeof(kData3), 0, 100) ||
!ReadASN1(false, kData4, sizeof(kData4), 0, 100)) {
return false;
}
static const size_t kLargePayloadLen = 8000;
static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
kLargePayloadLen & 0xff};
ScopedOpenSSLBytes large(reinterpret_cast<uint8_t *>(
OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
if (!large) {
return false;
}
memset(large.get() + sizeof(kLargePrefix), 0, kLargePayloadLen);
memcpy(large.get(), kLargePrefix, sizeof(kLargePrefix));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen * 2)) {
fprintf(stderr, "Large payload test failed.\n");
return false;
}
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen - 1)) {
fprintf(stderr, "max_len test failed.\n");
return false;
}
static const uint8_t kIndefPrefix[] = {0x30, 0x80};
memcpy(large.get(), kIndefPrefix, sizeof(kIndefPrefix));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen*2)) {
fprintf(stderr, "indefinite length test failed.\n");
return false;
}
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen-1)) {
fprintf(stderr, "indefinite length, max_len test failed.\n");
return false;
}
return true;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
#if defined(OPENSSL_WINDOWS)
// 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;
}
if (wsa_data.wVersion != wsa_version) {
fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
return 1;
}
#endif
if (!TestSocketConnect() ||
!TestPrintf() ||
!TestZeroCopyBioPairs() ||
!TestASN1()) {
return 1;
}
printf("PASS\n");
return 0;
}
+10 -9
View File
@@ -56,8 +56,6 @@
#include <openssl/bio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -122,13 +120,17 @@ err1:
static int buffer_free(BIO *bio) {
BIO_F_BUFFER_CTX *ctx;
if (bio == NULL || bio->ptr == NULL) {
if (bio == NULL) {
return 0;
}
ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
OPENSSL_free(ctx->ibuf);
OPENSSL_free(ctx->obuf);
if (ctx->ibuf != NULL) {
OPENSSL_free(ctx->ibuf);
}
if (ctx->obuf != NULL) {
OPENSSL_free(ctx->obuf);
}
OPENSSL_free(bio->ptr);
bio->ptr = NULL;
@@ -311,9 +313,8 @@ 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;
@@ -406,7 +407,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
return ret;
malloc_error:
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BIO, buffer_ctrl, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -479,7 +480,7 @@ static int buffer_puts(BIO *b, const char *str) {
return buffer_write(b, str, strlen(str));
}
static const BIO_METHOD methods_buffer = {
static 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,
+86 -95
View File
@@ -59,18 +59,12 @@
#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>
@@ -93,6 +87,7 @@ typedef struct bio_connect_st {
char *param_port;
int nbio;
uint8_t ip[4];
unsigned short port;
struct sockaddr_storage them;
@@ -113,59 +108,23 @@ static int closesocket(int sock) {
}
#endif
/* split_host_and_port sets |*out_host| and |*out_port| to the host and port
* parsed from |name|. It returns one on success or zero on error. Even when
* successful, |*out_port| may be NULL on return if no port was specified. */
static int split_host_and_port(char **out_host, char **out_port, const char *name) {
const char *host, *port = NULL;
size_t host_len = 0;
/* maybe_copy_ipv4_address sets |*ipv4| to the IPv4 address from |ss| (in
* big-endian order), if |ss| contains an IPv4 socket address. */
static void maybe_copy_ipv4_address(uint8_t *ipv4,
const struct sockaddr_storage *ss) {
const struct sockaddr_in *sin;
*out_host = NULL;
*out_port = NULL;
if (name[0] == '[') { /* bracketed IPv6 address */
const char *close = strchr(name, ']');
if (close == NULL) {
return 0;
}
host = name + 1;
host_len = close - host;
if (close[1] == ':') { /* [IP]:port */
port = close + 2;
} else if (close[1] != 0) {
return 0;
}
} else {
const char *colon = strchr(name, ':');
if (colon == NULL || strchr(colon + 1, ':') != NULL) { /* IPv6 address */
host = name;
host_len = strlen(name);
} else { /* host:port */
host = name;
host_len = colon - name;
port = colon + 1;
}
if (ss->ss_family != AF_INET) {
return;
}
*out_host = BUF_strndup(host, host_len);
if (*out_host == NULL) {
return 0;
}
if (port == NULL) {
*out_port = NULL;
return 1;
}
*out_port = OPENSSL_strdup(port);
if (*out_port == NULL) {
OPENSSL_free(*out_host);
*out_host = NULL;
return 0;
}
return 1;
sin = (const struct sockaddr_in*) ss;
memcpy(ipv4, &sin->sin_addr, 4);
}
static int conn_state(BIO *bio, BIO_CONNECT *c) {
int ret = -1, i;
char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
if (c->info_callback != NULL) {
@@ -175,43 +134,54 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
for (;;) {
switch (c->state) {
case BIO_CONN_S_BEFORE:
/* If there's a hostname and a port, assume that both are
* exactly what they say. If there is only a hostname, try
* (just once) to split it into a hostname and port. */
if (c->param_hostname == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
p = c->param_hostname;
if (p == NULL) {
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
for (; *p != 0; p++) {
if (*p == ':' || *p == '/') {
break;
}
}
i = *p;
if (i == ':' || i == '/') {
*(p++) = 0;
if (i == ':') {
for (q = p; *q; q++) {
if (*q == '/') {
*q = 0;
break;
}
}
if (c->param_port != NULL) {
OPENSSL_free(c->param_port);
}
c->param_port = BUF_strdup(p);
}
}
if (c->param_port == NULL) {
char *host, *port;
if (!split_host_and_port(&host, &port, c->param_hostname) ||
port == NULL) {
OPENSSL_free(host);
OPENSSL_free(port);
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop;
}
OPENSSL_free(c->param_port);
c->param_port = port;
OPENSSL_free(c->param_hostname);
c->param_hostname = host;
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop;
}
if (!bio_ip_and_port_to_socket_and_addr(
&bio->num, &c->them, &c->them_length, c->param_hostname,
c->param_port)) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_UNABLE_TO_CREATE_SOCKET);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
memset(c->ip, 0, 4);
maybe_copy_ipv4_address(c->ip, &c->them);
if (c->nbio) {
if (!bio_socket_nbio(bio->num, 1)) {
OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_ERROR_SETTING_NBIO);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
goto exit_loop;
@@ -222,8 +192,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
sizeof(i));
if (ret < 0) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_KEEPALIVE);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
@@ -236,8 +206,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
c->state = BIO_CONN_S_BLOCKED_CONNECT;
bio->retry_reason = BIO_RR_CONNECT;
} else {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
OPENSSL_PUT_SYSTEM_ERROR(connect);
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
}
@@ -257,8 +227,8 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = -1;
} else {
BIO_clear_retry_flags(bio);
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
OPENSSL_PUT_SYSTEM_ERROR(connect);
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NBIO_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
ret = 0;
}
@@ -310,8 +280,12 @@ static void BIO_CONNECT_free(BIO_CONNECT *c) {
return;
}
OPENSSL_free(c->param_hostname);
OPENSSL_free(c->param_port);
if (c->param_hostname != NULL) {
OPENSSL_free(c->param_hostname);
}
if (c->param_port != NULL) {
OPENSSL_free(c->param_port);
}
OPENSSL_free(c);
}
@@ -402,6 +376,7 @@ static int conn_write(BIO *bio, const char *in, int in_len) {
static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
int *ip;
const char **pptr;
long ret = 1;
BIO_CONNECT *data;
@@ -416,9 +391,27 @@ 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). */
if (ptr != NULL) {
pptr = (const char **)ptr;
if (num == 0) {
*pptr = data->param_hostname;
} else if (num == 1) {
*pptr = data->param_port;
} else if (num == 2) {
*pptr = (char *) &data->ip[0];
} else if (num == 3) {
*((int *)ptr) = data->port;
}
if (!bio->init) {
*pptr = "not initialized";
}
ret = 1;
}
break;
@@ -426,17 +419,15 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
if (ptr != NULL) {
bio->init = 1;
if (num == 0) {
OPENSSL_free(data->param_hostname);
if (data->param_hostname != NULL) {
OPENSSL_free(data->param_hostname);
}
data->param_hostname = BUF_strdup(ptr);
if (data->param_hostname == NULL) {
ret = 0;
}
} else if (num == 1) {
OPENSSL_free(data->param_port);
data->param_port = BUF_strdup(ptr);
if (data->param_port == NULL) {
ret = 0;
if (data->param_port != NULL) {
OPENSSL_free(data->param_port);
}
data->param_port = BUF_strdup(ptr);
} else {
ret = 0;
}
@@ -451,9 +442,9 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = bio->num;
}
ret = bio->num;
ret = 1;
} else {
ret = -1;
ret = 0;
}
break;
case BIO_CTRL_GET_CLOSE:
@@ -470,7 +461,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
break;
case BIO_CTRL_SET_CALLBACK: {
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
OPENSSL_PUT_ERROR(BIO, XXX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret = 0;
+3 -6
View File
@@ -57,15 +57,12 @@
#include <openssl/bio.h>
#include <errno.h>
#include <string.h>
#if !defined(OPENSSL_WINDOWS)
#include <unistd.h>
#else
#include <io.h>
#pragma warning(push, 3)
#include <windows.h>
#pragma warning(pop)
#include <Windows.h>
#endif
#include <openssl/buf.h>
@@ -208,9 +205,9 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = b->num;
}
return b->num;
return 1;
} else {
ret = -1;
ret = 0;
}
break;
case BIO_CTRL_GET_CLOSE:
+14 -14
View File
@@ -76,7 +76,6 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
@@ -88,7 +87,7 @@
#define BIO_FP_APPEND 0x08
static FILE *open_file(const char *filename, const char *mode) {
#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
#if defined(_WIN32) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename) + 1;
DWORD flags;
@@ -129,13 +128,13 @@ BIO *BIO_new_file(const char *filename, const char *mode) {
file = open_file(filename, mode);
if (file == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_SYSTEM_ERROR(fopen);
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_NO_SUCH_FILE);
} else {
OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_SYS_LIB);
}
return NULL;
}
@@ -182,19 +181,20 @@ static int file_free(BIO *bio) {
}
static int file_read(BIO *b, char *out, int outl) {
int ret = 0;
if (!b->init) {
return 0;
}
size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
return -1;
OPENSSL_PUT_SYSTEM_ERROR(fread);
OPENSSL_PUT_ERROR(BIO, file_read, ERR_R_SYS_LIB);
ret = -1;
}
/* fread reads at most |outl| bytes, so |ret| fits in an int. */
return (int)ret;
return ret;
}
static int file_write(BIO *b, const char *in, int inl) {
@@ -252,15 +252,15 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
} else if (num & BIO_FP_READ) {
BUF_strlcpy(p, "r", sizeof(p));
} else {
OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
OPENSSL_PUT_ERROR(BIO, file_ctrl, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
fp = open_file(ptr, p);
if (fp == NULL) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_SYSTEM_ERROR(fopen);
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
OPENSSL_PUT_ERROR(BIO, file_ctrl, ERR_R_SYS_LIB);
ret = 0;
break;
}
+3 -5
View File
@@ -57,7 +57,6 @@
#include <openssl/bio.h>
#include <limits.h>
#include <string.h>
/* hexdump_ctx contains the state of a hexdump. */
@@ -82,10 +81,9 @@ static char to_char(uint8_t b) {
return b;
}
/* hexdump_write adds |len| bytes of |data| to the current hex dump described by
/* hexdump adds |len| bytes of |data| to the current hex dump described by
* |ctx|. */
static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data,
size_t len) {
static int hexdump(struct hexdump_ctx *ctx, const uint8_t *data, size_t len) {
size_t i;
char buf[10];
unsigned l;
@@ -184,7 +182,7 @@ int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) {
ctx.bio = bio;
ctx.indent = indent;
if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) {
if (!hexdump(&ctx, data, len) || !finish(&ctx)) {
return 0;
}
+2 -1
View File
@@ -67,7 +67,8 @@ typedef unsigned short u_short;
#include <sys/types.h>
#include <sys/socket.h>
#else
typedef int socklen_t;
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#if defined(__cplusplus)
+82 -336
View File
@@ -53,7 +53,6 @@
#include <openssl/bio.h>
#include <assert.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
@@ -71,13 +70,7 @@ struct bio_bio_st {
size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
size_t size;
uint8_t *buf; /* "size" elements (if != NULL) */
char buf_externally_allocated; /* true iff buf was externally allocated. */
char zero_copy_read_lock; /* true iff a zero copy read operation
* is in progress. */
char zero_copy_write_lock; /* true iff a zero copy write operation
* is in progress. */
char *buf; /* "size" elements (if != NULL) */
size_t request; /* valid iff peer != NULL; 0 if len != 0,
* otherwise set by peer to number of bytes
@@ -92,9 +85,11 @@ static int bio_new(BIO *bio) {
if (b == NULL) {
return 0;
}
memset(b, 0, sizeof(struct bio_bio_st));
b->peer = NULL;
b->size = 17 * 1024; /* enough for one TLS record (just a default) */
b->buf = NULL;
bio->ptr = b;
return 1;
}
@@ -145,7 +140,7 @@ static int bio_free(BIO *bio) {
bio_destroy_pair(bio);
}
if (!b->buf_externally_allocated) {
if (b->buf != NULL) {
OPENSSL_free(b->buf);
}
@@ -154,254 +149,6 @@ static int bio_free(BIO *bio) {
return 1;
}
static size_t bio_zero_copy_get_read_buf(struct bio_bio_st* peer_b,
uint8_t** out_read_buf,
size_t* out_buf_offset) {
size_t max_available;
if (peer_b->len > peer_b->size - peer_b->offset) {
/* Only the first half of the ring buffer can be read. */
max_available = peer_b->size - peer_b->offset;
} else {
max_available = peer_b->len;
}
*out_read_buf = peer_b->buf;
*out_buf_offset = peer_b->offset;
return max_available;
}
int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
size_t* out_buf_offset,
size_t* out_available_bytes) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
*out_available_bytes = 0;
BIO_clear_retry_flags(bio);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
peer_b->request = 0; /* Is not used by zero-copy API. */
max_available =
bio_zero_copy_get_read_buf(peer_b, out_read_buf, out_buf_offset);
assert(peer_b->buf != NULL);
if (max_available > 0) {
peer_b->zero_copy_read_lock = 1;
}
*out_available_bytes = max_available;
return 1;
}
int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
size_t dummy_read_offset;
uint8_t* dummy_read_buf;
assert(BIO_get_retry_flags(bio) == 0);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (!peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
max_available =
bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
if (bytes_read > max_available) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
assert(peer_b->len >= bytes_read);
peer_b->len -= bytes_read;
assert(peer_b->offset + bytes_read <= peer_b->size);
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
* offset even if buffer becomes empty, to make sure
* write_offset = (offset + len) mod size does not change. */
if (peer_b->offset + bytes_read == peer_b->size ||
(!peer_b->zero_copy_write_lock && peer_b->len == 0)) {
peer_b->offset = 0;
} else {
peer_b->offset += bytes_read;
}
bio->num_read += bytes_read;
peer_b->zero_copy_read_lock = 0;
return 1;
}
static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b,
uint8_t** out_write_buf,
size_t* out_buf_offset) {
size_t write_offset;
size_t max_available;
assert(b->len <= b->size);
write_offset = b->offset + b->len;
if (write_offset >= b->size) {
/* Only the first half of the ring buffer can be written to. */
write_offset -= b->size;
/* write up to the start of the ring buffer. */
max_available = b->offset - write_offset;
} else {
/* write up to the end the buffer. */
max_available = b->size - write_offset;
}
*out_write_buf = b->buf;
*out_buf_offset = write_offset;
return max_available;
}
int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
size_t* out_buf_offset,
size_t* out_available_bytes) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
*out_available_bytes = 0;
BIO_clear_retry_flags(bio);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
b->request = 0;
if (b->closed) {
/* Bio is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
max_available = bio_zero_copy_get_write_buf(b, out_write_buf, out_buf_offset);
if (max_available > 0) {
b->zero_copy_write_lock = 1;
}
*out_available_bytes = max_available;
return 1;
}
int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t rest;
size_t dummy_write_offset;
uint8_t* dummy_write_buf;
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
b->request = 0;
if (b->closed) {
/* BIO is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
if (!b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
if (bytes_written > rest) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
bio->num_write += bytes_written;
/* Move write offset. */
b->len += bytes_written;
b->zero_copy_write_lock = 0;
return 1;
}
static int bio_read(BIO *bio, char *buf, int size_) {
size_t size = size_;
size_t rest;
@@ -422,7 +169,7 @@ static int bio_read(BIO *bio, char *buf, int size_) {
peer_b->request = 0; /* will be set in "retry_read" situation */
if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) {
if (buf == NULL || size == 0) {
return 0;
}
@@ -467,10 +214,7 @@ static int bio_read(BIO *bio, char *buf, int size_) {
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
peer_b->len -= chunk;
/* If zero_copy_write_lock == 1 we must advance the offset even if buffer
* becomes empty, to make sure write_offset = (offset + len) % size
* does not change. */
if (peer_b->len || peer_b->zero_copy_write_lock) {
if (peer_b->len) {
peer_b->offset += chunk;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size) {
@@ -504,14 +248,10 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
assert(b->peer != NULL);
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
return 0;
}
b->request = 0;
if (b->closed) {
/* we already closed */
OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
return -1;
}
@@ -564,9 +304,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
return num;
}
static int bio_make_pair(BIO* bio1, BIO* bio2,
size_t writebuf1_len, uint8_t* ext_writebuf1,
size_t writebuf2_len, uint8_t* ext_writebuf2) {
static int bio_make_pair(BIO *bio1, BIO *bio2) {
struct bio_bio_st *b1, *b2;
assert(bio1 != NULL);
@@ -576,46 +314,25 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
return 0;
}
assert(b1->buf_externally_allocated == 0);
assert(b2->buf_externally_allocated == 0);
if (b1->buf == NULL) {
if (writebuf1_len) {
b1->size = writebuf1_len;
}
if (!ext_writebuf1) {
b1->buf_externally_allocated = 0;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b1->buf = ext_writebuf1;
b1->buf_externally_allocated = 1;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
}
b1->len = 0;
b1->offset = 0;
}
if (b2->buf == NULL) {
if (writebuf2_len) {
b2->size = writebuf2_len;
}
if (!ext_writebuf2) {
b2->buf_externally_allocated = 0;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b2->buf = ext_writebuf2;
b2->buf_externally_allocated = 1;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
}
b2->len = 0;
b2->offset = 0;
@@ -624,13 +341,9 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b1->peer = bio2;
b1->closed = 0;
b1->request = 0;
b1->zero_copy_read_lock = 0;
b1->zero_copy_write_lock = 0;
b2->peer = bio1;
b2->closed = 0;
b2->request = 0;
b2->zero_copy_read_lock = 0;
b2->zero_copy_write_lock = 0;
bio1->init = 1;
bio2->init = 1;
@@ -647,6 +360,27 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
switch (cmd) {
/* specific CTRL codes */
case BIO_C_SET_BUFF_SIZE:
if (b->peer) {
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_IN_USE);
ret = 0;
} else if (num == 0) {
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_INVALID_ARGUMENT);
ret = 0;
} else {
size_t new_size = num;
if (b->size != new_size) {
if (b->buf) {
OPENSSL_free(b->buf);
b->buf = NULL;
}
b->size = new_size;
}
ret = 1;
}
break;
case BIO_C_GET_WRITE_BUF_SIZE:
ret = (long)b->size;
break;
@@ -685,6 +419,14 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
/* standard CTRL codes follow */
case BIO_CTRL_RESET:
if (b->buf != NULL) {
b->len = 0;
b->offset = 0;
}
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = bio->shutdown;
break;
@@ -736,53 +478,49 @@ static int bio_puts(BIO *bio, const char *str) {
return bio_write(bio, str, strlen(str));
}
static const BIO_METHOD methods_biop = {
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
bio_free, NULL /* no bio_callback_ctrl */
};
const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
BIO** bio2_p, size_t writebuf2) {
return BIO_new_bio_pair_external_buf(bio1_p, writebuf1, NULL, bio2_p,
writebuf2, NULL);
}
int BIO_new_bio_pair_external_buf(BIO** bio1_p, size_t writebuf1_len,
uint8_t* ext_writebuf1,
BIO** bio2_p, size_t writebuf2_len,
uint8_t* ext_writebuf2) {
int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p,
size_t writebuf2) {
BIO *bio1 = NULL, *bio2 = NULL;
long r;
int ret = 0;
/* External buffers must have sizes greater than 0. */
if ((ext_writebuf1 && !writebuf1_len) || (ext_writebuf2 && !writebuf2_len)) {
goto err;
}
bio1 = BIO_new(bio_s_bio());
bio1 = BIO_new(BIO_s_bio());
if (bio1 == NULL) {
goto err;
}
bio2 = BIO_new(bio_s_bio());
bio2 = BIO_new(BIO_s_bio());
if (bio2 == NULL) {
goto err;
}
if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len,
ext_writebuf2)) {
if (writebuf1) {
r = BIO_set_write_buffer_size(bio1, writebuf1);
if (!r) {
goto err;
}
}
if (writebuf2) {
r = BIO_set_write_buffer_size(bio2, writebuf2);
if (!r) {
goto err;
}
}
if (!bio_make_pair(bio1, bio2)) {
goto err;
}
ret = 1;
err:
if (ret == 0) {
BIO_free(bio1);
bio1 = NULL;
BIO_free(bio2);
bio2 = NULL;
if (bio1) {
BIO_free(bio1);
bio1 = NULL;
}
if (bio2) {
BIO_free(bio2);
bio2 = NULL;
}
}
*bio1_p = bio1;
@@ -790,6 +528,14 @@ err:
return ret;
}
static const BIO_METHOD methods_biop = {
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
bio_free, NULL /* no bio_callback_ctrl */
};
const BIO_METHOD *BIO_s_bio(void) { return &methods_biop; }
size_t BIO_ctrl_get_read_request(BIO *bio) {
return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
}
+4 -8
View File
@@ -64,7 +64,6 @@
#include <stdarg.h>
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
int BIO_printf(BIO *bio, const char *format, ...) {
@@ -87,11 +86,7 @@ int BIO_printf(BIO *bio, const char *format, ...) {
}
#endif
if (out_len < 0) {
return -1;
}
if ((size_t) out_len >= sizeof(buf)) {
if (out_len >= sizeof(buf)) {
const int requested_len = out_len;
/* The output was truncated. Note that vsnprintf's return value
* does not include a trailing NUL, but the buffer must be sized
@@ -99,8 +94,9 @@ int BIO_printf(BIO *bio, const char *format, ...) {
out = OPENSSL_malloc(requested_len + 1);
out_malloced = 1;
if (out == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return -1;
/* Unclear what can be done in this situation. OpenSSL has historically
* crashed and that seems better than producing the wrong output. */
abort();
}
va_start(args, format);
out_len = vsnprintf(out, requested_len + 1, format, args);
+2 -11
View File
@@ -58,16 +58,9 @@
#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"
@@ -152,13 +145,11 @@ 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;
+8 -11
View File
@@ -12,24 +12,21 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#define _POSIX_SOURCE
#include <openssl/bio.h>
#include <openssl/err.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#if !defined(OPENSSL_WINDOWS)
#include <netdb.h>
#include <unistd.h>
#else
#pragma warning(push, 3)
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma warning(pop)
#include <WinSock2.h>
#include <WS2tcpip.h>
typedef int socklen_t;
#endif
#include "internal.h"
@@ -51,15 +48,15 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
ret = getaddrinfo(hostname, port_str, &hint, &result);
if (ret != 0) {
OPENSSL_PUT_ERROR(SYS, 0);
ERR_add_error_data(1, gai_strerror(ret));
OPENSSL_PUT_ERROR(SYS, getaddrinfo, 0);
ERR_add_error_data(2, gai_strerror(ret));
return 0;
}
ret = 0;
for (cur = result; cur; cur = cur->ai_next) {
if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
if (cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
continue;
}
memset(out_addr, 0, sizeof(struct sockaddr_storage));
@@ -68,7 +65,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
*out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
if (*out_sock < 0) {
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_SYSTEM_ERROR(socket);
goto out;
}
+44 -54
View File
@@ -1,88 +1,78 @@
include_directories(../../include)
include_directories(. .. ../../include)
if (${ARCH} STREQUAL "x86_64")
set(
BN_ARCH_SOURCES
set(
BN_ARCH_SOURCES
x86_64-mont.${ASM_EXT}
x86_64-mont5.${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}
modexp512-x86_64.${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}
)
endif()
if (${ARCH} STREQUAL "aarch64")
set(
BN_ARCH_SOURCES
armv8-mont.${ASM_EXT}
)
armv4-mont.${ASM_EXT}
)
endif()
add_library(
bn
bn
OBJECT
OBJECT
add.c
asm/x86_64-gcc.c
bn.c
bn_asn1.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_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
${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)
perlasm(co-586.${ASM_EXT} asm/co-586.pl)
perlasm(x86-mont.${ASM_EXT} asm/x86-mont.pl)
perlasm(armv4-mont.${ASM_EXT} asm/armv4-mont.pl)
perlasm(armv8-mont.${ASM_EXT} asm/armv8-mont.pl)
add_executable(
bn_test
bn_test
bn_test.cc
$<TARGET_OBJECTS:test_support>
bn_test.c
)
target_link_libraries(bn_test crypto)
add_dependencies(all_tests bn_test)
+22 -5
View File
@@ -56,8 +56,6 @@
#include <openssl/bn.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -269,7 +267,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
if (dif < 0) /* hmm... should not be happening */
{
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
OPENSSL_PUT_ERROR(BN, BN_usub, BN_R_ARG2_LT_ARG3);
return 0;
}
@@ -313,8 +311,27 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
}
}
if (dif > 0 && rp != ap) {
memcpy(rp, ap, sizeof(*rp) * dif);
if (rp != ap) {
for (;;) {
if (!dif--) {
break;
}
rp[0] = ap[0];
if (!dif--) {
break;
}
rp[1] = ap[1];
if (!dif--) {
break;
}
rp[2] = ap[2];
if (!dif--) {
break;
}
rp[3] = ap[3];
rp += 4;
ap += 4;
}
}
r->top = max;
+10 -34
View File
@@ -38,20 +38,8 @@
# for execution on all NEON-capable processors, because gain on
# others outweighs the marginal loss on Cortex-A9.
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$num="r0"; # starts as num argument, but holds &tp[num-1]
$ap="r1";
@@ -79,15 +67,15 @@ $_n0="$num,#14*4";
$_num="$num,#15*4"; $_bpend=$_num;
$code=<<___;
#include <openssl/arm_arch.h>
#include "arm_arch.h"
.text
.code 32
#if __ARM_MAX_ARCH__>=7
#if __ARM_ARCH__>=7
.align 5
.LOPENSSL_armcap:
.word OPENSSL_armcap_P-.Lbn_mul_mont
.word OPENSSL_armcap_P-bn_mul_mont
#endif
.global bn_mul_mont
@@ -96,18 +84,14 @@ $code=<<___;
.align 5
bn_mul_mont:
.Lbn_mul_mont:
ldr ip,[sp,#4] @ load num
stmdb sp!,{r0,r2} @ sp points at argument block
#if __ARM_MAX_ARCH__>=7
#if __ARM_ARCH__>=7
tst ip,#7
bne .Lialu
adr r0,bn_mul_mont
ldr r2,.LOPENSSL_armcap
ldr r0,[r0,r2]
#ifdef __APPLE__
ldr r0,[r0]
#endif
tst r0,#1 @ NEON available?
ldmia sp, {r0,r2}
beq .Lialu
@@ -247,14 +231,9 @@ bn_mul_mont:
ldmia sp!,{r4-r12,lr} @ restore registers
add sp,sp,#2*4 @ skip over {r0,r2}
mov r0,#1
.Labrt:
#if __ARM_ARCH__>=5
ret @ bx lr
#else
tst lr,#1
.Labrt: tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
#endif
.size bn_mul_mont,.-bn_mul_mont
___
{
@@ -273,8 +252,7 @@ my ($rptr,$aptr,$bptr,$nptr,$n0,$num)=map("r$_",(0..5));
my ($tinptr,$toutptr,$inner,$outer)=map("r$_",(6..9));
$code.=<<___;
#if __ARM_MAX_ARCH__>=7
.arch armv7-a
#if __ARM_ARCH__>=7
.fpu neon
.type bn_mul8x_mont_neon,%function
@@ -673,7 +651,7 @@ bn_mul8x_mont_neon:
sub sp,ip,#96
vldmia sp!,{d8-d15}
ldmia sp!,{r4-r11}
ret @ bx lr
bx lr
.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
#endif
___
@@ -681,14 +659,12 @@ ___
$code.=<<___;
.asciz "Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
#if __ARM_MAX_ARCH__>=7
#if __ARM_ARCH__>=7
.comm OPENSSL_armcap_P,4,4
.hidden OPENSSL_armcap_P
#endif
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
$code =~ s/\bret\b/bx lr/gm;
print $code;
close STDOUT;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+24 -12
View File
@@ -61,12 +61,8 @@
#
# 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;
@@ -79,15 +75,31 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable these after testing. $avx goes up to 2 and $addx to 1.
$avx = 0;
$addx = 0;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$avx = ($1>=2.19) + ($1>=2.22);
$addx = ($1>=2.23);
}
open OUT,"| \"$^X\" $xlate $flavour $output";
if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$avx = ($1>=2.09) + ($1>=2.10);
$addx = ($1>=2.10);
}
if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$avx = ($1>=10) + ($1>=11);
$addx = ($1>=11);
}
if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
$avx = ($ver>=3.0) + ($ver>=3.01);
$addx = ($ver>=3.03);
}
open OUT,"| $^X $xlate $flavour $output";
*STDOUT = *OUT;
if ($avx>1) {{{
+20 -7
View File
@@ -95,15 +95,28 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
open OUT,"| $^X $xlate $flavour $output";
*STDOUT=*OUT;
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $addx goes up to 1.
$addx = 0;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.23);
}
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.10);
}
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$addx = ($1>=12);
}
if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
$addx = ($ver>=3.03);
}
($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp"); # common internal API
{
+93 -75
View File
@@ -1,6 +1,6 @@
#include <openssl/bn.h>
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS)
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS)
#include "../internal.h"
@@ -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,9 +100,8 @@ 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);
@@ -115,26 +114,23 @@ 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);
@@ -147,22 +143,19 @@ 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]);
@@ -175,13 +168,11 @@ 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]);
}
}
@@ -199,9 +190,8 @@ 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 */
@@ -226,9 +216,8 @@ 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 */
@@ -253,56 +242,47 @@ 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
@@ -312,45 +292,80 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0)
*/
/* Keep in mind that carrying into high part of multiplication result can not
* overflow, because it cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
#if 0
/* original macros are kept for reference purposes */
#define mul_add_c(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b); \
t1 = ta * tb; \
t2 = BN_UMULT_HIGH(ta, tb); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#define mul_add_c2(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b), t0; \
t1 = BN_UMULT_HIGH(ta, tb); \
t0 = ta * tb; \
t2 = t1 + t1; \
c2 += (t2 < t1) ? 1 : 0; \
t1 = t0 + t0; \
t2 += (t1 < t0) ? 1 : 0; \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#else
#define mul_add_c(a, b, c0, c1, c2) \
do { \
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
asm("addq %0,%0; adcq %2,%1" : "+d"(t2), "+r"(c2) : "g"(0) : "cc"); \
asm("addq %0,%0; adcq %2,%1" : "+a"(t1), "+d"(t2) : "g"(0) : "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
} while (0)
#endif
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -453,6 +468,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -491,6 +507,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -565,6 +582,7 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
}
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -596,4 +614,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
r[7] = c2;
}
#endif /* !NO_ASM && X86_64 && !WINDOWS */
#endif /* defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS) */
+14 -6
View File
@@ -53,12 +53,20 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this option after testing. $addx goes up to 1.
$addx = 0;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.23);
}
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.10);
}
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$addx = ($1>=12);
}
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
+17 -25
View File
@@ -38,12 +38,20 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $addx goes up to 1.
$addx = 0;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.23);
}
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.10);
}
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$addx = ($1>=12);
}
# int bn_mul_mont_gather5(
$rp="%rdi"; # BN_ULONG *rp,
@@ -1770,15 +1778,6 @@ sqr8x_reduction:
.align 32
.L8x_tail_done:
add (%rdx),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
adc \$0,%r11
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
xor %rax,%rax
neg $carry
@@ -3125,15 +3124,6 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_tail_done:
add 24+8(%rsp),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
adc \$0,%r11
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
mov $carry,%rax # xor %rax,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
@@ -3177,11 +3167,13 @@ my ($rptr,$nptr)=("%rdx","%rbp");
my @ri=map("%r$_",(10..13));
my @ni=map("%r$_",(14..15));
$code.=<<___;
xor %ebx,%ebx
xor %rbx,%rbx
sub %r15,%rsi # compare top-most words
adc %rbx,%rbx
mov %rcx,%r10 # -$num
.byte 0x67
or %rbx,%rax
.byte 0x67
mov %rcx,%r9 # -$num
xor \$1,%rax
sar \$3+2,%rcx # cf=0
+18 -23
View File
@@ -57,8 +57,6 @@
#include <openssl/bn.h>
#include <limits.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -69,7 +67,7 @@ BIGNUM *BN_new(void) {
BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM));
if (bn == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BN, BN_new, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -88,7 +86,7 @@ void BN_free(BIGNUM *bn) {
return;
}
if ((bn->flags & BN_FLG_STATIC_DATA) == 0) {
if (bn->d != NULL && (bn->flags & BN_FLG_STATIC_DATA) == 0) {
OPENSSL_free(bn->d);
}
@@ -166,10 +164,11 @@ void BN_clear(BIGNUM *bn) {
}
const BIGNUM *BN_value_one(void) {
static const BN_ULONG kOneLimbs[1] = { 1 };
static const BIGNUM kOne = STATIC_BIGNUM(kOneLimbs);
static const BN_ULONG data_one = 1;
static const BIGNUM const_one = {(BN_ULONG *)&data_one, 1, 1, 0,
BN_FLG_STATIC_DATA};
return &kOne;
return &const_one;
}
void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) {
@@ -199,15 +198,13 @@ 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
@@ -278,43 +275,41 @@ void BN_set_negative(BIGNUM *bn, int sign) {
}
}
BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
BN_ULONG *a;
if (words <= (size_t)bn->dmax) {
if (words <= (unsigned) bn->dmax) {
return bn;
}
if (words > (INT_MAX / (4 * BN_BITS2))) {
OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_BIGNUM_TOO_LONG);
return NULL;
}
if (bn->flags & BN_FLG_STATIC_DATA) {
OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
return NULL;
}
a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
if (a == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BN, bn_wexpand, ERR_R_MALLOC_FAILURE);
return NULL;
}
memcpy(a, bn->d, sizeof(BN_ULONG) * bn->top);
OPENSSL_free(bn->d);
if (bn->d) {
OPENSSL_free(bn->d);
}
bn->d = a;
bn->dmax = (int)words;
bn->dmax = words;
return bn;
}
BIGNUM *bn_expand(BIGNUM *bn, size_t bits) {
if (bits + BN_BITS2 - 1 < bits) {
OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return NULL;
}
BIGNUM *bn_expand(BIGNUM *bn, unsigned bits) {
return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2);
}
-93
View File
@@ -1,93 +0,0 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
return 0;
}
if (CBS_data(&child)[0] & 0x80) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
/* INTEGERs must be minimal. */
if (CBS_data(&child)[0] == 0x00 &&
CBS_len(&child) > 1 &&
!(CBS_data(&child)[1] & 0x80)) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
return 0;
}
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
return 0;
}
/* This function intentionally does not reject negative numbers or non-minimal
* encodings. Estonian IDs issued between September 2014 to September 2015 are
* broken. See https://crbug.com/532048 and https://crbug.com/534766.
*
* TODO(davidben): Remove this code and callers in March 2016. */
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
/* Negative numbers are unsupported. */
if (BN_is_negative(bn)) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
CBB child;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
/* The number must be padded with a leading zero if the high bit would
* otherwise be set (or |bn| is zero). */
if (BN_num_bits(bn) % 8 == 0 &&
!CBB_add_u8(&child, 0x00)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
uint8_t *out;
if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
BN_bn2bin(bn, out);
if (!CBB_flush(cbb)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
return 1;
}
+63
View File
@@ -0,0 +1,63 @@
/* 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},
};
+1411
View File
File diff suppressed because it is too large Load Diff
-1937
View File
File diff suppressed because it is too large Load Diff
+56 -150
View File
@@ -56,11 +56,8 @@
#include <openssl/bn.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
@@ -69,8 +66,7 @@
#include "internal.h"
BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
size_t num_words;
unsigned m;
unsigned num_words, m;
BN_ULONG word = 0;
BIGNUM *bn = NULL;
@@ -96,10 +92,7 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
return NULL;
}
/* |bn_wexpand| must check bounds on |num_words| to write it into
* |ret->dmax|. */
assert(num_words <= INT_MAX);
ret->top = (int)num_words;
ret->top = num_words;
ret->neg = 0;
while (len--) {
@@ -204,7 +197,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BN, BN_bn2hex, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -233,80 +226,66 @@ char *BN_bn2hex(const BIGNUM *bn) {
return buf;
}
/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
if (in_len > INT_MAX/4) {
OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return 0;
}
/* |in_len| is the number of hex digits. */
if (bn_expand(bn, in_len * 4) == NULL) {
return 0;
}
/* decode_hex decodes |i| bytes of hex data from |in| and updates |bn|. */
static void decode_hex(BIGNUM *bn, const char *in, int i) {
int h, m, j, k, c;
BN_ULONG l=0;
int i = 0;
while (in_len > 0) {
/* Decode one |BN_ULONG| at a time. */
int todo = BN_BYTES * 2;
if (todo > in_len) {
todo = in_len;
}
BN_ULONG word = 0;
int j;
for (j = todo; j > 0; j--) {
char c = in[in_len - j];
BN_ULONG hex;
if (c >= '0' && c <= '9') {
hex = c - '0';
} else if (c >= 'a' && c <= 'f') {
hex = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
hex = c - 'A' + 10;
j = i; /* least significant 'hex' */
h = 0;
while (j > 0) {
m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
l = 0;
for (;;) {
c = in[j - m];
if ((c >= '0') && (c <= '9')) {
k = c - '0';
} else if ((c >= 'a') && (c <= 'f')) {
k = c - 'a' + 10;
} else if ((c >= 'A') && (c <= 'F')) {
k = c - 'A' + 10;
} else {
hex = 0;
/* This shouldn't happen. The caller checks |isxdigit|. */
assert(0);
k = 0; /* paranoia */
}
l = (l << 4) | k;
if (--m <= 0) {
bn->d[h++] = l;
break;
}
word = (word << 4) | hex;
}
bn->d[i++] = word;
in_len -= todo;
j -= (BN_BYTES * 2);
}
assert(i <= bn->dmax);
bn->top = i;
return 1;
bn->top = h;
}
/* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */
static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
int i, j;
/* decode_dec decodes |i| bytes of decimal data from |in| and updates |bn|. */
static void decode_dec(BIGNUM *bn, const char *in, int i) {
int j;
BN_ULONG l = 0;
/* Decode |BN_DEC_NUM| digits at a time. */
j = BN_DEC_NUM - (in_len % BN_DEC_NUM);
j = BN_DEC_NUM - (i % BN_DEC_NUM);
if (j == BN_DEC_NUM) {
j = 0;
}
l = 0;
for (i = 0; i < in_len; i++) {
while (*in) {
l *= 10;
l += in[i] - '0';
l += *in - '0';
in++;
if (++j == BN_DEC_NUM) {
if (!BN_mul_word(bn, BN_DEC_CONV) ||
!BN_add_word(bn, l)) {
return 0;
}
BN_mul_word(bn, BN_DEC_CONV);
BN_add_word(bn, l);
l = 0;
j = 0;
}
}
return 1;
}
typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
typedef void (*decode_func) (BIGNUM *bn, const char *in, int i);
typedef int (*char_test_func) (int c);
static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
@@ -323,7 +302,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
in++;
}
for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
for (i = 0; want_char((unsigned char)in[i]); i++) {}
num = i + neg;
if (outp == NULL) {
@@ -340,15 +319,16 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
ret = *outp;
BN_zero(ret);
}
ret->neg = neg;
if (!decode(ret, in, i)) {
/* i is the number of hex digests; */
if (bn_expand(ret, i * 4) == NULL) {
goto err;
}
decode(ret, in, i);
bn_correct_top(ret);
if (!BN_is_zero(ret)) {
ret->neg = neg;
}
*outp = ret;
return num;
@@ -383,7 +363,7 @@ char *BN_bn2dec(const BIGNUM *a) {
(BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BN, BN_bn2dec, ERR_R_MALLOC_FAILURE);
goto err;
}
t = BN_dup(a);
@@ -425,9 +405,13 @@ char *BN_bn2dec(const BIGNUM *a) {
ok = 1;
err:
OPENSSL_free(bn_data);
BN_free(t);
if (!ok) {
if (bn_data != NULL) {
OPENSSL_free(bn_data);
}
if (t != NULL) {
BN_free(t);
}
if (!ok && buf) {
OPENSSL_free(buf);
buf = NULL;
}
@@ -455,7 +439,7 @@ int BN_asc2bn(BIGNUM **outp, const char *in) {
}
}
if (*orig_in == '-' && !BN_is_zero(*outp)) {
if (*orig_in == '-') {
(*outp)->neg = 1;
}
@@ -517,81 +501,3 @@ BN_ULONG BN_get_word(const BIGNUM *bn) {
return BN_MASK2;
}
}
size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
const size_t bits = BN_num_bits(in);
const size_t bytes = (bits + 7) / 8;
/* If the number of bits is a multiple of 8, i.e. if the MSB is set,
* prefix with a zero byte. */
int extend = 0;
if (bytes != 0 && (bits & 0x07) == 0) {
extend = 1;
}
const size_t len = bytes + extend;
if (len < bytes ||
4 + len < len ||
(len & 0xffffffff) != len) {
/* If we cannot represent the number then we emit zero as the interface
* doesn't allow an error to be signalled. */
if (out) {
memset(out, 0, 4);
}
return 4;
}
if (out == NULL) {
return 4 + len;
}
out[0] = len >> 24;
out[1] = len >> 16;
out[2] = len >> 8;
out[3] = len;
if (extend) {
out[4] = 0;
}
BN_bn2bin(in, out + 4 + extend);
if (in->neg && len > 0) {
out[4] |= 0x80;
}
return len + 4;
}
BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
if (len < 4) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
return NULL;
}
const size_t in_len = ((size_t)in[0] << 24) |
((size_t)in[1] << 16) |
((size_t)in[2] << 8) |
((size_t)in[3]);
if (in_len != len - 4) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
return NULL;
}
if (out == NULL) {
out = BN_new();
}
if (out == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (in_len == 0) {
BN_zero(out);
return out;
}
in += 4;
if (BN_bin2bn(in, in_len, out) == NULL) {
return NULL;
}
out->neg = ((*in) & 0x80) != 0;
if (out->neg) {
BN_clear_bit(out, BN_num_bits(out) - 1);
}
return out;
}
+11 -9
View File
@@ -54,8 +54,6 @@
#include <openssl/bn.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -124,7 +122,7 @@ struct bignum_ctx {
BN_CTX *BN_CTX_new(void) {
BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
if (!ret) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
OPENSSL_PUT_ERROR(BN, BN_CTX_new, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -153,7 +151,7 @@ void BN_CTX_start(BN_CTX *ctx) {
ctx->err_stack++;
} else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
/* (Try to) get a new frame pointer */
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
OPENSSL_PUT_ERROR(BN, BN_CTX_start, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
ctx->err_stack++;
}
}
@@ -169,7 +167,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) {
/* Setting too_many prevents repeated "get" attempts from
* cluttering the error stack. */
ctx->too_many = 1;
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
OPENSSL_PUT_ERROR(BN, BN_CTX_get, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
return NULL;
}
@@ -205,12 +203,14 @@ static void BN_STACK_init(BN_STACK *st) {
}
static void BN_STACK_finish(BN_STACK *st) {
OPENSSL_free(st->indexes);
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));
@@ -220,7 +220,9 @@ static int BN_STACK_push(BN_STACK *st, unsigned int idx) {
if (st->depth) {
memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
}
OPENSSL_free(st->indexes);
if (st->size) {
OPENSSL_free(st->indexes);
}
st->indexes = newitems;
st->size = newsize;
}
+18 -23
View File
@@ -125,7 +125,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
* so don't just rely on bn_check_top() here */
if ((num->top > 0 && num->d[num->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
OPENSSL_PUT_ERROR(BN, BN_div, BN_R_NOT_INITIALIZED);
return 0;
}
@@ -135,7 +135,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
if (BN_is_zero(divisor)) {
OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
OPENSSL_PUT_ERROR(BN, BN_div, BN_R_DIV_BY_ZERO);
return 0;
}
@@ -260,10 +260,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q = BN_MASK2;
} else {
/* n0 < d0 */
#ifdef BN_ULLONG
#ifdef BN_LLONG
BN_ULLONG t2;
#if defined(BN_ULLONG) && !defined(div_asm)
#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(div_asm)
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
#else
q = div_asm(n0, n1, d0);
@@ -278,17 +278,15 @@ 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_ULLONG */
#else /* !BN_LLONG */
BN_ULONG t2l, t2h;
#if defined(div_asm)
@@ -318,20 +316,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_ULLONG */
#endif /* !BN_LLONG */
}
l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
@@ -362,9 +357,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
* BN_rshift() will overwrite it.
*/
int neg = num->neg;
if (!BN_rshift(rm, snum, norm_shift)) {
goto err;
}
BN_rshift(rm, snum, norm_shift);
if (!BN_is_zero(rm)) {
rm->neg = neg;
}
@@ -492,7 +485,9 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
BN_free(abs_m);
if (abs_m) {
BN_free(abs_m);
}
return ret;
}
@@ -511,7 +506,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) {
/* max_shift >= 0 */
if (max_shift < 0) {
OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
OPENSSL_PUT_ERROR(BN, BN_mod_lshift_quick, BN_R_INPUT_NOT_REDUCED);
return 0;
}
@@ -601,7 +596,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
}
BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
#ifndef BN_ULLONG
#ifndef BN_LLONG
BN_ULONG ret = 0;
#else
BN_ULLONG ret = 0;
@@ -614,7 +609,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_ULLONG
#ifndef BN_LLONG
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
#else
+146 -155
View File
@@ -109,7 +109,6 @@
#include <openssl/bn.h>
#include <assert.h>
#include <string.h>
#include <openssl/cpu.h>
#include <openssl/err.h>
@@ -123,17 +122,6 @@
#define RSAZ_ENABLED
#include "rsaz_exp.h"
void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
const BN_ULONG *np, const BN_ULONG *n0, int num,
int power);
void bn_scatter5(const BN_ULONG *inp, size_t num, void *table, size_t power);
void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
const BN_ULONG *np, const BN_ULONG *n0, int num, int power);
int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
const BN_ULONG *not_used, const BN_ULONG *np,
const BN_ULONG *n0, int num);
#endif
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
@@ -142,7 +130,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
if ((p->flags & BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
OPENSSL_PUT_ERROR(BN, BN_exp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -183,13 +171,12 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
}
}
if (r != rr && !BN_copy(r, rr)) {
goto err;
}
ret = 1;
err:
if (r != rr) {
BN_copy(r, rr);
}
BN_CTX_end(ctx);
return ret;
}
@@ -285,10 +272,10 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
goto err;
}
if (BN_ucmp(m, &recp->N) < 0) {
if (BN_ucmp(m, &(recp->N)) < 0) {
BN_zero(d);
if (!BN_copy(r, m)) {
goto err;
return 0;
}
BN_CTX_end(ctx);
return 1;
@@ -344,7 +331,7 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
j = 0;
while (BN_ucmp(r, &(recp->N)) >= 0) {
if (j++ > 2) {
OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL);
OPENSSL_PUT_ERROR(BN, BN_div_recp, BN_R_BAD_RECIPROCAL);
goto err;
}
if (!BN_usub(r, r, &(recp->N))) {
@@ -429,7 +416,7 @@ err:
static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx) {
int i, j, bits, ret = 0, wstart, window;
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
int start = 1;
BIGNUM *aa;
/* Table of variables obtained from 'ctx' */
@@ -438,7 +425,7 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
OPENSSL_PUT_ERROR(BN, mod_exp_recp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -498,16 +485,15 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
start = 1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue = 0; /* The 'value' of the window */
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
if (!BN_one(r)) {
goto err;
}
for (;;) {
int wvalue; /* The 'value' of the window */
int wend; /* The bottom bit of the window */
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
@@ -556,6 +542,7 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
/* move the 'window' down further */
wstart -= wend + 1;
wvalue = 0;
start = 0;
if (wstart < 0) {
break;
@@ -613,21 +600,21 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
}
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, ret = 0, wstart, window;
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
int start = 1;
BIGNUM *d, *r;
const BIGNUM *aa;
/* Table of variables obtained from 'ctx' */
BIGNUM *val[TABLE_SIZE];
BN_MONT_CTX *new_mont = NULL;
BN_MONT_CTX *mont = NULL;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, mont);
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
}
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits = BN_num_bits(p);
@@ -644,13 +631,18 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
/* If this is not done, things will break in the montgomery part */
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL) {
goto err;
}
if (!BN_MONT_CTX_set(mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
if (a->neg || BN_ucmp(a, m) >= 0) {
@@ -688,18 +680,18 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
start = 1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue = 0; /* The 'value' of the window */
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
j = m->top; /* borrow j */
if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
if (bn_wexpand(r, j) == NULL) {
if (bn_wexpand(r, j) == NULL)
goto err;
}
/* 2^(top*BN_BITS2) - m */
r->d[0] = (0 - m->d[0]) & BN_MASK2;
for (i = 1; i < j; i++) {
for (i = 1; i < j; i++)
r->d[i] = (~m->d[i]) & BN_MASK2;
}
r->top = j;
/* Upper words will be zero if the corresponding words of 'm'
* were 0xfff[...], so decrement r->top accordingly. */
@@ -709,12 +701,10 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
for (;;) {
int wvalue; /* The 'value' of the window */
int wend; /* The bottom bit of the window */
if (BN_is_bit_set(p, wstart) == 0) {
if (!start && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
goto err;
if (!start) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
goto err;
}
if (wstart == 0) {
break;
@@ -726,6 +716,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* We now have wstart on a 'set' bit, we now need to work out how bit a
* window to do. To do this we need to scan forward until the last set bit
* before the end of the window */
j = wstart;
wvalue = 1;
wend = 0;
for (i = 1; i < window; i++) {
@@ -757,6 +748,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* move the 'window' down further */
wstart -= wend + 1;
wvalue = 0;
start = 0;
if (wstart < 0) {
break;
@@ -769,7 +761,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
ret = 1;
err:
BN_MONT_CTX_free(new_mont);
if (in_mont == NULL && mont != NULL) {
BN_MONT_CTX_free(mont);
}
BN_CTX_end(ctx);
return ret;
}
@@ -855,10 +849,10 @@ static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
*/
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont) {
BN_MONT_CTX *in_mont) {
int i, bits, ret = 0, window, wvalue;
int top;
BN_MONT_CTX *new_mont = NULL;
BN_MONT_CTX *mont = NULL;
int numPowers;
unsigned char *powerbufFree = NULL;
@@ -866,13 +860,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
top = m->top;
if (!(m->d[0] & 1)) {
OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_consttime,
BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits = BN_num_bits(p);
if (bits == 0) {
ret = BN_one(rr);
@@ -881,13 +875,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
BN_CTX_start(ctx);
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
/* 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)
mont = in_mont;
else {
if ((mont = BN_MONT_CTX_new()) == NULL)
goto err;
if (!BN_MONT_CTX_set(mont, m, ctx))
goto err;
}
mont = new_mont;
}
#ifdef RSAZ_ENABLED
@@ -896,9 +893,8 @@ 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;
@@ -906,9 +902,8 @@ 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;
@@ -923,11 +918,11 @@ 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;
/* Allocate a buffer large enough to hold all of the pre-computed
* powers of am, am itself and tmp.
@@ -937,24 +932,20 @@ 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 */
@@ -970,23 +961,20 @@ 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) ||
!BN_to_montgomery(&am, &am, mont, ctx)) {
if (!BN_mod(&am, a, m, ctx))
goto err;
}
} else if (!BN_to_montgomery(&am, a, mont, ctx)) {
if (!BN_to_montgomery(&am, &am, mont, ctx))
goto err;
} 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,
@@ -996,26 +984,33 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
* 512-bit RSA is hardly relevant, we omit it to spare size... */
if (window == 5 && top > 1) {
const BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
void bn_mul_mont_gather5(BN_ULONG * rp, const BN_ULONG * ap,
const void * table, const BN_ULONG * np,
const BN_ULONG * n0, int num, int power);
void bn_scatter5(const BN_ULONG * inp, size_t num, void * table,
size_t power);
void bn_gather5(BN_ULONG * out, size_t num, void * table, size_t power);
void bn_power5(BN_ULONG * rp, const BN_ULONG * ap, const void * table,
const BN_ULONG * np, const BN_ULONG * n0, int num,
int power);
int bn_from_montgomery(BN_ULONG * rp, const BN_ULONG * ap,
const BN_ULONG * not_used, const BN_ULONG * np,
const BN_ULONG * n0, int num);
BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
/* 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 {
BN_ULONG *np_double = am.d + top;
for (i = 0; i < top; i++) {
np_double[2 * i] = np[i];
}
np2 = np_double;
}
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);
@@ -1048,9 +1043,8 @@ 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
@@ -1062,9 +1056,8 @@ 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);
@@ -1108,18 +1101,17 @@ 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) ||
!copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers))
goto err;
if (!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)
@@ -1127,26 +1119,24 @@ 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) ||
!copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
goto err;
if (!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) ||
!copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
goto err;
if (!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.
@@ -1156,44 +1146,40 @@ 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:
BN_MONT_CTX_free(new_mont);
if ((in_mont == NULL) && (mont != NULL))
BN_MONT_CTX_free(mont);
if (powerbuf != NULL) {
OPENSSL_cleanse(powerbuf, powerbufLen);
OPENSSL_free(powerbufFree);
if (powerbufFree)
OPENSSL_free(powerbufFree);
}
BN_CTX_end(ctx);
return (ret);
}
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont) {
BN_MONT_CTX *new_mont = NULL;
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
BN_MONT_CTX *mont = NULL;
int b, bits, ret = 0;
int r_is_one;
BN_ULONG w, next_w;
@@ -1213,12 +1199,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word,
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
@@ -1251,13 +1238,15 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
goto err;
}
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
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)) {
goto err;
}
mont = new_mont;
}
r_is_one = 1; /* except for Montgomery factor */
@@ -1339,7 +1328,9 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
ret = 1;
err:
BN_MONT_CTX_free(new_mont);
if (in_mont == NULL && mont != NULL) {
BN_MONT_CTX_free(mont);
}
BN_CTX_end(ctx);
return ret;
}
@@ -1348,7 +1339,7 @@ err:
int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
BN_CTX *ctx, const BN_MONT_CTX *mont) {
BN_CTX *ctx, BN_MONT_CTX *in_mont) {
int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2,
wvalue1, wvalue2;
int r_is_one = 1;
@@ -1356,10 +1347,10 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a_mod_m;
/* Tables of variables obtained from 'ctx' */
BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
BN_MONT_CTX *new_mont = NULL;
BN_MONT_CTX *mont = NULL;
if (!(m->d[0] & 1)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
OPENSSL_PUT_ERROR(BN, BN_mod_exp2_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits1 = BN_num_bits(p1);
@@ -1380,13 +1371,16 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
goto err;
}
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL) {
goto err;
}
if (!BN_MONT_CTX_set(mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
window1 = BN_window_bits_for_exponent_size(bits1);
@@ -1483,33 +1477,28 @@ 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;
/* works for i<0 */
while (!BN_is_bit_set(p1, i)) {
while (!BN_is_bit_set(p1, i)) /* works for i<0 */
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++;
}
}
}
@@ -1538,7 +1527,9 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
ret = 1;
err:
BN_MONT_CTX_free(new_mont);
if (in_mont == NULL && mont != NULL) {
BN_MONT_CTX_free(mont);
}
BN_CTX_end(ctx);
return ret;
}
+21 -28
View File
@@ -223,23 +223,20 @@ err:
}
/* solves ax == 1 (mod n) */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx);
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx);
BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx) {
BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM *ret = NULL;
int sign;
if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
(n->flags & BN_FLG_CONSTTIME) != 0) {
return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
return BN_mod_inverse_no_branch(out, a, n, ctx);
}
*out_no_inverse = 0;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -261,8 +258,12 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
goto err;
}
BN_one(X);
BN_zero(Y);
if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
if (BN_copy(B, a) == NULL) {
goto err;
}
if (BN_copy(A, n) == NULL) {
goto err;
}
A->neg = 0;
@@ -279,7 +280,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
* sign*Y*a == A (mod |n|).
*/
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) {
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
/* Binary inversion algorithm; requires odd modulus.
* This is faster than the general algorithm if the modulus
* is sufficiently small (about 400 .. 500 bits on 32-bit
@@ -525,8 +526,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
}
}
} else {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
OPENSSL_PUT_ERROR(BN, BN_mod_inverse, BN_R_NO_INVERSE);
goto err;
}
ret = R;
@@ -539,25 +539,16 @@ err:
return ret;
}
BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
int no_inverse;
return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
}
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
* It does not contain branches that may leak sensitive information. */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM local_A, local_B;
BIGNUM *pA, *pB;
BIGNUM *ret = NULL;
int sign;
*out_no_inverse = 0;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -579,8 +570,12 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
goto err;
}
BN_one(X);
BN_zero(Y);
if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) {
if (BN_copy(B, a) == NULL) {
goto err;
}
if (BN_copy(A, n) == NULL) {
goto err;
}
A->neg = 0;
@@ -591,9 +586,8 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
*/
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
@@ -695,8 +689,7 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
}
}
} else {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
OPENSSL_PUT_ERROR(BN, BN_mod_inverse_no_branch, BN_R_NO_INVERSE);
goto err;
}
ret = R;

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