Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 345b735e31 | |||
| 3fbc298104 | |||
| 54e455157a |
@@ -2,5 +2,3 @@ build/
|
||||
ssl/test/runner/runner
|
||||
*.swp
|
||||
*.swo
|
||||
doc/*.html
|
||||
doc/doc.css
|
||||
|
||||
@@ -1,97 +1,33 @@
|
||||
Build Prerequisites:
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
* CMake[1] 2.8.8 or later is required.
|
||||
|
||||
* Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
|
||||
have both been reported to work. If not found by CMake, it may be configured
|
||||
explicitly by setting PERL_EXECUTABLE.
|
||||
|
||||
* On Windows you currently must use Ninja[2] to build; on other platforms,
|
||||
it is not required, but recommended, because it makes builds faster.
|
||||
|
||||
* If you need to build Ninja from source, then a recent version of
|
||||
Python[3] is required (Python 2.7.5 works).
|
||||
|
||||
* On Windows only, Yasm[4] is required. If not found by CMake, it may be
|
||||
configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
|
||||
|
||||
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
|
||||
with Platform SDK 8.1 or later are supported. Recent versions of GCC and
|
||||
Clang should work on non-Windows platforms, and maybe on Windows too.
|
||||
|
||||
* Go[5] is required. If not found by CMake, the go executable may be
|
||||
configured explicitly by setting GO_EXECUTABLE.
|
||||
|
||||
Using Ninja (note the 'N' is capitalized in the cmake invocation):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja ..
|
||||
ninja
|
||||
|
||||
Using makefiles (does not work on Windows):
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
You usually don't need to run cmake again after changing CMakeLists.txt files
|
||||
because the build scripts will detect changes to them and rebuild themselves
|
||||
automatically.
|
||||
|
||||
Note that the default build flags in the top-level CMakeLists.txt are for
|
||||
Note that the default build flags in the top-leve 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
|
||||
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/32-bit-toolchain.cmake -GNinja ..
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../util/arm-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 #includes the
|
||||
BoringSSL headers.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
[1] http://www.cmake.org/download/
|
||||
|
||||
[2] https://martine.github.io/ninja/
|
||||
|
||||
[3] https://www.python.org/downloads/
|
||||
|
||||
[4] http://yasm.tortall.net/
|
||||
|
||||
[5] https://golang.org/dl/
|
||||
[1] http://martine.github.io/ninja/
|
||||
[2] http://yasm.tortall.net/
|
||||
|
||||
+20
-123
@@ -1,145 +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 -ggdb -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -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.
|
||||
"C4210" # nonstandard extension used : function given file scope
|
||||
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
# possible loss of data
|
||||
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
# possible loss of data
|
||||
"C4245" # 'initializing' : conversion from 'long' to
|
||||
# 'unsigned long', signed/unsigned mismatch
|
||||
"C4267" # conversion from 'size_t' to 'int', possible loss of data
|
||||
"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")
|
||||
# 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})
|
||||
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")
|
||||
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
add_subdirectory(crypto)
|
||||
add_subdirectory(ssl)
|
||||
add_subdirectory(ssl/test)
|
||||
add_subdirectory(tool)
|
||||
add_subdirectory(decrepit)
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
BoringSSL Style Guide.
|
||||
|
||||
BoringSSL usually follows the Google C++ style guide, found below. The
|
||||
rest of this document describes differences and clarifications on top
|
||||
of the base guide.
|
||||
|
||||
https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
|
||||
|
||||
|
||||
Legacy code.
|
||||
|
||||
As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
|
||||
that does not follow this style guide. Particularly where public API
|
||||
is concerned, balance consistency within a module with the benefits of
|
||||
a given rule. Module-wide deviations on naming should be respected
|
||||
while integer and return value conventions take precedence over
|
||||
consistency.
|
||||
|
||||
Some modules have seen few changes, so they still retain the original
|
||||
indentation style for now. When editing these, try to retain the
|
||||
original style. For Emacs, doc/c-indentation.el from OpenSSL may be
|
||||
helpful in this.
|
||||
|
||||
|
||||
Language.
|
||||
|
||||
The majority of the project is in C, so C++-specific rules in the
|
||||
Google style guide do not apply. Support for C99 features depends on
|
||||
our target platforms. Typically, Chromium's target MSVC is the most
|
||||
restrictive.
|
||||
|
||||
Variable declarations in the middle of a function are allowed.
|
||||
|
||||
Comments should be /* C-style */ for consistency.
|
||||
|
||||
When declaration pointer types, * should be placed next to the variable
|
||||
name, not the type. So
|
||||
|
||||
uint8_t *ptr;
|
||||
|
||||
not
|
||||
|
||||
uint8_t* ptr;
|
||||
|
||||
Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
|
||||
OPENSSL_free(). Use the standard C assert() function freely.
|
||||
|
||||
For new constants, prefer enums when the values are sequential and typed
|
||||
constants for flags. If adding values to an existing set of #defines, continue
|
||||
with #define.
|
||||
|
||||
|
||||
Formatting.
|
||||
|
||||
Single-statement blocks are not allowed. All conditions and loops must
|
||||
use braces:
|
||||
|
||||
if (foo) {
|
||||
do_something();
|
||||
}
|
||||
|
||||
not
|
||||
|
||||
if (foo)
|
||||
do_something();
|
||||
|
||||
|
||||
Integers.
|
||||
|
||||
Prefer using explicitly-sized integers where appropriate rather than
|
||||
generic C ones. For instance, to represent a byte, use uint8_t, not
|
||||
unsigned char. Likewise, represent a two-byte field as uint16_t, not
|
||||
unsigned short.
|
||||
|
||||
Sizes are represented as size_t.
|
||||
|
||||
Within a struct that is retained across the lifetime of an SSL
|
||||
connection, if bounds of a size are known and it's easy, use a smaller
|
||||
integer type like uint8_t. This is a "free" connection footprint
|
||||
optimization for servers. Don't make code significantly more complex
|
||||
for it, and do still check the bounds when passing in and out of the
|
||||
struct. This narrowing should not propagate to local variables and
|
||||
function parameters.
|
||||
|
||||
When doing arithmetic, account for overflow conditions.
|
||||
|
||||
Except with platform APIs, do not use ssize_t. MSVC lacks it, and
|
||||
prefer out-of-band error signaling for size_t (see Return values).
|
||||
|
||||
|
||||
Naming.
|
||||
|
||||
Follow Google naming conventions in C++ files. In C files, use the
|
||||
following naming conventions for consistency with existing OpenSSL and C
|
||||
styles:
|
||||
|
||||
Define structs with typedef named TYPE_NAME. The corresponding struct
|
||||
should be named struct type_name_st.
|
||||
|
||||
Name public functions as MODULE_function_name, unless the module
|
||||
already uses a different naming scheme for legacy reasons. The module
|
||||
name should be a type name if the function is a method of a particular
|
||||
type.
|
||||
|
||||
Some types are allocated within the library while others are
|
||||
initialized into a struct allocated by the caller, often on the
|
||||
stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
|
||||
TYPE_NAME_init/TYPE_NAME_cleanup, respectively. 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 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.
|
||||
@@ -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
|
||||
+93
-153
@@ -1,89 +1,67 @@
|
||||
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.
|
||||
@@ -126,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)
|
||||
@@ -136,95 +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: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_executable(
|
||||
thread_test
|
||||
|
||||
thread_test.c
|
||||
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(thread_test crypto)
|
||||
|
||||
add_executable(
|
||||
refcount_test
|
||||
|
||||
refcount_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(refcount_test crypto)
|
||||
perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
|
||||
perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
|
||||
|
||||
+23
-42
@@ -1,53 +1,44 @@
|
||||
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,13 +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)
|
||||
|
||||
+34
-16
@@ -525,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,
|
||||
@@ -1033,25 +1059,17 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
@@ -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>) {
|
||||
|
||||
+13
-306
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
|
||||
+252
-747
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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));
|
||||
@@ -715,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
|
||||
@@ -838,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:
|
||||
@@ -946,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
|
||||
@@ -1423,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]
|
||||
@@ -1485,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
|
||||
|
||||
@@ -1591,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:
|
||||
@@ -1602,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
|
||||
@@ -2121,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
|
||||
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-30
@@ -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,10 +87,6 @@
|
||||
# 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
|
||||
@@ -109,8 +94,6 @@
|
||||
* |cpu.h|. */
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
|
||||
#define ARMV7_NEON (1 << 0)
|
||||
|
||||
@@ -118,19 +101,9 @@ extern uint32_t OPENSSL_armcap_P;
|
||||
* The Poly1305 NEON code is known to trigger bugs in the NEON units of some
|
||||
* phones. If this bit isn't set then the Poly1305 NEON code won't be used.
|
||||
* See https://code.google.com/p/chromium/issues/detail?id=341598. */
|
||||
#define ARMV7_NEON_FUNCTIONAL (1 << 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_THREAD_H */
|
||||
|
||||
+40
-39
@@ -1,45 +1,46 @@
|
||||
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
|
||||
)
|
||||
|
||||
+8
-16
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
@@ -86,7 +86,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *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);
|
||||
}
|
||||
|
||||
|
||||
+7
-9
@@ -56,8 +56,6 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -257,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);
|
||||
@@ -327,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);
|
||||
@@ -350,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;
|
||||
@@ -413,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);
|
||||
@@ -426,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;
|
||||
@@ -449,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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
-36
@@ -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);
|
||||
@@ -176,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;
|
||||
@@ -184,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);
|
||||
}
|
||||
|
||||
@@ -426,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);
|
||||
}
|
||||
@@ -462,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;
|
||||
@@ -497,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
-20
@@ -137,7 +137,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
#endif
|
||||
if (j & 0x80)
|
||||
{
|
||||
if (BIO_puts(bp, "Error in encoding\n") <= 0)
|
||||
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
|
||||
goto end;
|
||||
ret=0;
|
||||
goto end;
|
||||
@@ -165,7 +165,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
if (j & V_ASN1_CONSTRUCTED)
|
||||
{
|
||||
ep=p+len;
|
||||
if (BIO_puts(bp, "\n") <= 0) goto end;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
if (len > length)
|
||||
{
|
||||
BIO_printf(bp,
|
||||
@@ -196,7 +196,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
else if (xclass != 0)
|
||||
{
|
||||
p+=len;
|
||||
if (BIO_puts(bp, "\n") <= 0) goto end;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,7 +210,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
(tag == V_ASN1_UTCTIME) ||
|
||||
(tag == V_ASN1_GENERALIZEDTIME))
|
||||
{
|
||||
if (BIO_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)
|
||||
@@ -221,12 +221,12 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
opp=op;
|
||||
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
|
||||
{
|
||||
if (BIO_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;
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
|
||||
if (ii < 0)
|
||||
{
|
||||
if (BIO_puts(bp, "Bad boolean\n") <= 0)
|
||||
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bp,":%d",ii);
|
||||
@@ -273,7 +273,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
if (printable)
|
||||
/* printable string */
|
||||
{
|
||||
if (BIO_puts(bp, ":") <= 0)
|
||||
if (BIO_write(bp,":",1) <= 0)
|
||||
goto end;
|
||||
if (BIO_write(bp,(const char *)opp,
|
||||
os->length) <= 0)
|
||||
@@ -283,7 +283,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
/* not printable => print octet string
|
||||
* as hex dump */
|
||||
{
|
||||
if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
|
||||
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
|
||||
goto end;
|
||||
for (i=0; i<os->length; i++)
|
||||
{
|
||||
@@ -297,7 +297,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
{
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
if (BIO_write(bp,"\n",1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (!BIO_hexdump(bp, opp,
|
||||
@@ -323,9 +323,9 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_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++)
|
||||
{
|
||||
@@ -335,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);
|
||||
@@ -355,9 +355,9 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_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++)
|
||||
{
|
||||
@@ -367,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);
|
||||
@@ -382,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,
|
||||
@@ -394,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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
|
||||
+59
-96
@@ -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);
|
||||
@@ -189,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,
|
||||
@@ -206,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;
|
||||
}
|
||||
|
||||
@@ -215,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 */
|
||||
@@ -224,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,
|
||||
@@ -255,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)
|
||||
@@ -283,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)
|
||||
@@ -298,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;
|
||||
|
||||
|
||||
@@ -306,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 */
|
||||
@@ -340,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;
|
||||
}
|
||||
|
||||
@@ -354,7 +339,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -380,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)
|
||||
@@ -394,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++)
|
||||
{
|
||||
@@ -437,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;
|
||||
@@ -479,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;
|
||||
}
|
||||
|
||||
@@ -508,7 +480,7 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -524,7 +496,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
return 0;
|
||||
}
|
||||
auxerr:
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_AUX_ERROR);
|
||||
err:
|
||||
ASN1_item_ex_free(pval, it);
|
||||
if (errtt)
|
||||
@@ -569,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 */
|
||||
@@ -593,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;
|
||||
}
|
||||
}
|
||||
@@ -603,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;
|
||||
}
|
||||
}
|
||||
@@ -627,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)
|
||||
{
|
||||
@@ -659,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)
|
||||
@@ -682,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;
|
||||
}
|
||||
|
||||
@@ -690,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;
|
||||
@@ -708,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;
|
||||
}
|
||||
}
|
||||
@@ -732,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)
|
||||
@@ -745,7 +718,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
||||
-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)
|
||||
@@ -764,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;
|
||||
@@ -775,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 */
|
||||
}
|
||||
|
||||
@@ -793,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;
|
||||
@@ -806,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)
|
||||
@@ -823,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)
|
||||
@@ -843,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;
|
||||
}
|
||||
|
||||
@@ -864,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;
|
||||
@@ -891,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;
|
||||
@@ -959,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;
|
||||
@@ -968,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
|
||||
@@ -1015,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 */
|
||||
@@ -1029,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;
|
||||
@@ -1052,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;
|
||||
@@ -1114,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)
|
||||
@@ -1125,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;
|
||||
@@ -1172,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;
|
||||
@@ -1182,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;
|
||||
}
|
||||
|
||||
@@ -1191,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,
|
||||
@@ -1204,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;
|
||||
@@ -1219,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);
|
||||
@@ -1287,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;
|
||||
}
|
||||
@@ -1296,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;
|
||||
}
|
||||
@@ -1309,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:
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
|
||||
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
|
||||
static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
|
||||
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
|
||||
NULL, 0,
|
||||
bn_new,
|
||||
bn_free,
|
||||
@@ -126,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);
|
||||
|
||||
@@ -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, <mp, sizeof(long));
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+17
-18
@@ -1,32 +1,31 @@
|
||||
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()
|
||||
|
||||
+29
-159
@@ -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,146 +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) != 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) != 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) {
|
||||
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) !=
|
||||
len - header_len) {
|
||||
OPENSSL_free(*out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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,
|
||||
|
||||
+25
-28
@@ -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>
|
||||
@@ -142,7 +136,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
case BIO_CONN_S_BEFORE:
|
||||
p = c->param_hostname;
|
||||
if (p == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
|
||||
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_HOSTNAME_SPECIFIED);
|
||||
goto exit_loop;
|
||||
}
|
||||
for (; *p != 0; p++) {
|
||||
@@ -161,13 +155,15 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
OPENSSL_free(c->param_port);
|
||||
if (c->param_port != NULL) {
|
||||
OPENSSL_free(c->param_port);
|
||||
}
|
||||
c->param_port = BUF_strdup(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->param_port == NULL) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
|
||||
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_PORT_SPECIFIED);
|
||||
ERR_add_error_data(2, "host=", c->param_hostname);
|
||||
goto exit_loop;
|
||||
}
|
||||
@@ -175,7 +171,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
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;
|
||||
}
|
||||
@@ -185,7 +181,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
|
||||
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;
|
||||
@@ -197,7 +193,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
sizeof(i));
|
||||
if (ret < 0) {
|
||||
OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
|
||||
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_KEEPALIVE);
|
||||
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
|
||||
goto exit_loop;
|
||||
}
|
||||
@@ -211,7 +207,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
bio->retry_reason = BIO_RR_CONNECT;
|
||||
} else {
|
||||
OPENSSL_PUT_SYSTEM_ERROR(connect);
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
|
||||
OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_CONNECT_ERROR);
|
||||
ERR_add_error_data(4, "host=", c->param_hostname, ":",
|
||||
c->param_port);
|
||||
}
|
||||
@@ -232,7 +228,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
|
||||
} else {
|
||||
BIO_clear_retry_flags(bio);
|
||||
OPENSSL_PUT_SYSTEM_ERROR(connect);
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
|
||||
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;
|
||||
}
|
||||
@@ -284,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);
|
||||
}
|
||||
|
||||
@@ -391,11 +391,10 @@ 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). */
|
||||
@@ -420,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;
|
||||
}
|
||||
@@ -464,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;
|
||||
|
||||
+1
-4
@@ -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>
|
||||
|
||||
+6
-7
@@ -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;
|
||||
|
||||
@@ -133,9 +132,9 @@ BIO *BIO_new_file(const char *filename, const char *mode) {
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -191,7 +190,7 @@ static int file_read(BIO *b, char *out, int outl) {
|
||||
ret = fread(out, 1, outl, (FILE *)b->ptr);
|
||||
if (ret == 0 && ferror((FILE *)b->ptr)) {
|
||||
OPENSSL_PUT_SYSTEM_ERROR(fread);
|
||||
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
|
||||
OPENSSL_PUT_ERROR(BIO, file_read, ERR_R_SYS_LIB);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@@ -253,7 +252,7 @@ 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;
|
||||
}
|
||||
@@ -261,7 +260,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
if (fp == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
peer_b->len -= bytes_read;
|
||||
assert(peer_b->len >= 0);
|
||||
assert(peer_b->offset + bytes_read <= peer_b->size);
|
||||
|
||||
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
|
||||
* offset even if buffer becomes empty, to make sure
|
||||
* write_offset = (offset + len) mod size does not change. */
|
||||
if (peer_b->offset + bytes_read == peer_b->size ||
|
||||
(!peer_b->zero_copy_write_lock && peer_b->len == 0)) {
|
||||
peer_b->offset = 0;
|
||||
} else {
|
||||
peer_b->offset += bytes_read;
|
||||
}
|
||||
|
||||
bio->num_read += bytes_read;
|
||||
peer_b->zero_copy_read_lock = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b,
|
||||
uint8_t** out_write_buf,
|
||||
size_t* out_buf_offset) {
|
||||
size_t write_offset;
|
||||
size_t max_available;
|
||||
|
||||
assert(b->len <= b->size);
|
||||
|
||||
write_offset = b->offset + b->len;
|
||||
|
||||
if (write_offset >= b->size) {
|
||||
/* Only the first half of the ring buffer can be written to. */
|
||||
write_offset -= b->size;
|
||||
/* write up to the start of the ring buffer. */
|
||||
max_available = b->offset - write_offset;
|
||||
} else {
|
||||
/* write up to the end the buffer. */
|
||||
max_available = b->size - write_offset;
|
||||
}
|
||||
|
||||
*out_write_buf = b->buf;
|
||||
*out_buf_offset = write_offset;
|
||||
return max_available;
|
||||
}
|
||||
|
||||
int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
|
||||
size_t* out_buf_offset,
|
||||
size_t* out_available_bytes) {
|
||||
struct bio_bio_st* b;
|
||||
struct bio_bio_st* peer_b;
|
||||
size_t max_available;
|
||||
|
||||
*out_available_bytes = 0;
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
if (!bio->init) {
|
||||
OPENSSL_PUT_ERROR(BIO, BIO_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);
|
||||
}
|
||||
|
||||
+3
-3
@@ -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, ...) {
|
||||
@@ -95,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
@@ -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;
|
||||
|
||||
@@ -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,8 +48,8 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
+43
-43
@@ -1,65 +1,67 @@
|
||||
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}
|
||||
)
|
||||
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)
|
||||
@@ -68,11 +70,9 @@ perlasm(x86-mont.${ASM_EXT} asm/x86-mont.pl)
|
||||
perlasm(armv4-mont.${ASM_EXT} asm/armv4-mont.pl)
|
||||
|
||||
add_executable(
|
||||
bn_test
|
||||
bn_test
|
||||
|
||||
bn_test.cc
|
||||
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
bn_test.c
|
||||
)
|
||||
|
||||
target_link_libraries(bn_test crypto)
|
||||
|
||||
+1
-1
@@ -267,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
@@ -84,10 +72,10 @@ $code=<<___;
|
||||
.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
@@ -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;
|
||||
@@ -103,7 +99,7 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
open OUT,"| $^X $xlate $flavour $output";
|
||||
*STDOUT = *OUT;
|
||||
|
||||
if ($avx>1) {{{
|
||||
|
||||
@@ -95,7 +95,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
open OUT,"| $^X $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
|
||||
+93
-75
@@ -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
-20
@@ -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);
|
||||
}
|
||||
|
||||
@@ -200,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
|
||||
@@ -279,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+56
-150
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
+13
-18
@@ -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;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
#ifdef BN_LLONG
|
||||
BN_ULLONG t2;
|
||||
|
||||
#if defined(BN_LLONG) && !defined(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,14 +278,12 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
t2 = (BN_ULLONG)d1 * q;
|
||||
|
||||
for (;;) {
|
||||
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
|
||||
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2]))
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0) {
|
||||
if (rem < d0)
|
||||
break; /* don't let rem overflow */
|
||||
}
|
||||
t2 -= d1;
|
||||
}
|
||||
#else /* !BN_LLONG */
|
||||
@@ -318,17 +316,14 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
|
||||
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0) {
|
||||
if (rem < d0)
|
||||
break; /* don't let rem overflow */
|
||||
}
|
||||
if (t2l < d1) {
|
||||
if (t2l < d1)
|
||||
t2h--;
|
||||
}
|
||||
t2l -= d1;
|
||||
}
|
||||
#endif /* !BN_LLONG */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+89
-113
@@ -109,7 +109,6 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -131,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;
|
||||
}
|
||||
|
||||
@@ -172,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;
|
||||
}
|
||||
@@ -333,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))) {
|
||||
@@ -418,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' */
|
||||
@@ -427,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;
|
||||
}
|
||||
|
||||
@@ -487,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)) {
|
||||
@@ -545,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;
|
||||
@@ -603,7 +601,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
||||
|
||||
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
|
||||
int i, j, bits, ret = 0, wstart, window;
|
||||
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
|
||||
int start = 1;
|
||||
BIGNUM *d, *r;
|
||||
const BIGNUM *aa;
|
||||
@@ -616,7 +614,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -682,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. */
|
||||
@@ -703,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;
|
||||
@@ -720,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++) {
|
||||
@@ -751,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;
|
||||
@@ -763,7 +761,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (in_mont == NULL) {
|
||||
if (in_mont == NULL && mont != NULL) {
|
||||
BN_MONT_CTX_free(mont);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
@@ -865,7 +863,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
top = m->top;
|
||||
|
||||
if (!(m->d[0] & 1)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_consttime,
|
||||
BN_R_CALLED_WITH_EVEN_MODULUS);
|
||||
return 0;
|
||||
}
|
||||
bits = BN_num_bits(p);
|
||||
@@ -877,14 +876,15 @@ 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 this is not done, things will break in the montgomery part. */
|
||||
if (in_mont != NULL) {
|
||||
* 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 || !BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
else {
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set(mont, m, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RSAZ_ENABLED
|
||||
@@ -893,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;
|
||||
@@ -903,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;
|
||||
@@ -920,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.
|
||||
@@ -934,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 */
|
||||
@@ -967,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,
|
||||
@@ -1010,20 +1001,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* BN_to_montgomery can contaminate words above .top
|
||||
* [in BN_DEBUG[_DEBUG] build]... */
|
||||
for (i = am.top; i < top; i++) {
|
||||
for (i = am.top; i < top; i++)
|
||||
am.d[i] = 0;
|
||||
}
|
||||
for (i = tmp.top; i < top; i++) {
|
||||
for (i = tmp.top; i < top; i++)
|
||||
tmp.d[i] = 0;
|
||||
}
|
||||
|
||||
if (top & 7) {
|
||||
if (top & 7)
|
||||
np2 = np;
|
||||
} else {
|
||||
for (np2 = am.d + top, i = 0; i < top; i++) {
|
||||
else
|
||||
for (np2 = am.d + top, i = 0; i < top; i++)
|
||||
np2[2 * i] = np[i];
|
||||
}
|
||||
}
|
||||
|
||||
bn_scatter5(tmp.d, top, powerbuf, 0);
|
||||
bn_scatter5(am.d, am.top, powerbuf, 1);
|
||||
@@ -1056,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
|
||||
@@ -1070,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);
|
||||
@@ -1116,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)
|
||||
@@ -1135,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.
|
||||
@@ -1164,36 +1146,32 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* Scan the window, squaring the result as we go */
|
||||
for (i = 0; i < window; i++, bits--) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
|
||||
}
|
||||
|
||||
/* Fetch the appropriate pre-computed value from the pre-buf */
|
||||
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
|
||||
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Multiply the result into the intermediate result */
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the final result from montgomery to standard format */
|
||||
if (!BN_from_montgomery(rr, &tmp, mont, ctx)) {
|
||||
if (!BN_from_montgomery(rr, &tmp, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (in_mont == NULL) {
|
||||
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);
|
||||
@@ -1221,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;
|
||||
}
|
||||
|
||||
@@ -1259,11 +1238,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (in_mont != NULL) {
|
||||
if (in_mont != NULL)
|
||||
mont = in_mont;
|
||||
} else {
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
else {
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (!BN_MONT_CTX_set(mont, m, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -1347,7 +1328,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (in_mont == NULL) {
|
||||
if (in_mont == NULL && mont != NULL) {
|
||||
BN_MONT_CTX_free(mont);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
@@ -1369,7 +1350,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
|
||||
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);
|
||||
@@ -1496,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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1551,7 +1527,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (in_mont == NULL) {
|
||||
if (in_mont == NULL && mont != NULL) {
|
||||
BN_MONT_CTX_free(mont);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
+13
-6
@@ -258,8 +258,12 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
|
||||
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;
|
||||
@@ -522,7 +526,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_inverse, BN_R_NO_INVERSE);
|
||||
goto err;
|
||||
}
|
||||
ret = R;
|
||||
@@ -566,8 +570,12 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, 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;
|
||||
@@ -578,9 +586,8 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
|
||||
*/
|
||||
pB = &local_B;
|
||||
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
if (!BN_nnmod(B, pB, A, ctx)) {
|
||||
if (!BN_nnmod(B, pB, A, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
@@ -682,7 +689,7 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
|
||||
+207
-144
@@ -130,8 +130,40 @@
|
||||
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
#define mul_add(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULONG high, low, ret, tmp = (a); \
|
||||
ret = (r); \
|
||||
high = BN_UMULT_HIGH(w, tmp); \
|
||||
ret += (c); \
|
||||
low = (w) * tmp; \
|
||||
(c) = (ret < (c)) ? 1 : 0; \
|
||||
(c) += high; \
|
||||
ret += low; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
|
||||
#define mul(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULONG high, low, ret, ta = (a); \
|
||||
low = (w) * ta; \
|
||||
high = BN_UMULT_HIGH(w, ta); \
|
||||
ret = low + (c); \
|
||||
(c) = high; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
|
||||
#define sqr(r0, r1, a) \
|
||||
{ \
|
||||
BN_ULONG tmp = (a); \
|
||||
(r0) = tmp * tmp; \
|
||||
(r1) = BN_UMULT_HIGH(tmp, tmp); \
|
||||
}
|
||||
|
||||
#else
|
||||
/*************************************************************
|
||||
* No long long type
|
||||
*/
|
||||
@@ -392,7 +424,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
|
||||
#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
|
||||
|
||||
#if defined(BN_LLONG)
|
||||
#if defined(BN_LLONG) && defined(BN_DIV2W)
|
||||
|
||||
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
|
||||
@@ -470,7 +502,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
@@ -585,27 +617,23 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
t1 = a[0];
|
||||
t2 = b[0];
|
||||
r[0] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[1];
|
||||
t2 = b[1];
|
||||
r[1] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[2];
|
||||
t2 = b[2];
|
||||
r[2] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
c = (t1 < t2);
|
||||
}
|
||||
t1 = a[3];
|
||||
t2 = b[3];
|
||||
r[3] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
c = (t1 < t2);
|
||||
}
|
||||
a += 4;
|
||||
b += 4;
|
||||
r += 4;
|
||||
@@ -615,9 +643,8 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
t1 = a[0];
|
||||
t2 = b[0];
|
||||
r[0] = (t1 - t2 - c) & BN_MASK2;
|
||||
if (t1 != t2) {
|
||||
if (t1 != t2)
|
||||
c = (t1 < t2);
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
r++;
|
||||
@@ -632,151 +659,175 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
/* Keep in mind that additions to multiplication result can not overflow,
|
||||
* because its high half cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
tt = (t + t) & BN_MASK; \
|
||||
if (tt < t) \
|
||||
c2++; \
|
||||
t1 = (BN_ULONG)Lw(tt); \
|
||||
t2 = (BN_ULONG)Hw(tt); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
BN_ULLONG tt = t + c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(tt); \
|
||||
hi = (BN_ULONG)Hw(tt); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_LOHI)
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because the high word of
|
||||
* a multiplication result cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
BN_UMULT_LOHI(t1, t2, 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) \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_ULONG lo, hi, tt; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
tt = hi + ((c0 < lo) ? 1 : 0); \
|
||||
c1 += tt; \
|
||||
c2 += (c1 < tt) ? 1 : 0; \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
BN_UMULT_LOHI(t0, t1, ta, tb); \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
{ \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, ta); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
BN_UMULT_LOHI(t1, t2, ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
t1 = ta * tb; \
|
||||
t2 = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
t1 = BN_UMULT_HIGH(ta, tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
t1 = ta * ta; \
|
||||
t2 = BN_UMULT_HIGH(ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
* the high word of a multiplication result cannot be all-ones. */
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG tt; \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
tt = hi; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
tt++; \
|
||||
c1 = (c1 + tt) & BN_MASK2; \
|
||||
if (c1 < tt) \
|
||||
c2++; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
if (t2 & BN_TBIT) \
|
||||
c2++; \
|
||||
t2 = (t2 + t2) & BN_MASK2; \
|
||||
if (t1 & BN_TBIT) \
|
||||
t2++; \
|
||||
t1 = (t1 + t1) & BN_MASK2; \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG lo, hi; \
|
||||
sqr64(lo, hi, (a)[i]); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
sqr64(t1, t2, (a)[i]); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
#endif /* !BN_LLONG */
|
||||
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -879,6 +930,12 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -917,6 +974,12 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -991,6 +1054,12 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -1055,13 +1124,11 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
#ifdef mul64
|
||||
mh = HBITS(ml);
|
||||
ml = LBITS(ml);
|
||||
for (j = 0; j < num; ++j) {
|
||||
for (j = 0; j < num; ++j)
|
||||
mul(tp[j], ap[j], ml, mh, c0);
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < num; ++j) {
|
||||
for (j = 0; j < num; ++j)
|
||||
mul(tp[j], ap[j], ml, c0);
|
||||
}
|
||||
#endif
|
||||
|
||||
tp[num] = c0;
|
||||
@@ -1074,13 +1141,11 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
#ifdef mul64
|
||||
mh = HBITS(ml);
|
||||
ml = LBITS(ml);
|
||||
for (j = 0; j < num; ++j) {
|
||||
for (j = 0; j < num; ++j)
|
||||
mul_add(tp[j], ap[j], ml, mh, c0);
|
||||
}
|
||||
#else
|
||||
for (j = 0; j < num; ++j) {
|
||||
for (j = 0; j < num; ++j)
|
||||
mul_add(tp[j], ap[j], ml, c0);
|
||||
}
|
||||
#endif
|
||||
c1 = (tp[num] + c0) & BN_MASK2;
|
||||
tp[num] = c1;
|
||||
@@ -1113,15 +1178,13 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
|
||||
c0 = bn_sub_words(rp, tp, np, num);
|
||||
if (tp[num] != 0 || c0 == 0) {
|
||||
for (i = 0; i < num + 2; i++) {
|
||||
for (i = 0; i < num + 2; i++)
|
||||
vp[i] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < num; i++) {
|
||||
for (i = 0; i < num; i++)
|
||||
rp[i] = tp[i], vp[i] = 0;
|
||||
}
|
||||
vp[num] = 0;
|
||||
vp[num + 1] = 0;
|
||||
return 1;
|
||||
|
||||
+21
-32
@@ -125,31 +125,20 @@
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#pragma warning(push, 3)
|
||||
#include <intrin.h>
|
||||
#pragma warning(pop)
|
||||
#pragma intrinsic(__umulh, _umul128)
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather
|
||||
/* bn_expand acts the same as |BN_wexpand|, but takes a number of bits rather
|
||||
* than a number of words. */
|
||||
BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
|
||||
|
||||
#if defined(OPENSSL_64_BIT)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
/* MSVC doesn't support two-word integers on 64-bit. */
|
||||
#define BN_LLONG __int128_t
|
||||
#define BN_ULLONG __uint128_t
|
||||
#endif
|
||||
|
||||
#define BN_ULLONG unsigned long long
|
||||
#define BN_BITS 128
|
||||
#define BN_BITS2 64
|
||||
#define BN_BYTES 8
|
||||
#define BN_BITS4 32
|
||||
#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
|
||||
@@ -159,15 +148,16 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_MASK2h1 (0xffffffff80000000L)
|
||||
#define BN_TBIT (0x8000000000000000L)
|
||||
#define BN_DEC_CONV (10000000000000000000UL)
|
||||
#define BN_DEC_FMT1 "%" PRIu64
|
||||
#define BN_DEC_FMT2 "%019" PRIu64
|
||||
#define BN_DEC_NUM 19
|
||||
#define BN_HEX_FMT1 "%" PRIx64
|
||||
|
||||
#elif defined(OPENSSL_32_BIT)
|
||||
|
||||
#define BN_LLONG int64_t
|
||||
#define BN_ULLONG uint64_t
|
||||
#define BN_MASK (0xffffffffffffffffLL)
|
||||
#define BN_ULLONG unsigned long long
|
||||
#define BN_MASK (0xffffffffffffffffLL)
|
||||
#define BN_BITS 64
|
||||
#define BN_BITS2 32
|
||||
#define BN_BYTES 4
|
||||
#define BN_BITS4 16
|
||||
#define BN_MASK2 (0xffffffffL)
|
||||
@@ -176,7 +166,10 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_MASK2h (0xffff0000L)
|
||||
#define BN_TBIT (0x80000000L)
|
||||
#define BN_DEC_CONV (1000000000L)
|
||||
#define BN_DEC_FMT1 "%" PRIu32
|
||||
#define BN_DEC_FMT2 "%09" PRIu32
|
||||
#define BN_DEC_NUM 9
|
||||
#define BN_HEX_FMT1 "%" PRIx32
|
||||
|
||||
#else
|
||||
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
|
||||
@@ -190,11 +183,6 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
|
||||
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
|
||||
|
||||
#if defined(BN_LLONG)
|
||||
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
|
||||
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
|
||||
#endif
|
||||
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
|
||||
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
|
||||
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
|
||||
@@ -220,8 +208,6 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
|
||||
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
||||
|
||||
#if !defined(BN_LLONG)
|
||||
|
||||
#define LBITS(a) ((a) & BN_MASK2l)
|
||||
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
|
||||
#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
|
||||
@@ -252,10 +238,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
(h) = ht; \
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
|
||||
# if defined(__GNUC__) && __GNUC__ >= 2
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
# define BN_UMULT_HIGH(a,b) ({ \
|
||||
register BN_ULONG ret,discard; \
|
||||
__asm__ ("mulq %3" \
|
||||
@@ -268,9 +252,14 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
: "=a"(low),"=d"(high) \
|
||||
: "a"(a),"g"(b) \
|
||||
: "cc");
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# define BN_UMULT_HIGH(a, b) __umulh((a), (b))
|
||||
# define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
|
||||
# endif
|
||||
# if defined(_MSC_VER) && _MSC_VER>=1400
|
||||
unsigned __int64 __umulh (unsigned __int64 a,unsigned __int64 b);
|
||||
unsigned __int64 _umul128 (unsigned __int64 a,unsigned __int64 b,
|
||||
unsigned __int64 *h);
|
||||
# pragma intrinsic(__umulh,_umul128)
|
||||
# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
|
||||
# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
|
||||
# endif
|
||||
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
|
||||
+32
-34
@@ -108,14 +108,10 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/thread.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
@@ -177,11 +173,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
|
||||
BIGNUM tmod;
|
||||
BN_ULONG buf[2];
|
||||
|
||||
if (BN_is_zero(mod)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
Ri = BN_CTX_get(ctx);
|
||||
if (Ri == NULL) {
|
||||
@@ -299,36 +290,44 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
|
||||
const BIGNUM *mod, BN_CTX *bn_ctx) {
|
||||
CRYPTO_MUTEX_lock_read(lock);
|
||||
BN_MONT_CTX *ctx = *pmont;
|
||||
CRYPTO_MUTEX_unlock(lock);
|
||||
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
|
||||
const BIGNUM *mod, BN_CTX *ctx) {
|
||||
BN_MONT_CTX *ret;
|
||||
|
||||
if (ctx) {
|
||||
return ctx;
|
||||
CRYPTO_r_lock(lock);
|
||||
ret = *pmont;
|
||||
CRYPTO_r_unlock(lock);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
CRYPTO_MUTEX_lock_write(lock);
|
||||
ctx = *pmont;
|
||||
if (ctx) {
|
||||
goto out;
|
||||
/* We don't want to serialise globally while doing our lazy-init math in
|
||||
* BN_MONT_CTX_set. That punishes threads that are doing independent
|
||||
* things. Instead, punish the case where more than one thread tries to
|
||||
* lazy-init the same 'pmont', by having each do the lazy-init math work
|
||||
* independently and only use the one from the thread that wins the race
|
||||
* (the losers throw away the work they've done). */
|
||||
ret = BN_MONT_CTX_new();
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
if (!BN_MONT_CTX_set(ret, mod, ctx)) {
|
||||
BN_MONT_CTX_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = BN_MONT_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
goto out;
|
||||
/* The locked compare-and-set, after the local work is done. */
|
||||
CRYPTO_w_lock(lock);
|
||||
if (*pmont) {
|
||||
BN_MONT_CTX_free(ret);
|
||||
ret = *pmont;
|
||||
} else {
|
||||
*pmont = ret;
|
||||
}
|
||||
if (!BN_MONT_CTX_set(ctx, mod, bn_ctx)) {
|
||||
BN_MONT_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
goto out;
|
||||
}
|
||||
*pmont = ctx;
|
||||
|
||||
out:
|
||||
CRYPTO_MUTEX_unlock(lock);
|
||||
return ctx;
|
||||
CRYPTO_w_unlock(lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
|
||||
@@ -513,9 +512,8 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_copy(t, a)) {
|
||||
if (BN_copy(t, a))
|
||||
retn = BN_from_montgomery_word(ret, t, mont);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return retn;
|
||||
|
||||
+6
-9
@@ -57,7 +57,6 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -150,9 +149,8 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
|
||||
assert(cl >= 0);
|
||||
c = bn_sub_words(r, a, b, cl);
|
||||
|
||||
if (dl == 0) {
|
||||
if (dl == 0)
|
||||
return c;
|
||||
}
|
||||
|
||||
r += cl;
|
||||
a += cl;
|
||||
@@ -331,9 +329,8 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
|
||||
/* Else do normal multiply */
|
||||
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
|
||||
bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
|
||||
if ((dna + dnb) < 0) {
|
||||
if ((dna + dnb) < 0)
|
||||
memset(&r[2 * n2 + dna + dnb], 0, sizeof(BN_ULONG) * -(dna + dnb));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -666,8 +663,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
|
||||
end:
|
||||
bn_correct_top(rr);
|
||||
if (r != rr && !BN_copy(r, rr)) {
|
||||
goto err;
|
||||
if (r != rr) {
|
||||
BN_copy(r, rr);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
@@ -877,8 +874,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
|
||||
rr->top = max;
|
||||
}
|
||||
|
||||
if (rr != r && !BN_copy(r, rr)) {
|
||||
goto err;
|
||||
if (rr != r) {
|
||||
BN_copy(r, rr);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
|
||||
+513
-518
File diff suppressed because it is too large
Load Diff
+14
-15
@@ -108,8 +108,6 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/rand.h>
|
||||
@@ -134,17 +132,16 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
|
||||
|
||||
buf = OPENSSL_malloc(bytes);
|
||||
if (buf == NULL) {
|
||||
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_rand, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Make a random number and set the top and bottom bits. */
|
||||
if (!RAND_bytes(buf, bytes)) {
|
||||
/* make a random number and set the top and bottom bits */
|
||||
if (RAND_pseudo_bytes(buf, bytes) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (top != -1) {
|
||||
if (top && bits > 1) {
|
||||
if (top) {
|
||||
if (bit == 0) {
|
||||
buf[0] = 1;
|
||||
buf[1] |= 0x80;
|
||||
@@ -186,7 +183,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
|
||||
unsigned count = 100;
|
||||
|
||||
if (range->neg || BN_is_zero(range)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_INVALID_RANGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -219,7 +216,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
|
||||
}
|
||||
|
||||
if (!--count) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
|
||||
OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
|
||||
return 0;
|
||||
}
|
||||
} while (BN_cmp(r, range) >= 0);
|
||||
@@ -231,7 +228,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
|
||||
}
|
||||
|
||||
if (!--count) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
|
||||
OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
|
||||
return 0;
|
||||
}
|
||||
} while (BN_cmp(r, range) >= 0);
|
||||
@@ -264,13 +261,13 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
|
||||
}
|
||||
|
||||
if (BN_is_zero(range)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
|
||||
OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_DIV_BY_ZERO);
|
||||
goto err;
|
||||
}
|
||||
|
||||
k_bytes = OPENSSL_malloc(num_k_bytes);
|
||||
if (!k_bytes) {
|
||||
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -281,7 +278,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
|
||||
/* No reasonable DSA or ECDSA key should have a private key
|
||||
* this large and we don't handle this case in order to avoid
|
||||
* leaking the length of the private key. */
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_PRIVATE_KEY_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
memcpy(private_bytes, priv->d, todo);
|
||||
@@ -289,7 +286,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
|
||||
|
||||
for (attempt = 0;; attempt++) {
|
||||
for (done = 0; done < num_k_bytes;) {
|
||||
if (!RAND_bytes(random_bytes, sizeof(random_bytes))) {
|
||||
if (RAND_pseudo_bytes(random_bytes, sizeof(random_bytes)) != 1) {
|
||||
goto err;
|
||||
}
|
||||
SHA512_Init(&sha);
|
||||
@@ -321,6 +318,8 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(k_bytes);
|
||||
if (k_bytes) {
|
||||
OPENSSL_free(k_bytes);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+28
-40
@@ -1,44 +1,32 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2012, Intel Corporation *
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions are *
|
||||
* met: *
|
||||
* *
|
||||
* * Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* * Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the *
|
||||
* distribution. *
|
||||
* *
|
||||
* * Neither the name of the Intel Corporation nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY *
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR *
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
/******************************************************************************
|
||||
* Copyright(c) 2012, Intel Corp.
|
||||
* Developers and authors:
|
||||
* Shay Gueron (1, 2), and Vlad Krasnov (1)
|
||||
* (1) Intel Corporation, Israel Development Center, Haifa, Israel
|
||||
* (2) University of Haifa, Israel
|
||||
******************************************************************************
|
||||
* Developers and authors: *
|
||||
* Shay Gueron (1, 2), and Vlad Krasnov (1) *
|
||||
* (1) Intel Corporation, Israel Development Center, Haifa, Israel *
|
||||
* (2) University of Haifa, Israel *
|
||||
*****************************************************************************/
|
||||
* LICENSE:
|
||||
* This submission to OpenSSL is to be made available under the OpenSSL
|
||||
* license, and only to the OpenSSL project, in order to allow integration
|
||||
* into the publicly distributed code.
|
||||
* The use of this code, or portions of this code, or concepts embedded in
|
||||
* this code, or modification of this code and/or algorithm(s) in it, or the
|
||||
* use of this code for any other purpose than stated above, requires special
|
||||
* licensing.
|
||||
******************************************************************************
|
||||
* DISCLAIMER:
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS AND THE COPYRIGHT OWNERS
|
||||
* ``AS IS''. ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS OR THE COPYRIGHT
|
||||
* OWNERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef RSAZ_EXP_H
|
||||
#define RSAZ_EXP_H
|
||||
|
||||
@@ -56,23 +56,13 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
|
||||
int i, nw, lb, rb;
|
||||
BN_ULONG *t, *f;
|
||||
BN_ULONG l;
|
||||
|
||||
if (n < 0) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r->neg = a->neg;
|
||||
nw = n / BN_BITS2;
|
||||
if (bn_wexpand(r, a->top + nw + 1) == NULL) {
|
||||
@@ -137,11 +127,6 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
|
||||
BN_ULONG *t, *f;
|
||||
BN_ULONG l, tmp;
|
||||
|
||||
if (n < 0) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nw = n / BN_BITS2;
|
||||
rb = n % BN_BITS2;
|
||||
lb = BN_BITS2 - rb;
|
||||
|
||||
+13
-13
@@ -86,7 +86,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
}
|
||||
if (r == 0) {
|
||||
/* m divides p */
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
|
||||
goto end;
|
||||
}
|
||||
} while (r == 1 && ++i < 82);
|
||||
@@ -271,7 +271,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
* Even if p is not prime, we should have found some y
|
||||
* such that r == -1.
|
||||
*/
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_TOO_MANY_ITERATIONS);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
goto end;
|
||||
}
|
||||
if (BN_is_one(y)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
while (!BN_is_one(t)) {
|
||||
i++;
|
||||
if (i == e) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
|
||||
goto end;
|
||||
}
|
||||
if (!BN_mod_mul(t, t, t, p, ctx)) {
|
||||
@@ -413,14 +413,14 @@ vrfy:
|
||||
}
|
||||
|
||||
if (!err && 0 != BN_cmp(x, A)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (err) {
|
||||
if (ret != in) {
|
||||
if (ret != NULL && ret != in) {
|
||||
BN_clear_free(ret);
|
||||
}
|
||||
ret = NULL;
|
||||
@@ -434,7 +434,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
|
||||
int ok = 0, last_delta_valid = 0;
|
||||
|
||||
if (in->neg) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
|
||||
OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NEGATIVE_NUMBER);
|
||||
return 0;
|
||||
}
|
||||
if (BN_is_zero(in)) {
|
||||
@@ -452,7 +452,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
|
||||
last_delta = BN_CTX_get(ctx);
|
||||
delta = BN_CTX_get(ctx);
|
||||
if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
|
||||
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
|
||||
!BN_sqr(tmp, estimate, ctx) ||
|
||||
/* |delta| = |in| - |tmp| */
|
||||
!BN_sub(delta, in, tmp)) {
|
||||
OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
|
||||
OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -490,15 +490,15 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
|
||||
}
|
||||
|
||||
if (BN_cmp(tmp, in) != 0) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
|
||||
OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NOT_A_SQUARE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
|
||||
ok = 0;
|
||||
if (ok && out_sqrt == in) {
|
||||
BN_copy(out_sqrt, estimate);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
return ok;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user