Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b87c803006 | |||
| 57cfbea68c | |||
| e1cc35e581 | |||
| 2b02f4b67d | |||
| d0d532f169 | |||
| 6929f27ed5 | |||
| 71186e85d1 | |||
| 0b8f85ebe5 | |||
| ba28dfc381 | |||
| 53210cb48e | |||
| ea80f9d5df | |||
| 75f9914e17 | |||
| 1e21e994ec | |||
| bca451e085 | |||
| e36888d91a | |||
| dde19c6cdb | |||
| 4a9313a7e7 | |||
| 28d1dc8c51 | |||
| c5665c9ac9 | |||
| b8d74f5b6a | |||
| d5ff2f93ba | |||
| fd06601340 | |||
| 9b63f2964d | |||
| dfb4138197 | |||
| ffb1107c91 | |||
| 32b47a5e35 | |||
| a833c357ed | |||
| ced9479fd1 | |||
| e8b554dff8 | |||
| 2c51645c59 | |||
| e6f2221423 | |||
| 49b5038b77 | |||
| eab773a8aa | |||
| 076ade5218 | |||
| 78476f6065 | |||
| ba1660b282 | |||
| 5eead165fc | |||
| 8499621d21 | |||
| a380f9d199 | |||
| e4f96d615c | |||
| 45c844adbe | |||
| 231a475355 | |||
| 126fa278f8 | |||
| 7f2ee3522d | |||
| 14c7e8d282 | |||
| c5ac2b6c78 | |||
| a983b4c248 | |||
| b348897a02 | |||
| da4789e412 | |||
| 4e41926774 | |||
| 54955fe711 | |||
| ec978dd812 | |||
| da86360852 | |||
| 864c88799b | |||
| d50f1c8e3d | |||
| 123db57009 | |||
| e75cc2766c | |||
| 0a011fc49f | |||
| 8e816eb7b6 | |||
| 5b7b09cfca | |||
| 0f31ac7566 | |||
| 11a7b3c2d9 | |||
| 3c51d9b1b9 | |||
| c034e2d3ce | |||
| dda85e85a0 | |||
| d2cb1c19e2 | |||
| 9ec3798236 | |||
| abbbee10ad | |||
| fb73e97292 | |||
| 7bb1d292cb | |||
| 4199b0d190 | |||
| 7bb88bb686 | |||
| 9ef31f01af | |||
| b2e2e32c35 | |||
| 997c706d43 | |||
| 489833160b | |||
| 1e5ac5d502 | |||
| af3b8a990c | |||
| 70aba26c75 | |||
| af3b3d397e | |||
| 74df74b98f | |||
| f85d323114 | |||
| 6f73379114 | |||
| cec45b7e43 | |||
| 4b0d0e4c5e | |||
| ea213d1f0b | |||
| b917909336 | |||
| 8b176716e9 | |||
| d547f55971 | |||
| 0d211bdc4b | |||
| 305e6fb7f7 | |||
| 5e393fedef | |||
| 9ef99d5656 | |||
| 1b22f85a56 | |||
| b6b6ff3bef | |||
| 3a322f5e48 | |||
| 9415a14acf | |||
| a1bbacac51 | |||
| 351af19bb0 | |||
| c6722cd6e0 | |||
| 35c8afd314 | |||
| 193c2fff53 | |||
| a7f56f0bfb | |||
| be941d4659 | |||
| 0cce863f74 | |||
| 079b394c49 | |||
| afdbb62de2 | |||
| fc4467e568 | |||
| 7784c4c4dd | |||
| 9559401473 | |||
| c984611d2d | |||
| 60a85cb5e4 | |||
| 373a6a5a7d | |||
| 46dd8ec993 | |||
| 3ef7697ed3 | |||
| b1133e9565 | |||
| 840445d406 | |||
| 99dce54031 | |||
| 89917a5c60 | |||
| e228bd299d | |||
| 2c62fe9c58 | |||
| ac9a7f6384 | |||
| cef36f0cf6 | |||
| 52db0eb46c | |||
| 4c0e6c64b6 | |||
| 1991af6900 | |||
| ab6306bcb6 | |||
| a128a55e0b | |||
| 3baa6e153b | |||
| c4aa727e73 | |||
| 0939f80c6a | |||
| 490469f850 | |||
| 4fec04b484 | |||
| 8404bdb9a6 | |||
| 53a2dfcb1f | |||
| 1db9e1bc7a | |||
| 5d9ba81b6c | |||
| deb2a8769d | |||
| 52bf690ba4 | |||
| 34941c0cab | |||
| 49ddf41557 | |||
| ced00b4258 | |||
| a4c8ff0190 | |||
| 43612b6bc7 | |||
| f04976ba25 | |||
| 9d0b4bcb92 | |||
| 938fa7cc84 | |||
| 34de91e377 | |||
| b74b08144e | |||
| f5d2cd0808 | |||
| a048678cd6 | |||
| 1286beef94 | |||
| 1a5e8ecd64 | |||
| 49cdd46991 | |||
| 3cbdc34619 | |||
| 93d242bdea | |||
| 4f4e0dda3b | |||
| 7f78df470b | |||
| 803c77a681 | |||
| 5b9860827f | |||
| 5ecb88b95b | |||
| 3871dc9e39 | |||
| 8c29e7dfb4 | |||
| daa8850c83 | |||
| 6dbde984a2 | |||
| 97227dc52d | |||
| 3e9e043229 | |||
| 455919dda2 | |||
| 1f53747baa | |||
| ad75a661bf | |||
| 592b532dda | |||
| 7f0965a66d | |||
| f139c9957c | |||
| f99f2448bd | |||
| 0aecbcf62e | |||
| 54afdab584 | |||
| 31f5b3c605 | |||
| 0838721264 | |||
| 7b9bbd9639 | |||
| 1b0bd28275 | |||
| 5fd1807d95 | |||
| a252b34d66 | |||
| b6f6927cac |
+15
-9
@@ -47,6 +47,9 @@ elseif(MSVC)
|
||||
"C4127" # conditional expression is constant
|
||||
"C4200" # nonstandard extension used : zero-sized array in
|
||||
# struct/union.
|
||||
"C4204" # nonstandard extension used: non-constant aggregate initializer
|
||||
"C4221" # nonstandard extension used : 'identifier' : cannot be
|
||||
# initialized using address of automatic variable
|
||||
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
# possible loss of data
|
||||
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
|
||||
@@ -121,12 +124,17 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
if(FUZZ)
|
||||
if(!CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
message("You need to build with Clang for fuzzing to work")
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
message(FATAL_ERROR "You need to build with Clang for fuzzing to work")
|
||||
endif()
|
||||
|
||||
add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
set(RUNNER_ARGS "-fuzzer")
|
||||
add_definitions(-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE)
|
||||
set(RUNNER_ARGS "-deterministic")
|
||||
|
||||
if(NOT NO_FUZZER_MODE)
|
||||
add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
set(RUNNER_ARGS ${RUNNER_ARGS} "-fuzzer" "-shim-config" "fuzzer_mode.json")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
|
||||
@@ -160,14 +168,12 @@ elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
|
||||
set(ARCH "x86")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
|
||||
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")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm*")
|
||||
set(ARCH "arm")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
set(ARCH "aarch64")
|
||||
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "mips")
|
||||
# Just to avoid the “unknown processor” error.
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
+22
-29
@@ -30,15 +30,16 @@ The arguments to `jobs` and `workers` should be the number of cores that you wis
|
||||
|
||||
The recommended values of `max_len` for each test are:
|
||||
|
||||
| Test | `max_len` value |
|
||||
|------------|-----------------|
|
||||
| `cert` | 3072 |
|
||||
| `client` | 20000 |
|
||||
| `pkcs8` | 2048 |
|
||||
| `privkey` | 2048 |
|
||||
| `server` | 4096 |
|
||||
| `spki` | 1024 |
|
||||
| `read_pem` | 512 |
|
||||
| Test | `max_len` value |
|
||||
|---------------|-----------------|
|
||||
| `cert` | 3072 |
|
||||
| `client` | 20000 |
|
||||
| `pkcs8` | 2048 |
|
||||
| `privkey` | 2048 |
|
||||
| `server` | 4096 |
|
||||
| `spki` | 1024 |
|
||||
| `read_pem` | 512 |
|
||||
| `ssl_ctx_api` | 256 |
|
||||
|
||||
These were determined by rounding up the length of the largest case in the corpus.
|
||||
|
||||
@@ -52,39 +53,31 @@ In order to minimise all the corpuses, build for fuzzing and run `./fuzz/minimis
|
||||
|
||||
## Fuzzer mode
|
||||
|
||||
When `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` defined. This modifies the library, particularly the TLS stack, to be more friendly to fuzzers. It will:
|
||||
When `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` and `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` defined. This modifies the library to be more friendly to fuzzers. If `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` is set, BoringSSL will:
|
||||
|
||||
* Replace `RAND_bytes` with a deterministic PRNG. Call `RAND_reset_for_fuzzing()` at the start of fuzzers which use `RAND_bytes` to reset the PRNG state.
|
||||
|
||||
* Use a hard-coded time instead of the actual time.
|
||||
|
||||
Additionally, if `BORINGSSL_UNSAFE_FUZZER_MODE` is set, BoringSSL will:
|
||||
|
||||
* Modify the TLS stack to perform all signature checks (CertificateVerify and ServerKeyExchange) and the Finished check, but always act as if the check succeeded.
|
||||
|
||||
* Treat every cipher as the NULL cipher.
|
||||
|
||||
* Use a hard-coded time instead of the actual time.
|
||||
|
||||
* Tickets are unencrypted and the MAC check is performed but ignored.
|
||||
|
||||
This is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
|
||||
|
||||
## TLS transcripts
|
||||
|
||||
The `client` and `server` corpora are seeded from the test suite. The test suite has a `-fuzzer` flag which mirrors the fuzzer mode changes above and a `-deterministic` flag which removes all non-determinism on the Go side. Not all tests pass, so `ssl/test/runner/fuzzer_mode.json` contains the necessary suppressions. To run the tests against a fuzzer-mode `bssl_shim`, run:
|
||||
The `client` and `server` corpora are seeded from the test suite. The test suite has a `-fuzzer` flag which mirrors the fuzzer mode changes above and a `-deterministic` flag which removes all non-determinism on the Go side. Not all tests pass, so `ssl/test/runner/fuzzer_mode.json` contains the necessary suppressions. The `run_tests` target will pass appropriate command-line flags.
|
||||
|
||||
There are separate corpora, `client_corpus_no_fuzzer_mode` and `server_corpus_no_fuzzer_mode`. These are transcripts for fuzzers with only `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` defined. To build in this mode, pass `-DNO_FUZZER_MODE=1` into CMake. This configuration is run in the same way but without `-fuzzer` and `-shim-path` flags.
|
||||
|
||||
If both sets of tests pass, refresh the fuzzer corpora with `refresh_ssl_corpora.sh`:
|
||||
|
||||
```
|
||||
cd ssl/test/runner
|
||||
go test -fuzzer -deterministic -shim-config fuzzer_mode.json
|
||||
```
|
||||
|
||||
For a different build directory from `build/`, pass the appropriate `-shim-path` flag. If those tests pass, record a set of transcripts with:
|
||||
|
||||
```
|
||||
go test -fuzzer -deterministic -transcript-dir /tmp/transcripts/
|
||||
```
|
||||
|
||||
Note the suppressions file is ignored so disabled tests record transcripts too. Then merge into the existing corpora:
|
||||
|
||||
```
|
||||
cd build/
|
||||
./fuzz/client -max_len=50000 -merge=1 ../fuzz/client_corpus /tmp/transcripts/tls/client
|
||||
./fuzz/server -max_len=50000 -merge=1 ../fuzz/server_corpus /tmp/transcripts/tls/server
|
||||
cd fuzz
|
||||
./refresh_fuzzer_corpora.sh /path/to/fuzzer/mode/build /path/to/non/fuzzer/mode/build
|
||||
```
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
## Bazel
|
||||
|
||||
If you are using [Bazel](http://www.bazel.io) then you can incorporate
|
||||
If you are using [Bazel](https://bazel.build) then you can incorporate
|
||||
BoringSSL as an external repository by using a commit from the
|
||||
`master-with-bazel` branch. That branch is maintained by a bot from `master`
|
||||
and includes the needed generated files and a top-level BUILD file.
|
||||
@@ -38,7 +38,7 @@ updating things more complex.
|
||||
BoringSSL is designed to work with many different build systems. Currently,
|
||||
different projects use [GYP](https://gyp.gsrc.io/),
|
||||
[GN](https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/quick_start.md),
|
||||
[Bazel](http://bazel.io/) and [Make](https://www.gnu.org/software/make/) to
|
||||
[Bazel](https://bazel.build/) and [Make](https://www.gnu.org/software/make/) to
|
||||
build BoringSSL, without too much pain.
|
||||
|
||||
The development build system is CMake and the CMake build knows how to
|
||||
|
||||
@@ -64,6 +64,7 @@ add_subdirectory(err)
|
||||
add_subdirectory(buf)
|
||||
add_subdirectory(base64)
|
||||
add_subdirectory(bytestring)
|
||||
add_subdirectory(pool)
|
||||
|
||||
# Level 0.2 - depends on nothing but itself
|
||||
add_subdirectory(sha)
|
||||
@@ -136,6 +137,7 @@ add_library(
|
||||
$<TARGET_OBJECTS:err>
|
||||
$<TARGET_OBJECTS:base64>
|
||||
$<TARGET_OBJECTS:bytestring>
|
||||
$<TARGET_OBJECTS:pool>
|
||||
$<TARGET_OBJECTS:sha>
|
||||
$<TARGET_OBJECTS:md4>
|
||||
$<TARGET_OBJECTS:md5>
|
||||
|
||||
@@ -53,6 +53,7 @@ add_library(
|
||||
OBJECT
|
||||
|
||||
aes.c
|
||||
key_wrap.c
|
||||
mode_wrappers.c
|
||||
|
||||
${AES_ARCH_SOURCES}
|
||||
|
||||
+128
-48
@@ -15,88 +15,168 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "../test/file_test.h"
|
||||
|
||||
|
||||
static bool TestRaw(FileTest *t) {
|
||||
std::vector<uint8_t> key, plaintext, ciphertext;
|
||||
if (!t->GetBytes(&key, "Key") ||
|
||||
!t->GetBytes(&plaintext, "Plaintext") ||
|
||||
!t->GetBytes(&ciphertext, "Ciphertext")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (plaintext.size() != AES_BLOCK_SIZE ||
|
||||
ciphertext.size() != AES_BLOCK_SIZE) {
|
||||
t->PrintLine("Plaintext or Ciphertext not a block size.");
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
if (AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) {
|
||||
t->PrintLine("AES_set_encrypt_key failed.");
|
||||
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");
|
||||
AES_encrypt(plaintext.data(), block, &aes_key);
|
||||
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, ciphertext.data(),
|
||||
ciphertext.size())) {
|
||||
t->PrintLine("AES_encrypt gave the wrong output.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test in-place encryption.
|
||||
memcpy(block, plaintext, AES_BLOCK_SIZE);
|
||||
memcpy(block, plaintext.data(), 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");
|
||||
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, ciphertext.data(),
|
||||
ciphertext.size())) {
|
||||
t->PrintLine("In-place AES_encrypt gave the wrong output.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AES_set_decrypt_key(key, key_len * 8, &aes_key) != 0) {
|
||||
fprintf(stderr, "AES_set_decrypt_key failed\n");
|
||||
if (AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) {
|
||||
t->PrintLine("AES_set_decrypt_key failed.");
|
||||
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");
|
||||
AES_decrypt(ciphertext.data(), block, &aes_key);
|
||||
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, plaintext.data(),
|
||||
plaintext.size())) {
|
||||
t->PrintLine("AES_decrypt gave the wrong output.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test in-place decryption.
|
||||
memcpy(block, ciphertext, AES_BLOCK_SIZE);
|
||||
memcpy(block, ciphertext.data(), 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");
|
||||
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, plaintext.data(),
|
||||
plaintext.size())) {
|
||||
t->PrintLine("In-place AES_decrypt gave the wrong output.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
CRYPTO_library_init();
|
||||
static bool TestKeyWrap(FileTest *t) {
|
||||
// All test vectors use the default IV, so test both with implicit and
|
||||
// explicit IV.
|
||||
//
|
||||
// TODO(davidben): Find test vectors that use a different IV.
|
||||
static const uint8_t kDefaultIV[] = {
|
||||
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
|
||||
};
|
||||
|
||||
// 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")) {
|
||||
std::vector<uint8_t> key, plaintext, ciphertext;
|
||||
if (!t->GetBytes(&key, "Key") ||
|
||||
!t->GetBytes(&plaintext, "Plaintext") ||
|
||||
!t->GetBytes(&ciphertext, "Ciphertext")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
if (plaintext.size() + 8 != ciphertext.size()) {
|
||||
t->PrintLine("Invalid Plaintext and Ciphertext lengths.");
|
||||
return false;
|
||||
}
|
||||
|
||||
AES_KEY aes_key;
|
||||
if (AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) {
|
||||
t->PrintLine("AES_set_encrypt_key failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]);
|
||||
if (AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(), plaintext.data(),
|
||||
plaintext.size()) != static_cast<int>(ciphertext.size()) ||
|
||||
!t->ExpectBytesEqual(buf.get(), ciphertext.size(), ciphertext.data(),
|
||||
ciphertext.size())) {
|
||||
t->PrintLine("AES_wrap_key with implicit IV failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(buf.get(), 0, ciphertext.size());
|
||||
if (AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
|
||||
plaintext.size()) != static_cast<int>(ciphertext.size()) ||
|
||||
!t->ExpectBytesEqual(buf.get(), ciphertext.size(), ciphertext.data(),
|
||||
ciphertext.size())) {
|
||||
t->PrintLine("AES_wrap_key with explicit IV failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key) != 0) {
|
||||
t->PrintLine("AES_set_decrypt_key failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
buf.reset(new uint8_t[plaintext.size()]);
|
||||
if (AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
|
||||
ciphertext.size()) != static_cast<int>(plaintext.size()) ||
|
||||
!t->ExpectBytesEqual(buf.get(), plaintext.size(), plaintext.data(),
|
||||
plaintext.size())) {
|
||||
t->PrintLine("AES_unwrap_key with implicit IV failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(buf.get(), 0, plaintext.size());
|
||||
if (AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
|
||||
ciphertext.size()) != static_cast<int>(plaintext.size()) ||
|
||||
!t->ExpectBytesEqual(buf.get(), plaintext.size(), plaintext.data(),
|
||||
plaintext.size())) {
|
||||
t->PrintLine("AES_unwrap_key with explicit IV failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestAES(FileTest *t, void *arg) {
|
||||
if (t->GetParameter() == "Raw") {
|
||||
return TestRaw(t);
|
||||
}
|
||||
if (t->GetParameter() == "KeyWrap") {
|
||||
return TestKeyWrap(t);
|
||||
}
|
||||
|
||||
t->PrintLine("Unknown mode '%s'.", t->GetParameter().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
CRYPTO_library_init();
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s <test file.txt>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return FileTestMain(TestAES, nullptr, argv[1]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Test vectors from FIPS-197, Appendix C.
|
||||
|
||||
Mode = Raw
|
||||
Key = 000102030405060708090a0b0c0d0e0f
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = 69c4e0d86a7b0430d8cdb78070b4c55a
|
||||
|
||||
Mode = Raw
|
||||
Key = 000102030405060708090a0b0c0d0e0f1011121314151617
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = dda97ca4864cdfe06eaf70a0ec0d7191
|
||||
|
||||
Mode = Raw
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = 8ea2b7ca516745bfeafc49904b496089
|
||||
|
||||
|
||||
# Test vectors from
|
||||
# http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = 1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f1011121314151617
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = 96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Plaintext = 00112233445566778899aabbccddeeff
|
||||
Ciphertext = 64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f1011121314151617
|
||||
Plaintext = 00112233445566778899aabbccddeeff0001020304050607
|
||||
Ciphertext = 031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Plaintext = 00112233445566778899aabbccddeeff0001020304050607
|
||||
Ciphertext = a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1
|
||||
|
||||
Mode = KeyWrap
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Plaintext = 00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f
|
||||
Ciphertext = 28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21
|
||||
@@ -3011,7 +3011,7 @@ _aesp8_xts_enc5x:
|
||||
vxor $twk0,$twk0,v31
|
||||
|
||||
vcipher $out0,$out0,v26
|
||||
lvsr $inpperm,r0,$taillen # $in5 is no more
|
||||
lvsr $inpperm,0,$taillen # $in5 is no more
|
||||
vcipher $out1,$out1,v26
|
||||
vcipher $out2,$out2,v26
|
||||
vcipher $out3,$out3,v26
|
||||
@@ -3773,7 +3773,7 @@ foreach(split("\n",$code)) {
|
||||
if ($flavour =~ /le$/o) {
|
||||
SWITCH: for($conv) {
|
||||
/\?inv/ && do { @bytes=map($_^0xf,@bytes); last; };
|
||||
/\?rev/ && do { @bytes=reverse(@bytes); last; };
|
||||
/\?rev/ && do { @bytes=reverse(@bytes); last; };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND 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 OpenSSL PROJECT OR
|
||||
* ITS 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.
|
||||
* ==================================================================== */
|
||||
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
/* kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. */
|
||||
static const uint8_t kDefaultIV[] = {
|
||||
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
|
||||
};
|
||||
|
||||
static const unsigned kBound = 6;
|
||||
|
||||
int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
|
||||
const uint8_t *in, size_t in_len) {
|
||||
/* See RFC 3394, section 2.2.1. */
|
||||
|
||||
if (in_len > INT_MAX - 8 || in_len < 8 || in_len % 8 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iv == NULL) {
|
||||
iv = kDefaultIV;
|
||||
}
|
||||
|
||||
memmove(out + 8, in, in_len);
|
||||
uint8_t A[AES_BLOCK_SIZE];
|
||||
memcpy(A, iv, 8);
|
||||
|
||||
size_t n = in_len / 8;
|
||||
|
||||
for (unsigned j = 0; j < kBound; j++) {
|
||||
for (size_t i = 1; i <= n; i++) {
|
||||
memcpy(A + 8, out + 8 * i, 8);
|
||||
AES_encrypt(A, A, key);
|
||||
|
||||
uint32_t t = (uint32_t)(n * j + i);
|
||||
A[7] ^= t & 0xff;
|
||||
A[6] ^= (t >> 8) & 0xff;
|
||||
A[5] ^= (t >> 16) & 0xff;
|
||||
A[4] ^= (t >> 24) & 0xff;
|
||||
memcpy(out + 8 * i, A + 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(out, A, 8);
|
||||
return (int)in_len + 8;
|
||||
}
|
||||
|
||||
int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
|
||||
const uint8_t *in, size_t in_len) {
|
||||
/* See RFC 3394, section 2.2.2. */
|
||||
|
||||
if (in_len > INT_MAX || in_len < 16 || in_len % 8 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iv == NULL) {
|
||||
iv = kDefaultIV;
|
||||
}
|
||||
|
||||
uint8_t A[AES_BLOCK_SIZE];
|
||||
memcpy(A, in, 8);
|
||||
memmove(out, in + 8, in_len - 8);
|
||||
|
||||
size_t n = (in_len / 8) - 1;
|
||||
|
||||
for (unsigned j = kBound - 1; j < kBound; j--) {
|
||||
for (size_t i = n; i > 0; i--) {
|
||||
uint32_t t = (uint32_t)(n * j + i);
|
||||
A[7] ^= t & 0xff;
|
||||
A[6] ^= (t >> 8) & 0xff;
|
||||
A[5] ^= (t >> 16) & 0xff;
|
||||
A[4] ^= (t >> 24) & 0xff;
|
||||
memcpy(A + 8, out + 8 * (i - 1), 8);
|
||||
AES_decrypt(A, A, key);
|
||||
memcpy(out + 8 * (i - 1), A + 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (CRYPTO_memcmp(A, iv, 8) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)in_len - 8;
|
||||
}
|
||||
+20
-14
@@ -220,37 +220,43 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
ASN1_GENERALIZEDTIME *tmps = NULL;
|
||||
|
||||
if (s == NULL)
|
||||
s = M_ASN1_GENERALIZEDTIME_new();
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
tmps = ASN1_GENERALIZEDTIME_new();
|
||||
else
|
||||
tmps = s;
|
||||
if (tmps == NULL)
|
||||
return NULL;
|
||||
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
return (NULL);
|
||||
goto err;
|
||||
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = (char *)s->data;
|
||||
if ((p == NULL) || ((size_t)s->length < len)) {
|
||||
p = (char *)tmps->data;
|
||||
if ((p == NULL) || ((size_t)tmps->length < len)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
if (s->data != NULL)
|
||||
OPENSSL_free(s->data);
|
||||
s->data = (unsigned char *)p;
|
||||
OPENSSL_free(tmps->data);
|
||||
tmps->data = (unsigned char *)p;
|
||||
}
|
||||
|
||||
BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
|
||||
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
|
||||
ts->tm_sec);
|
||||
s->length = strlen(p);
|
||||
s->type = V_ASN1_GENERALIZEDTIME;
|
||||
return (s);
|
||||
tmps->length = strlen(p);
|
||||
tmps->type = V_ASN1_GENERALIZEDTIME;
|
||||
return tmps;
|
||||
err:
|
||||
if (s == NULL)
|
||||
ASN1_GENERALIZEDTIME_free(tmps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+21
-7
@@ -56,6 +56,7 @@
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -70,7 +71,7 @@
|
||||
/* Utility functions for manipulating fields and offsets */
|
||||
|
||||
/* Add 'offset' to 'addr' */
|
||||
#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
|
||||
#define offset2ptr(addr, offset) (void *)(((char *)(addr)) + (offset))
|
||||
|
||||
/* Given an ASN1_ITEM CHOICE type return the selector value */
|
||||
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
@@ -134,6 +135,8 @@ void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
if (enc) {
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->alias_only = 0;
|
||||
enc->alias_only_on_next_parse = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
@@ -142,11 +145,13 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (enc) {
|
||||
if (enc->enc) {
|
||||
if (enc->enc && !enc->alias_only) {
|
||||
OPENSSL_free(enc->enc);
|
||||
}
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->alias_only = 0;
|
||||
enc->alias_only_on_next_parse = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
@@ -159,14 +164,23 @@ int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (enc->enc) {
|
||||
if (!enc->alias_only) {
|
||||
OPENSSL_free(enc->enc);
|
||||
}
|
||||
enc->enc = OPENSSL_malloc(inlen);
|
||||
if (!enc->enc) {
|
||||
return 0;
|
||||
|
||||
enc->alias_only = enc->alias_only_on_next_parse;
|
||||
enc->alias_only_on_next_parse = 0;
|
||||
|
||||
if (enc->alias_only) {
|
||||
enc->enc = (uint8_t *) in;
|
||||
} else {
|
||||
enc->enc = OPENSSL_malloc(inlen);
|
||||
if (!enc->enc) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(enc->enc, in, inlen);
|
||||
}
|
||||
memcpy(enc->enc, in, inlen);
|
||||
|
||||
enc->len = inlen;
|
||||
enc->modified = 0;
|
||||
|
||||
|
||||
+15
-7
@@ -336,7 +336,13 @@ long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
|
||||
}
|
||||
|
||||
size_t BIO_pending(const BIO *bio) {
|
||||
return BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL);
|
||||
const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL);
|
||||
assert(r >= 0);
|
||||
|
||||
if (r < 0) {
|
||||
return 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t BIO_ctrl_pending(const BIO *bio) {
|
||||
@@ -344,7 +350,13 @@ size_t BIO_ctrl_pending(const BIO *bio) {
|
||||
}
|
||||
|
||||
size_t BIO_wpending(const BIO *bio) {
|
||||
return BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL);
|
||||
const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL);
|
||||
assert(r >= 0);
|
||||
|
||||
if (r < 0) {
|
||||
return 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int BIO_set_close(BIO *bio, int close_flag) {
|
||||
@@ -448,12 +460,8 @@ static int print_bio(const char *str, size_t len, void *bio) {
|
||||
return BIO_write((BIO *)bio, str, len);
|
||||
}
|
||||
|
||||
void BIO_print_errors(BIO *bio) {
|
||||
ERR_print_errors_cb(print_bio, bio);
|
||||
}
|
||||
|
||||
void ERR_print_errors(BIO *bio) {
|
||||
BIO_print_errors(bio);
|
||||
ERR_print_errors_cb(print_bio, bio);
|
||||
}
|
||||
|
||||
/* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
|
||||
|
||||
@@ -59,7 +59,7 @@ static void PrintSocketError(const char *func) {
|
||||
|
||||
class ScopedSocket {
|
||||
public:
|
||||
ScopedSocket(int sock) : sock_(sock) {}
|
||||
explicit ScopedSocket(int sock) : sock_(sock) {}
|
||||
~ScopedSocket() {
|
||||
closesocket(sock_);
|
||||
}
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
|
||||
#include <winsock2.h>
|
||||
OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
+11
-10
@@ -80,7 +80,7 @@
|
||||
: "+m"(r), "+d"(high) \
|
||||
: "r"(carry), "g"(0) \
|
||||
: "cc"); \
|
||||
carry = high; \
|
||||
(carry) = high; \
|
||||
} while (0)
|
||||
|
||||
#define mul(r, a, word, carry) \
|
||||
@@ -91,7 +91,8 @@
|
||||
: "+r"(carry), "+d"(high) \
|
||||
: "a"(low), "g"(0) \
|
||||
: "cc"); \
|
||||
(r) = carry, carry = high; \
|
||||
(r) = (carry); \
|
||||
(carry) = high; \
|
||||
} while (0)
|
||||
#undef sqr
|
||||
#define sqr(r0, r1, a) asm("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc");
|
||||
@@ -256,14 +257,14 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"((a)[i]) : "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
|
||||
@@ -1059,18 +1059,17 @@ $code.=<<___;
|
||||
mulx 2*8($aptr),%r15,%r13 # ...
|
||||
adox -3*8($tptr),%r11
|
||||
adcx %r15,%r12
|
||||
adox $zero,%r12
|
||||
adox -2*8($tptr),%r12
|
||||
adcx $zero,%r13
|
||||
adox $zero,%r13
|
||||
|
||||
mov $bptr,8(%rsp) # off-load &b[i]
|
||||
.byte 0x67
|
||||
mov $mi,%r15
|
||||
imulq 24(%rsp),$mi # "t[0]"*n0
|
||||
xor %ebp,%ebp # xor $zero,$zero # cf=0, of=0
|
||||
|
||||
mulx 3*8($aptr),%rax,%r14
|
||||
mov $mi,%rdx
|
||||
adox -2*8($tptr),%r12
|
||||
adcx %rax,%r13
|
||||
adox -1*8($tptr),%r13
|
||||
adcx $zero,%r14
|
||||
|
||||
+12
-13
@@ -340,7 +340,7 @@ static bool TestSquare(FileTest *t, BN_CTX *ctx) {
|
||||
BN_zero(zero.get());
|
||||
|
||||
bssl::UniquePtr<BIGNUM> ret(BN_new()), remainder(BN_new());
|
||||
if (!ret ||
|
||||
if (!ret || !remainder ||
|
||||
!BN_sqr(ret.get(), a.get(), ctx) ||
|
||||
!ExpectBIGNUMsEqual(t, "A^2", square.get(), ret.get()) ||
|
||||
!BN_mul(ret.get(), a.get(), a.get(), ctx) ||
|
||||
@@ -876,6 +876,10 @@ static bool TestMPI() {
|
||||
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMPITests); i++) {
|
||||
const MPITest &test = kMPITests[i];
|
||||
bssl::UniquePtr<BIGNUM> bn(ASCIIToBIGNUM(test.base10));
|
||||
if (!bn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
|
||||
if (mpi_len > sizeof(scratch)) {
|
||||
fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
|
||||
@@ -1020,14 +1024,12 @@ static bool TestASN1() {
|
||||
}
|
||||
|
||||
// Test the value serializes correctly.
|
||||
CBB cbb;
|
||||
bssl::ScopedCBB cbb;
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
CBB_zero(&cbb);
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!BN_marshal_asn1(&cbb, bn.get()) ||
|
||||
!CBB_finish(&cbb, &der, &der_len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
if (!CBB_init(cbb.get(), 0) ||
|
||||
!BN_marshal_asn1(cbb.get(), bn.get()) ||
|
||||
!CBB_finish(cbb.get(), &der, &der_len)) {
|
||||
return false;
|
||||
}
|
||||
bssl::UniquePtr<uint8_t> delete_der(der);
|
||||
@@ -1110,16 +1112,13 @@ static bool TestASN1() {
|
||||
if (!bn) {
|
||||
return false;
|
||||
}
|
||||
CBB cbb;
|
||||
CBB_zero(&cbb);
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
BN_marshal_asn1(&cbb, bn.get())) {
|
||||
bssl::ScopedCBB cbb;
|
||||
if (!CBB_init(cbb.get(), 0) ||
|
||||
BN_marshal_asn1(cbb.get(), bn.get())) {
|
||||
fprintf(stderr, "Serialized negative number.\n");
|
||||
CBB_cleanup(&cbb);
|
||||
return false;
|
||||
}
|
||||
ERR_clear_error();
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9875,6 +9875,18 @@ A = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4
|
||||
B = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7
|
||||
M = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed
|
||||
|
||||
# Regression tests for CVE-2016-7055.
|
||||
|
||||
ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9
|
||||
A = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878
|
||||
B = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81
|
||||
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
|
||||
|
||||
ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9
|
||||
A = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81
|
||||
B = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878
|
||||
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
|
||||
|
||||
|
||||
# ModExp tests.
|
||||
#
|
||||
|
||||
+71
-67
@@ -67,34 +67,34 @@
|
||||
!(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
|
||||
|
||||
#ifdef BN_ULLONG
|
||||
#define mul_add(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULLONG t; \
|
||||
t = (BN_ULLONG)w * (a) + (r) + (c); \
|
||||
(r) = Lw(t); \
|
||||
(c) = Hw(t); \
|
||||
}
|
||||
#define mul_add(r, a, w, c) \
|
||||
do { \
|
||||
BN_ULLONG t; \
|
||||
t = (BN_ULLONG)(w) * (a) + (r) + (c); \
|
||||
(r) = Lw(t); \
|
||||
(c) = Hw(t); \
|
||||
} while (0)
|
||||
|
||||
#define mul(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULLONG t; \
|
||||
t = (BN_ULLONG)w * (a) + (c); \
|
||||
(r) = Lw(t); \
|
||||
(c) = Hw(t); \
|
||||
}
|
||||
#define mul(r, a, w, c) \
|
||||
do { \
|
||||
BN_ULLONG t; \
|
||||
t = (BN_ULLONG)(w) * (a) + (c); \
|
||||
(r) = Lw(t); \
|
||||
(c) = Hw(t); \
|
||||
} while (0)
|
||||
|
||||
#define sqr(r0, r1, a) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULLONG t; \
|
||||
t = (BN_ULLONG)(a) * (a); \
|
||||
(r0) = Lw(t); \
|
||||
(r1) = Hw(t); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define mul_add(r, a, w, c) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG high, low, ret, tmp = (a); \
|
||||
ret = (r); \
|
||||
BN_UMULT_LOHI(low, high, w, tmp); \
|
||||
@@ -104,23 +104,23 @@
|
||||
ret += low; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define mul(r, a, w, c) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG high, low, ret, ta = (a); \
|
||||
BN_UMULT_LOHI(low, high, w, ta); \
|
||||
ret = low + (c); \
|
||||
(c) = high; \
|
||||
(c) += (ret < low) ? 1 : 0; \
|
||||
(r) = ret; \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define sqr(r0, r1, a) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG tmp = (a); \
|
||||
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#endif /* !BN_ULLONG */
|
||||
|
||||
@@ -369,42 +369,46 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
t += (c0); /* no carry */ \
|
||||
(c0) = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
(c1) = ((c1) + (hi)) & BN_MASK2; \
|
||||
if ((c1) < hi) { \
|
||||
(c2)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#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++; \
|
||||
#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++; \
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \
|
||||
t += (c0); /* no carry */ \
|
||||
(c0) = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
(c1) = ((c1) + hi) & BN_MASK2; \
|
||||
if ((c1) < hi) { \
|
||||
(c2)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
@@ -418,10 +422,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
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; \
|
||||
(c0) += lo; \
|
||||
hi += ((c0) < lo) ? 1 : 0; \
|
||||
(c1) += hi; \
|
||||
(c2) += ((c1) < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
@@ -429,14 +433,14 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
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; \
|
||||
(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; \
|
||||
(c1) += hi; \
|
||||
(c2) += ((c1) < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
@@ -444,10 +448,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, ta); \
|
||||
c0 += lo; \
|
||||
(c0) += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
(c1) += hi; \
|
||||
(c2) += ((c1) < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
@@ -160,7 +160,7 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_TBIT (0x8000000000000000UL)
|
||||
#define BN_DEC_CONV (10000000000000000000UL)
|
||||
#define BN_DEC_NUM 19
|
||||
#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
|
||||
#define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo))
|
||||
|
||||
#elif defined(OPENSSL_32_BIT)
|
||||
|
||||
@@ -181,17 +181,17 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_TBIT (0x80000000UL)
|
||||
#define BN_DEC_CONV (1000000000UL)
|
||||
#define BN_DEC_NUM 9
|
||||
#define TOBN(hi, lo) lo, hi
|
||||
#define TOBN(hi, lo) (lo), (hi)
|
||||
|
||||
#else
|
||||
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
|
||||
#endif
|
||||
|
||||
|
||||
#define STATIC_BIGNUM(x) \
|
||||
{ \
|
||||
(BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
|
||||
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
|
||||
#define STATIC_BIGNUM(x) \
|
||||
{ \
|
||||
(BN_ULONG *)(x), sizeof(x) / sizeof(BN_ULONG), \
|
||||
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
|
||||
}
|
||||
|
||||
#if defined(BN_ULLONG)
|
||||
|
||||
@@ -231,6 +231,25 @@ static bool TestGetASN1() {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned tag;
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
if (!CBS_get_any_asn1(&data, &contents, &tag) ||
|
||||
tag != CBS_ASN1_SEQUENCE ||
|
||||
CBS_len(&contents) != 2 ||
|
||||
memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t header_len;
|
||||
CBS_init(&data, kData1, sizeof(kData1));
|
||||
if (!CBS_get_any_asn1_element(&data, &contents, &tag, &header_len) ||
|
||||
tag != CBS_ASN1_SEQUENCE ||
|
||||
header_len != 2 ||
|
||||
CBS_len(&contents) != 4 ||
|
||||
memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +262,20 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
return CBS_get_bytes(cbs, out, len);
|
||||
}
|
||||
|
||||
int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
|
||||
size_t header_len;
|
||||
if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBS_skip(out, header_len)) {
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
|
||||
size_t *out_header_len) {
|
||||
return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
|
||||
|
||||
@@ -316,8 +316,6 @@ static const struct KnownAEAD kAEADs[] = {
|
||||
{ "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true },
|
||||
{ "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true },
|
||||
{ "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true },
|
||||
{ "aes-128-key-wrap", EVP_aead_aes_128_key_wrap, true },
|
||||
{ "aes-256-key-wrap", EVP_aead_aes_256_key_wrap, true },
|
||||
{ "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false },
|
||||
{ "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false },
|
||||
{ "", NULL, false },
|
||||
|
||||
@@ -1179,266 +1179,6 @@ const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
|
||||
const EVP_AEAD *EVP_aead_aes_256_gcm(void) { return &aead_aes_256_gcm; }
|
||||
|
||||
|
||||
/* AES Key Wrap is specified in
|
||||
* http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf
|
||||
* or https://tools.ietf.org/html/rfc3394 */
|
||||
|
||||
struct aead_aes_key_wrap_ctx {
|
||||
uint8_t key[32];
|
||||
unsigned key_bits;
|
||||
};
|
||||
|
||||
static int aead_aes_key_wrap_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len) {
|
||||
struct aead_aes_key_wrap_ctx *kw_ctx;
|
||||
const size_t key_bits = key_len * 8;
|
||||
|
||||
if (key_bits != 128 && key_bits != 256) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0; /* EVP_AEAD_CTX_init should catch this. */
|
||||
}
|
||||
|
||||
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
|
||||
tag_len = 8;
|
||||
}
|
||||
|
||||
if (tag_len != 8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
kw_ctx = OPENSSL_malloc(sizeof(struct aead_aes_key_wrap_ctx));
|
||||
if (kw_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(kw_ctx->key, key, key_len);
|
||||
kw_ctx->key_bits = key_bits;
|
||||
|
||||
ctx->aead_state = kw_ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aead_aes_key_wrap_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_aes_key_wrap_ctx *kw_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(kw_ctx, sizeof(struct aead_aes_key_wrap_ctx));
|
||||
OPENSSL_free(kw_ctx);
|
||||
}
|
||||
|
||||
/* kDefaultAESKeyWrapNonce is the default nonce value given in 2.2.3.1. */
|
||||
static const uint8_t kDefaultAESKeyWrapNonce[8] = {0xa6, 0xa6, 0xa6, 0xa6,
|
||||
0xa6, 0xa6, 0xa6, 0xa6};
|
||||
|
||||
|
||||
static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
const struct aead_aes_key_wrap_ctx *kw_ctx = ctx->aead_state;
|
||||
union {
|
||||
double align;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
/* Variables in this function match up with the variables in the second half
|
||||
* of section 2.2.1. */
|
||||
unsigned i, j, n;
|
||||
uint8_t A[AES_BLOCK_SIZE];
|
||||
|
||||
if (ad_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len == 0) {
|
||||
nonce = kDefaultAESKeyWrapNonce;
|
||||
nonce_len = sizeof(kDefaultAESKeyWrapNonce);
|
||||
}
|
||||
|
||||
if (nonce_len != 8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len % 8 != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
|
||||
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
|
||||
* conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
|
||||
* a comparison is always true. */
|
||||
if (in_len > 0xfffffff0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = in_len / 8;
|
||||
|
||||
if (n < 2) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len + 8 < in_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len + 8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (AES_set_encrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memmove(out + 8, in, in_len);
|
||||
memcpy(A, nonce, 8);
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
for (i = 1; i <= n; i++) {
|
||||
uint32_t t;
|
||||
|
||||
memcpy(A + 8, out + 8 * i, 8);
|
||||
AES_encrypt(A, A, &ks.ks);
|
||||
t = n * j + i;
|
||||
A[7] ^= t & 0xff;
|
||||
A[6] ^= (t >> 8) & 0xff;
|
||||
A[5] ^= (t >> 16) & 0xff;
|
||||
A[4] ^= (t >> 24) & 0xff;
|
||||
memcpy(out + 8 * i, A + 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(out, A, 8);
|
||||
*out_len = in_len + 8;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
const struct aead_aes_key_wrap_ctx *kw_ctx = ctx->aead_state;
|
||||
union {
|
||||
double align;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
/* Variables in this function match up with the variables in the second half
|
||||
* of section 2.2.1. */
|
||||
unsigned i, j, n;
|
||||
uint8_t A[AES_BLOCK_SIZE];
|
||||
|
||||
if (ad_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len == 0) {
|
||||
nonce = kDefaultAESKeyWrapNonce;
|
||||
nonce_len = sizeof(kDefaultAESKeyWrapNonce);
|
||||
}
|
||||
|
||||
if (nonce_len != 8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len % 8 != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
|
||||
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
|
||||
* conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
|
||||
* a comparison is always true. */
|
||||
if (in_len > 0xfffffff8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_len < 24) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = (in_len / 8) - 1;
|
||||
|
||||
if (max_out_len < in_len - 8) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (AES_set_decrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(A, in, 8);
|
||||
memmove(out, in + 8, in_len - 8);
|
||||
|
||||
for (j = 5; j < 6; j--) {
|
||||
for (i = n; i > 0; i--) {
|
||||
uint32_t t;
|
||||
|
||||
t = n * j + i;
|
||||
A[7] ^= t & 0xff;
|
||||
A[6] ^= (t >> 8) & 0xff;
|
||||
A[5] ^= (t >> 16) & 0xff;
|
||||
A[4] ^= (t >> 24) & 0xff;
|
||||
memcpy(A + 8, out + 8 * (i - 1), 8);
|
||||
AES_decrypt(A, A, &ks.ks);
|
||||
memcpy(out + 8 * (i - 1), A + 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (CRYPTO_memcmp(A, nonce, 8) != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_len = in_len - 8;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_aes_128_key_wrap = {
|
||||
16, /* key len */
|
||||
8, /* nonce len */
|
||||
8, /* overhead */
|
||||
8, /* max tag length */
|
||||
aead_aes_key_wrap_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal,
|
||||
aead_aes_key_wrap_open,
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_256_key_wrap = {
|
||||
32, /* key len */
|
||||
8, /* nonce len */
|
||||
8, /* overhead */
|
||||
8, /* max tag length */
|
||||
aead_aes_key_wrap_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_aes_key_wrap_cleanup,
|
||||
aead_aes_key_wrap_seal,
|
||||
aead_aes_key_wrap_open,
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_key_wrap(void) { return &aead_aes_128_key_wrap; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_256_key_wrap(void) { return &aead_aes_256_key_wrap; }
|
||||
|
||||
|
||||
#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
|
||||
#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12
|
||||
|
||||
|
||||
+51
-46
@@ -60,63 +60,68 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#define c2l(c, l) \
|
||||
(l = ((uint32_t)(*((c)++))), l |= ((uint32_t)(*((c)++))) << 8L, \
|
||||
l |= ((uint32_t)(*((c)++))) << 16L, \
|
||||
l |= ((uint32_t)(*((c)++))) << 24L)
|
||||
#define c2l(c, l) \
|
||||
do { \
|
||||
(l) = ((uint32_t)(*((c)++))); \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 8L; \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 16L; \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 24L; \
|
||||
} while (0)
|
||||
|
||||
#define c2ln(c, l1, l2, n) \
|
||||
{ \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
l2 = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 7: \
|
||||
l2 |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 6: \
|
||||
l2 |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 5: \
|
||||
l2 |= ((uint32_t)(*(--(c)))); \
|
||||
case 4: \
|
||||
l1 = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 3: \
|
||||
l1 |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 2: \
|
||||
l1 |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 1: \
|
||||
l1 |= ((uint32_t)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
#define c2ln(c, l1, l2, n) \
|
||||
do { \
|
||||
(c) += (n); \
|
||||
(l1) = (l2) = 0; \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
(l2) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 7: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 6: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 5: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))); \
|
||||
case 4: \
|
||||
(l1) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 3: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 2: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 1: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define l2c(l, c) \
|
||||
(*((c)++) = (uint8_t)(((l)) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
|
||||
#define l2c(l, c) \
|
||||
do { \
|
||||
*((c)++) = (uint8_t)(((l)) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
#define l2cn(l1, l2, c, n) \
|
||||
{ \
|
||||
c += n; \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
#define l2cn(l1, l2, c, n) \
|
||||
do { \
|
||||
(c) += (n); \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
|
||||
case 7: \
|
||||
case 7: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
|
||||
case 6: \
|
||||
case 6: \
|
||||
*(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
|
||||
case 5: \
|
||||
case 5: \
|
||||
*(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
case 4: \
|
||||
case 4: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
|
||||
case 3: \
|
||||
case 3: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
|
||||
case 2: \
|
||||
case 2: \
|
||||
*(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
|
||||
case 1: \
|
||||
case 1: \
|
||||
*(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY;
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
|
||||
/* Remove CBC padding. Code from here on is timing-sensitive with respect to
|
||||
* |padding_ok| and |data_plus_mac_len| for CBC ciphers. */
|
||||
unsigned padding_ok, data_plus_mac_len, data_len;
|
||||
unsigned padding_ok, data_plus_mac_len;
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
|
||||
if (!EVP_tls_cbc_remove_padding(
|
||||
&padding_ok, &data_plus_mac_len, out, total,
|
||||
@@ -279,7 +279,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
* already been checked against the MAC size at the top of the function. */
|
||||
assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx));
|
||||
}
|
||||
data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx);
|
||||
unsigned data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx);
|
||||
|
||||
/* At this point, if the padding is valid, the first |data_plus_mac_len| bytes
|
||||
* after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# These test vectors have been taken from
|
||||
# http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf
|
||||
|
||||
KEY: 000102030405060708090A0B0C0D0E0F
|
||||
NONCE:
|
||||
IN: 00112233445566778899AABBCCDDEEFF
|
||||
AD:
|
||||
CT: 1FA68B0A8112B447AEF34BD8FB5A7B82
|
||||
TAG: 9D3E862371D2CFE5
|
||||
@@ -1,23 +0,0 @@
|
||||
# These test vectors have been taken from
|
||||
# http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf
|
||||
|
||||
KEY: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
|
||||
NONCE:
|
||||
IN: 00112233445566778899AABBCCDDEEFF
|
||||
AD:
|
||||
CT: 64E8C3F9CE0F5BA263E9777905818A2A
|
||||
TAG: 93C8191E7D6E8AE7
|
||||
|
||||
KEY: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
|
||||
NONCE:
|
||||
IN: 00112233445566778899AABBCCDDEEFF0001020304050607
|
||||
AD:
|
||||
CT: A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB895
|
||||
TAG: 8CD5D17D6B254DA1
|
||||
|
||||
KEY: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
|
||||
NONCE:
|
||||
IN: 00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F
|
||||
AD:
|
||||
CT: 28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43B
|
||||
TAG: FB988B9B7A02DD21
|
||||
+18
-14
@@ -264,23 +264,27 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
|
||||
|
||||
/* u32toBE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
|
||||
* big-endian order. The value of p is advanced by four. */
|
||||
#define u32toBE(n, p) \
|
||||
(*((p)++)=(uint8_t)(n>>24), \
|
||||
*((p)++)=(uint8_t)(n>>16), \
|
||||
*((p)++)=(uint8_t)(n>>8), \
|
||||
*((p)++)=(uint8_t)(n))
|
||||
#define u32toBE(n, p) \
|
||||
do { \
|
||||
*((p)++) = (uint8_t)((n) >> 24); \
|
||||
*((p)++) = (uint8_t)((n) >> 16); \
|
||||
*((p)++) = (uint8_t)((n) >> 8); \
|
||||
*((p)++) = (uint8_t)((n)); \
|
||||
} while (0)
|
||||
|
||||
/* u64toBE serialises an unsigned, 64-bit number (n) as eight bytes at (p) in
|
||||
* big-endian order. The value of p is advanced by eight. */
|
||||
#define u64toBE(n, p) \
|
||||
(*((p)++)=(uint8_t)(n>>56), \
|
||||
*((p)++)=(uint8_t)(n>>48), \
|
||||
*((p)++)=(uint8_t)(n>>40), \
|
||||
*((p)++)=(uint8_t)(n>>32), \
|
||||
*((p)++)=(uint8_t)(n>>24), \
|
||||
*((p)++)=(uint8_t)(n>>16), \
|
||||
*((p)++)=(uint8_t)(n>>8), \
|
||||
*((p)++)=(uint8_t)(n))
|
||||
#define u64toBE(n, p) \
|
||||
do { \
|
||||
*((p)++) = (uint8_t)((n) >> 56); \
|
||||
*((p)++) = (uint8_t)((n) >> 48); \
|
||||
*((p)++) = (uint8_t)((n) >> 40); \
|
||||
*((p)++) = (uint8_t)((n) >> 32); \
|
||||
*((p)++) = (uint8_t)((n) >> 24); \
|
||||
*((p)++) = (uint8_t)((n) >> 16); \
|
||||
*((p)++) = (uint8_t)((n) >> 8); \
|
||||
*((p)++) = (uint8_t)((n)); \
|
||||
} while (0)
|
||||
|
||||
/* These functions serialize the state of a hash and thus perform the standard
|
||||
* "final" operation without adding the padding and length that such a function
|
||||
|
||||
@@ -786,3 +786,5 @@ int CONF_modules_load_file(CONF_MUST_BE_NULL *filename, const char *appname,
|
||||
void CONF_modules_free(void) {}
|
||||
|
||||
void OPENSSL_config(CONF_MUST_BE_NULL *config_name) {}
|
||||
|
||||
void OPENSSL_no_config(void) {}
|
||||
|
||||
@@ -640,9 +640,6 @@ static void fe_invert(fe out, const fe z) {
|
||||
int i;
|
||||
|
||||
fe_sq(t0, z);
|
||||
for (i = 1; i < 1; ++i) {
|
||||
fe_sq(t0, t0);
|
||||
}
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 2; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
@@ -650,9 +647,6 @@ static void fe_invert(fe out, const fe z) {
|
||||
fe_mul(t1, z, t1);
|
||||
fe_mul(t0, t0, t1);
|
||||
fe_sq(t2, t0);
|
||||
for (i = 1; i < 1; ++i) {
|
||||
fe_sq(t2, t2);
|
||||
}
|
||||
fe_mul(t1, t1, t2);
|
||||
fe_sq(t2, t1);
|
||||
for (i = 1; i < 5; ++i) {
|
||||
@@ -907,9 +901,6 @@ static void fe_pow22523(fe out, const fe z) {
|
||||
int i;
|
||||
|
||||
fe_sq(t0, z);
|
||||
for (i = 1; i < 1; ++i) {
|
||||
fe_sq(t0, t0);
|
||||
}
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 2; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
@@ -917,9 +908,6 @@ static void fe_pow22523(fe out, const fe z) {
|
||||
fe_mul(t1, z, t1);
|
||||
fe_mul(t0, t0, t1);
|
||||
fe_sq(t0, t0);
|
||||
for (i = 1; i < 1; ++i) {
|
||||
fe_sq(t0, t0);
|
||||
}
|
||||
fe_mul(t0, t1, t0);
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 5; ++i) {
|
||||
@@ -4625,20 +4613,7 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) {
|
||||
uint8_t seed[32];
|
||||
RAND_bytes(seed, 32);
|
||||
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
SHA512(seed, 32, az);
|
||||
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
ge_p3 A;
|
||||
x25519_ge_scalarmult_base(&A, az);
|
||||
ge_p3_tobytes(out_public_key, &A);
|
||||
|
||||
memcpy(out_private_key, seed, 32);
|
||||
memmove(out_private_key + 32, out_public_key, 32);
|
||||
ED25519_keypair_from_seed(out_public_key, out_private_key, seed);
|
||||
}
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
@@ -4712,6 +4687,24 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
|
||||
}
|
||||
|
||||
void ED25519_keypair_from_seed(uint8_t out_public_key[32],
|
||||
uint8_t out_private_key[64],
|
||||
const uint8_t seed[32]) {
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
SHA512(seed, 32, az);
|
||||
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
ge_p3 A;
|
||||
x25519_ge_scalarmult_base(&A, az);
|
||||
ge_p3_tobytes(out_public_key, &A);
|
||||
|
||||
memcpy(out_private_key, seed, 32);
|
||||
memcpy(out_private_key + 32, out_public_key, 32);
|
||||
}
|
||||
|
||||
|
||||
#if defined(BORINGSSL_X25519_X86_64)
|
||||
|
||||
|
||||
@@ -53,11 +53,30 @@ static bool TestSignature(FileTest *t, void *arg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestKeypairFromSeed() {
|
||||
uint8_t public_key1[32], private_key1[64];
|
||||
ED25519_keypair(public_key1, private_key1);
|
||||
|
||||
uint8_t seed[32];
|
||||
memcpy(seed, private_key1, sizeof(seed));
|
||||
|
||||
uint8_t public_key2[32], private_key2[64];
|
||||
ED25519_keypair_from_seed(public_key2, private_key2, seed);
|
||||
|
||||
if (memcmp(public_key1, public_key2, sizeof(public_key1)) != 0 ||
|
||||
memcmp(private_key1, private_key2, sizeof(private_key1)) != 0) {
|
||||
fprintf(stderr, "TestKeypairFromSeed: resulting keypairs did not match.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s <test input.txt>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return FileTestMain(TestSignature, nullptr, argv[1]);
|
||||
return TestKeypairFromSeed() && FileTestMain(TestSignature, nullptr, argv[1]);
|
||||
}
|
||||
|
||||
+1
-1
@@ -291,7 +291,7 @@ static const uint32_t DES_SPtrans[8][64] = {
|
||||
|
||||
#define HPERM_OP(a, t, n, m) \
|
||||
((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \
|
||||
(a) = (a) ^ (t) ^ (t >> (16 - (n))))
|
||||
(a) = (a) ^ (t) ^ ((t) >> (16 - (n))))
|
||||
|
||||
void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
|
||||
static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1,
|
||||
|
||||
+57
-45
@@ -64,45 +64,51 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define c2l(c, l) \
|
||||
(l = ((uint32_t)(*((c)++))), l |= ((uint32_t)(*((c)++))) << 8L, \
|
||||
l |= ((uint32_t)(*((c)++))) << 16L, l |= ((uint32_t)(*((c)++))) << 24L)
|
||||
#define c2l(c, l) \
|
||||
do { \
|
||||
(l) = ((uint32_t)(*((c)++))); \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 8L; \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 16L; \
|
||||
(l) |= ((uint32_t)(*((c)++))) << 24L; \
|
||||
} while (0)
|
||||
|
||||
#define l2c(l, c) \
|
||||
(*((c)++) = (unsigned char)(((l)) & 0xff), \
|
||||
*((c)++) = (unsigned char)(((l) >> 8L) & 0xff), \
|
||||
*((c)++) = (unsigned char)(((l) >> 16L) & 0xff), \
|
||||
*((c)++) = (unsigned char)(((l) >> 24L) & 0xff))
|
||||
#define l2c(l, c) \
|
||||
do { \
|
||||
*((c)++) = (unsigned char)(((l)) & 0xff); \
|
||||
*((c)++) = (unsigned char)(((l) >> 8L) & 0xff); \
|
||||
*((c)++) = (unsigned char)(((l) >> 16L) & 0xff); \
|
||||
*((c)++) = (unsigned char)(((l) >> 24L) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
/* NOTE - c is not incremented as per c2l */
|
||||
#define c2ln(c, l1, l2, n) \
|
||||
{ \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
l2 = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 7: \
|
||||
l2 |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 6: \
|
||||
l2 |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 5: \
|
||||
l2 |= ((uint32_t)(*(--(c)))); \
|
||||
case 4: \
|
||||
l1 = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 3: \
|
||||
l1 |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 2: \
|
||||
l1 |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 1: \
|
||||
l1 |= ((uint32_t)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
#define c2ln(c, l1, l2, n) \
|
||||
do { \
|
||||
(c) += (n); \
|
||||
(l1) = (l2) = 0; \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
(l2) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 7: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 6: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 5: \
|
||||
(l2) |= ((uint32_t)(*(--(c)))); \
|
||||
case 4: \
|
||||
(l1) = ((uint32_t)(*(--(c)))) << 24L; \
|
||||
case 3: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 16L; \
|
||||
case 2: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))) << 8L; \
|
||||
case 1: \
|
||||
(l1) |= ((uint32_t)(*(--(c)))); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* NOTE - c is not incremented as per l2c */
|
||||
#define l2cn(l1, l2, c, n) \
|
||||
{ \
|
||||
c += n; \
|
||||
do { \
|
||||
(c) += (n); \
|
||||
switch (n) { \
|
||||
case 8: \
|
||||
*(--(c)) = (unsigned char)(((l2) >> 24L) & 0xff); \
|
||||
@@ -121,7 +127,7 @@ extern "C" {
|
||||
case 1: \
|
||||
*(--(c)) = (unsigned char)(((l1)) & 0xff); \
|
||||
} \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
/* IP and FP
|
||||
* The problem is more of a geometric problem that random bit fiddling.
|
||||
@@ -160,44 +166,50 @@ When I finally started to think of the problem in 2D
|
||||
I first got ~42 operations without xors. When I remembered
|
||||
how to use xors :-) I got it to its final state.
|
||||
*/
|
||||
#define PERM_OP(a, b, t, n, m) \
|
||||
((t) = ((((a) >> (n)) ^ (b)) & (m)), (b) ^= (t), (a) ^= ((t) << (n)))
|
||||
#define PERM_OP(a, b, t, n, m) \
|
||||
do { \
|
||||
(t) = ((((a) >> (n)) ^ (b)) & (m)); \
|
||||
(b) ^= (t); \
|
||||
(a) ^= ((t) << (n)); \
|
||||
} while (0)
|
||||
|
||||
#define IP(l, r) \
|
||||
{ \
|
||||
do { \
|
||||
uint32_t tt; \
|
||||
PERM_OP(r, l, tt, 4, 0x0f0f0f0fL); \
|
||||
PERM_OP(l, r, tt, 16, 0x0000ffffL); \
|
||||
PERM_OP(r, l, tt, 2, 0x33333333L); \
|
||||
PERM_OP(l, r, tt, 8, 0x00ff00ffL); \
|
||||
PERM_OP(r, l, tt, 1, 0x55555555L); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define FP(l, r) \
|
||||
{ \
|
||||
do { \
|
||||
uint32_t tt; \
|
||||
PERM_OP(l, r, tt, 1, 0x55555555L); \
|
||||
PERM_OP(r, l, tt, 8, 0x00ff00ffL); \
|
||||
PERM_OP(l, r, tt, 2, 0x33333333L); \
|
||||
PERM_OP(r, l, tt, 16, 0x0000ffffL); \
|
||||
PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
|
||||
u = R ^ ks->subkeys[S][0]; \
|
||||
t = R ^ ks->subkeys[S][1]
|
||||
do { \
|
||||
(u) = (R) ^ (ks)->subkeys[S][0]; \
|
||||
(t) = (R) ^ (ks)->subkeys[S][1]; \
|
||||
} while (0)
|
||||
|
||||
#define D_ENCRYPT(ks, LL, R, S) \
|
||||
{ \
|
||||
do { \
|
||||
LOAD_DATA(ks, R, S, u, t, E0, E1); \
|
||||
t = ROTATE(t, 4); \
|
||||
LL ^= \
|
||||
(LL) ^= \
|
||||
DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
|
||||
DES_SPtrans[4][(u >> 18L) & 0x3f] ^ \
|
||||
DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \
|
||||
DES_SPtrans[3][(t >> 10L) & 0x3f] ^ \
|
||||
DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define ITERATIONS 16
|
||||
#define HALF_ITERATIONS 8
|
||||
|
||||
+28
-18
@@ -140,29 +140,39 @@ extern "C" {
|
||||
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)(l = (((uint32_t)(*((c)++))) << 24), \
|
||||
l |= (((uint32_t)(*((c)++))) << 16), \
|
||||
l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
|
||||
#define HOST_c2l(c, l) \
|
||||
do { \
|
||||
(l) = (((uint32_t)(*((c)++))) << 24); \
|
||||
(l) |= (((uint32_t)(*((c)++))) << 16); \
|
||||
(l) |= (((uint32_t)(*((c)++))) << 8); \
|
||||
(l) |= (((uint32_t)(*((c)++)))); \
|
||||
} while (0)
|
||||
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l)) & 0xff))
|
||||
#define HOST_l2c(l, c) \
|
||||
do { \
|
||||
*((c)++) = (uint8_t)(((l) >> 24) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l)) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
|
||||
l |= (((uint32_t)(*((c)++))) << 16), \
|
||||
l |= (((uint32_t)(*((c)++))) << 24))
|
||||
#define HOST_c2l(c, l) \
|
||||
do { \
|
||||
(l) = (((uint32_t)(*((c)++)))); \
|
||||
(l) |= (((uint32_t)(*((c)++))) << 8); \
|
||||
(l) |= (((uint32_t)(*((c)++))) << 16); \
|
||||
(l) |= (((uint32_t)(*((c)++))) << 24); \
|
||||
} while (0)
|
||||
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)(*((c)++) = (uint8_t)(((l)) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 24) & 0xff))
|
||||
#define HOST_l2c(l, c) \
|
||||
do { \
|
||||
*((c)++) = (uint8_t)(((l)) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff); \
|
||||
*((c)++) = (uint8_t)(((l) >> 24) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
#endif /* DATA_ORDER */
|
||||
|
||||
|
||||
@@ -46,6 +46,15 @@ add_executable(
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
add_executable(
|
||||
p256-x86_64_test
|
||||
|
||||
p256-x86_64_test.cc
|
||||
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(example_mul crypto)
|
||||
target_link_libraries(ec_test crypto)
|
||||
target_link_libraries(p256-x86_64_test crypto)
|
||||
add_dependencies(all_tests example_mul ec_test)
|
||||
|
||||
@@ -94,6 +94,7 @@ ecp_nistz256_mul_by_2:
|
||||
push %r13
|
||||
|
||||
mov 8*0($a_ptr), $a0
|
||||
xor $t4,$t4
|
||||
mov 8*1($a_ptr), $a1
|
||||
add $a0, $a0 # a0:a3+a0:a3
|
||||
mov 8*2($a_ptr), $a2
|
||||
@@ -104,7 +105,7 @@ ecp_nistz256_mul_by_2:
|
||||
adc $a2, $a2
|
||||
adc $a3, $a3
|
||||
mov $a1, $t1
|
||||
sbb $t4, $t4
|
||||
adc \$0, $t4
|
||||
|
||||
sub 8*0($a_ptr), $a0
|
||||
mov $a2, $t2
|
||||
@@ -112,14 +113,14 @@ ecp_nistz256_mul_by_2:
|
||||
sbb 8*2($a_ptr), $a2
|
||||
mov $a3, $t3
|
||||
sbb 8*3($a_ptr), $a3
|
||||
test $t4, $t4
|
||||
sbb \$0, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
cmovc $t0, $a0
|
||||
cmovc $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
cmovc $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
cmovc $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
@@ -333,7 +334,7 @@ __ecp_nistz256_mul_montq:
|
||||
adc \$0, $acc0
|
||||
|
||||
########################################################################
|
||||
# Second reduction step
|
||||
# Second reduction step
|
||||
mov $acc1, $t1
|
||||
shl \$32, $acc1
|
||||
mulq $poly3
|
||||
@@ -380,7 +381,7 @@ __ecp_nistz256_mul_montq:
|
||||
adc \$0, $acc1
|
||||
|
||||
########################################################################
|
||||
# Third reduction step
|
||||
# Third reduction step
|
||||
mov $acc2, $t1
|
||||
shl \$32, $acc2
|
||||
mulq $poly3
|
||||
@@ -427,7 +428,7 @@ __ecp_nistz256_mul_montq:
|
||||
adc \$0, $acc2
|
||||
|
||||
########################################################################
|
||||
# Final reduction step
|
||||
# Final reduction step
|
||||
mov $acc3, $t1
|
||||
shl \$32, $acc3
|
||||
mulq $poly3
|
||||
@@ -440,7 +441,7 @@ __ecp_nistz256_mul_montq:
|
||||
mov $acc5, $t1
|
||||
adc \$0, $acc2
|
||||
|
||||
########################################################################
|
||||
########################################################################
|
||||
# Branch-less conditional subtraction of P
|
||||
sub \$-1, $acc4 # .Lpoly[0]
|
||||
mov $acc0, $t2
|
||||
@@ -1067,6 +1068,8 @@ ecp_nistz256_from_mont:
|
||||
mov $acc1, $in_ptr
|
||||
adc \$0, %rdx
|
||||
|
||||
###########################################
|
||||
# Branch-less conditional subtraction
|
||||
sub \$-1, $acc0
|
||||
mov $acc2, %rax
|
||||
sbb $t1, $acc1
|
||||
@@ -1568,13 +1571,14 @@ $code.=<<___;
|
||||
.type __ecp_nistz256_add_toq,\@abi-omnipotent
|
||||
.align 32
|
||||
__ecp_nistz256_add_toq:
|
||||
xor $t4,$t4
|
||||
add 8*0($b_ptr), $a0
|
||||
adc 8*1($b_ptr), $a1
|
||||
mov $a0, $t0
|
||||
adc 8*2($b_ptr), $a2
|
||||
adc 8*3($b_ptr), $a3
|
||||
mov $a1, $t1
|
||||
sbb $t4, $t4
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $a0
|
||||
mov $a2, $t2
|
||||
@@ -1582,14 +1586,14 @@ __ecp_nistz256_add_toq:
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb $poly3, $a3
|
||||
test $t4, $t4
|
||||
sbb \$0, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
cmovc $t0, $a0
|
||||
cmovc $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
cmovc $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
cmovc $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
@@ -1657,13 +1661,14 @@ __ecp_nistz256_subq:
|
||||
.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent
|
||||
.align 32
|
||||
__ecp_nistz256_mul_by_2q:
|
||||
xor $t4, $t4
|
||||
add $a0, $a0 # a0:a3+a0:a3
|
||||
adc $a1, $a1
|
||||
mov $a0, $t0
|
||||
adc $a2, $a2
|
||||
adc $a3, $a3
|
||||
mov $a1, $t1
|
||||
sbb $t4, $t4
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $a0
|
||||
mov $a2, $t2
|
||||
@@ -1671,14 +1676,14 @@ __ecp_nistz256_mul_by_2q:
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb $poly3, $a3
|
||||
test $t4, $t4
|
||||
sbb \$0, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
cmovc $t0, $a0
|
||||
cmovc $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
cmovc $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
cmovc $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
@@ -1793,7 +1798,7 @@ $code.=<<___;
|
||||
movq %xmm1, $r_ptr
|
||||
call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_y, S);
|
||||
___
|
||||
{
|
||||
{
|
||||
######## ecp_nistz256_div_by_2(res_y, res_y); ##########################
|
||||
# operate in 4-5-6-7 "name space" that matches squaring output
|
||||
#
|
||||
@@ -1882,7 +1887,7 @@ $code.=<<___;
|
||||
lea $M(%rsp), $b_ptr
|
||||
mov $acc4, $acc6 # harmonize sub output and mul input
|
||||
xor %ecx, %ecx
|
||||
mov $acc4, $S+8*0(%rsp) # have to save:-(
|
||||
mov $acc4, $S+8*0(%rsp) # have to save:-(
|
||||
mov $acc5, $acc2
|
||||
mov $acc5, $S+8*1(%rsp)
|
||||
cmovz $acc0, $acc3
|
||||
@@ -2133,6 +2138,7 @@ $code.=<<___;
|
||||
#lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
|
||||
#call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
|
||||
|
||||
xor $t4, $t4
|
||||
add $acc0, $acc0 # a0:a3+a0:a3
|
||||
lea $Rsqr(%rsp), $a_ptr
|
||||
adc $acc1, $acc1
|
||||
@@ -2140,7 +2146,7 @@ $code.=<<___;
|
||||
adc $acc2, $acc2
|
||||
adc $acc3, $acc3
|
||||
mov $acc1, $t1
|
||||
sbb $t4, $t4
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $acc0
|
||||
mov $acc2, $t2
|
||||
@@ -2148,15 +2154,15 @@ $code.=<<___;
|
||||
sbb \$0, $acc2
|
||||
mov $acc3, $t3
|
||||
sbb $poly3, $acc3
|
||||
test $t4, $t4
|
||||
sbb \$0, $t4
|
||||
|
||||
cmovz $t0, $acc0
|
||||
cmovc $t0, $acc0
|
||||
mov 8*0($a_ptr), $t0
|
||||
cmovz $t1, $acc1
|
||||
cmovc $t1, $acc1
|
||||
mov 8*1($a_ptr), $t1
|
||||
cmovz $t2, $acc2
|
||||
cmovc $t2, $acc2
|
||||
mov 8*2($a_ptr), $t2
|
||||
cmovz $t3, $acc3
|
||||
cmovc $t3, $acc3
|
||||
mov 8*3($a_ptr), $t3
|
||||
|
||||
call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
|
||||
@@ -2438,6 +2444,7 @@ $code.=<<___;
|
||||
#lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
|
||||
#call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
|
||||
|
||||
xor $t4, $t4
|
||||
add $acc0, $acc0 # a0:a3+a0:a3
|
||||
lea $Rsqr(%rsp), $a_ptr
|
||||
adc $acc1, $acc1
|
||||
@@ -2445,7 +2452,7 @@ $code.=<<___;
|
||||
adc $acc2, $acc2
|
||||
adc $acc3, $acc3
|
||||
mov $acc1, $t1
|
||||
sbb $t4, $t4
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $acc0
|
||||
mov $acc2, $t2
|
||||
@@ -2453,15 +2460,15 @@ $code.=<<___;
|
||||
sbb \$0, $acc2
|
||||
mov $acc3, $t3
|
||||
sbb $poly3, $acc3
|
||||
test $t4, $t4
|
||||
sbb \$0, $t4
|
||||
|
||||
cmovz $t0, $acc0
|
||||
cmovc $t0, $acc0
|
||||
mov 8*0($a_ptr), $t0
|
||||
cmovz $t1, $acc1
|
||||
cmovc $t1, $acc1
|
||||
mov 8*1($a_ptr), $t1
|
||||
cmovz $t2, $acc2
|
||||
cmovc $t2, $acc2
|
||||
mov 8*2($a_ptr), $t2
|
||||
cmovz $t3, $acc3
|
||||
cmovc $t3, $acc3
|
||||
mov 8*3($a_ptr), $t3
|
||||
|
||||
call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
|
||||
@@ -2613,14 +2620,14 @@ __ecp_nistz256_add_tox:
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb $poly3, $a3
|
||||
sbb \$0, $t4
|
||||
|
||||
bt \$0, $t4
|
||||
cmovnc $t0, $a0
|
||||
cmovnc $t1, $a1
|
||||
cmovc $t0, $a0
|
||||
cmovc $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovnc $t2, $a2
|
||||
cmovc $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovnc $t3, $a3
|
||||
cmovc $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
@@ -2708,14 +2715,14 @@ __ecp_nistz256_mul_by_2x:
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb $poly3, $a3
|
||||
sbb \$0, $t4
|
||||
|
||||
bt \$0, $t4
|
||||
cmovnc $t0, $a0
|
||||
cmovnc $t1, $a1
|
||||
cmovc $t0, $a0
|
||||
cmovc $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovnc $t2, $a2
|
||||
cmovc $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovnc $t3, $a3
|
||||
cmovc $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
|
||||
+2
-10
@@ -26,8 +26,6 @@
|
||||
#include <openssl/nid.h>
|
||||
|
||||
|
||||
namespace bssl {
|
||||
|
||||
// kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
|
||||
// omitted.
|
||||
static const uint8_t kECKeyWithoutPublic[] = {
|
||||
@@ -112,7 +110,7 @@ static bssl::UniquePtr<EC_KEY> DecodeECPrivateKey(const uint8_t *in,
|
||||
// EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
|
||||
// returns true on success or false on error.
|
||||
static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
|
||||
ScopedCBB cbb;
|
||||
bssl::ScopedCBB cbb;
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
if (!CBB_init(cbb.get(), 0) ||
|
||||
@@ -474,7 +472,7 @@ static bool ForEachCurve(bool (*test_func)(int nid)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int Main() {
|
||||
int main() {
|
||||
CRYPTO_library_init();
|
||||
|
||||
if (!Testd2i_ECPrivateKey() ||
|
||||
@@ -490,9 +488,3 @@ static int Main() {
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace bssl
|
||||
|
||||
int main() {
|
||||
return bssl::Main();
|
||||
}
|
||||
|
||||
+12
-10
@@ -175,9 +175,9 @@ static void longfelem_scalar(longfelem out, const u64 scalar) {
|
||||
out[7] *= scalar;
|
||||
}
|
||||
|
||||
#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
|
||||
#define two105m41m9 ((((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9))
|
||||
#define two105 (((limb)1) << 105)
|
||||
#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
|
||||
#define two105m41p9 ((((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9))
|
||||
|
||||
/* zero105 is 0 mod p */
|
||||
static const felem zero105 = {two105m41m9, two105, two105m41p9, two105m41p9};
|
||||
@@ -211,9 +211,11 @@ static void felem_diff(felem out, const felem in) {
|
||||
out[3] -= in[3];
|
||||
}
|
||||
|
||||
#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
|
||||
#define two107m43m11 \
|
||||
((((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11))
|
||||
#define two107 (((limb)1) << 107)
|
||||
#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
|
||||
#define two107m43p11 \
|
||||
((((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11))
|
||||
|
||||
/* zero107 is 0 mod p */
|
||||
static const felem zero107 = {two107m43m11, two107, two107m43p11, two107m43p11};
|
||||
@@ -272,10 +274,10 @@ static void longfelem_diff(longfelem out, const longfelem in) {
|
||||
out[7] -= in[7];
|
||||
}
|
||||
|
||||
#define two64m0 (((limb)1) << 64) - 1
|
||||
#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
|
||||
#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
|
||||
#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
|
||||
#define two64m0 ((((limb)1) << 64) - 1)
|
||||
#define two110p32m0 ((((limb)1) << 110) + (((limb)1) << 32) - 1)
|
||||
#define two64m46 ((((limb)1) << 64) - (((limb)1) << 46))
|
||||
#define two64m32 ((((limb)1) << 64) - (((limb)1) << 32))
|
||||
|
||||
/* zero110 is 0 mod p. */
|
||||
static const felem zero110 = {two64m0, two110p32m0, two64m46, two64m32};
|
||||
@@ -594,9 +596,9 @@ static void felem_small_mul(longfelem out, const smallfelem small1,
|
||||
smallfelem_mul(out, small1, small2);
|
||||
}
|
||||
|
||||
#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
|
||||
#define two100m36m4 ((((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4))
|
||||
#define two100 (((limb)1) << 100)
|
||||
#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
|
||||
#define two100m36p4 ((((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4))
|
||||
|
||||
/* zero100 is 0 mod p */
|
||||
static const felem zero100 = {two100m36m4, two100, two100m36p4, two100m36p4};
|
||||
|
||||
+11
-57
@@ -31,56 +31,16 @@
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "../bn/internal.h"
|
||||
#include "../ec/internal.h"
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
#include "p256-x86_64.h"
|
||||
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
!defined(OPENSSL_SMALL)
|
||||
|
||||
|
||||
#define P256_LIMBS (256 / BN_BITS2)
|
||||
|
||||
typedef struct {
|
||||
BN_ULONG X[P256_LIMBS];
|
||||
BN_ULONG Y[P256_LIMBS];
|
||||
BN_ULONG Z[P256_LIMBS];
|
||||
} P256_POINT;
|
||||
|
||||
typedef struct {
|
||||
BN_ULONG X[P256_LIMBS];
|
||||
BN_ULONG Y[P256_LIMBS];
|
||||
} P256_POINT_AFFINE;
|
||||
|
||||
typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
|
||||
|
||||
/* Arithmetic on field elements using Almost Montgomery Multiplication. The
|
||||
* "almost" means, in particular, that the inputs and outputs of these
|
||||
* functions are in the range [0, 2**BN_BITS2), not [0, P). Only
|
||||
* |ecp_nistz256_from_mont| outputs a fully reduced value in [0, P). Almost
|
||||
* Montgomery Arithmetic is described clearly in "Efficient Software
|
||||
* Implementations of Modular Exponentiation" by Shay Gueron. */
|
||||
|
||||
/* Modular neg: res = -a mod P, where res is not fully reduced. */
|
||||
void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
|
||||
/* Montgomery mul: res = a*b*2^-256 mod P, where res is not fully reduced. */
|
||||
void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS],
|
||||
const BN_ULONG b[P256_LIMBS]);
|
||||
/* Montgomery sqr: res = a*a*2^-256 mod P, where res is not fully reduced. */
|
||||
void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS]);
|
||||
/* Convert a number from Montgomery domain, by multiplying with 1, where res
|
||||
* will be fully reduced mod P. */
|
||||
void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]);
|
||||
|
||||
|
||||
/* Functions that perform constant time access to the precomputed tables */
|
||||
void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index);
|
||||
void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
|
||||
const P256_POINT_AFFINE *in_t, int index);
|
||||
|
||||
/* One converted into the Montgomery domain */
|
||||
static const BN_ULONG ONE[P256_LIMBS] = {
|
||||
TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
|
||||
@@ -90,7 +50,7 @@ static const BN_ULONG ONE[P256_LIMBS] = {
|
||||
/* Precomputed tables for the default generator */
|
||||
#include "p256-x86_64-table.h"
|
||||
|
||||
/* Recode window to a signed digit, see ecp_nistputil.c for details */
|
||||
/* Recode window to a signed digit, see util-64.c for details */
|
||||
static unsigned booth_recode_w5(unsigned in) {
|
||||
unsigned s, d;
|
||||
|
||||
@@ -130,15 +90,11 @@ static void copy_conditional(BN_ULONG dst[P256_LIMBS],
|
||||
}
|
||||
}
|
||||
|
||||
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
|
||||
void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
|
||||
const P256_POINT *b);
|
||||
void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
|
||||
const P256_POINT_AFFINE *b);
|
||||
|
||||
/* r = in^-1 mod p */
|
||||
static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]) {
|
||||
/* ecp_nistz256_mod_inverse_mont sets |r| to (|in| * 2^-256)^-1 * 2^256 mod p.
|
||||
* That is, |r| is the modular inverse of |in| for input and output in the
|
||||
* Montgomery domain. */
|
||||
static void ecp_nistz256_mod_inverse_mont(BN_ULONG r[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]) {
|
||||
/* The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff
|
||||
ffffffff
|
||||
We use FLT and used poly-2 as exponent */
|
||||
@@ -524,13 +480,11 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecp_nistz256_mod_inverse(z_inv3, point_z);
|
||||
ecp_nistz256_mod_inverse_mont(z_inv3, point_z);
|
||||
ecp_nistz256_sqr_mont(z_inv2, z_inv3);
|
||||
|
||||
/* Unlike the |BN_mod_mul_montgomery|-based implementation, we cannot factor
|
||||
* out the two calls to |ecp_nistz256_from_mont| into one call, because
|
||||
* |ecp_nistz256_from_mont| must be the last operation to ensure that the
|
||||
* result is fully reduced mod P. */
|
||||
/* TODO(davidben): The two calls to |ecp_nistz256_from_mont| may be factored
|
||||
* into one call now that other operations also reduce mod P. */
|
||||
|
||||
if (x != NULL) {
|
||||
BN_ULONG x_aff[P256_LIMBS];
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* Copyright (c) 2014, Intel Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_EC_P256_X86_64_H
|
||||
#define OPENSSL_HEADER_EC_P256_X86_64_H
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
!defined(OPENSSL_SMALL)
|
||||
|
||||
/* P-256 field operations.
|
||||
*
|
||||
* An element mod P in P-256 is represented as a little-endian array of
|
||||
* |P256_LIMBS| |BN_ULONG|s, spanning the full range of values.
|
||||
*
|
||||
* The following functions take fully-reduced inputs mod P and give
|
||||
* fully-reduced outputs. They may be used in-place. */
|
||||
|
||||
#define P256_LIMBS (256 / BN_BITS2)
|
||||
|
||||
/* ecp_nistz256_neg sets |res| to -|a| mod P. */
|
||||
void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
|
||||
|
||||
/* ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P. */
|
||||
void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS],
|
||||
const BN_ULONG b[P256_LIMBS]);
|
||||
|
||||
/* ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P. */
|
||||
void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS]);
|
||||
|
||||
/* ecp_nistz256_from_mont sets |res| to |in|, converted from Montgomery domain
|
||||
* by multiplying with 1. */
|
||||
void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]);
|
||||
|
||||
|
||||
/* P-256 point operations.
|
||||
*
|
||||
* The following functions may be used in-place. All coordinates are in the
|
||||
* Montgomery domain. */
|
||||
|
||||
/* A P256_POINT represents a P-256 point in Jacobian coordinates. */
|
||||
typedef struct {
|
||||
BN_ULONG X[P256_LIMBS];
|
||||
BN_ULONG Y[P256_LIMBS];
|
||||
BN_ULONG Z[P256_LIMBS];
|
||||
} P256_POINT;
|
||||
|
||||
/* A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity
|
||||
* is encoded as (0, 0). */
|
||||
typedef struct {
|
||||
BN_ULONG X[P256_LIMBS];
|
||||
BN_ULONG Y[P256_LIMBS];
|
||||
} P256_POINT_AFFINE;
|
||||
|
||||
/* ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16
|
||||
* and all zeros (the point at infinity) if |index| is 0. This is done in
|
||||
* constant time. */
|
||||
void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16],
|
||||
int index);
|
||||
|
||||
/* ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64
|
||||
* and all zeros (the point at infinity) if |index| is 0. This is done in
|
||||
* constant time. */
|
||||
void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
|
||||
const P256_POINT_AFFINE in_t[64], int index);
|
||||
|
||||
/* ecp_nistz256_point_double sets |r| to |a| doubled. */
|
||||
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
|
||||
|
||||
/* ecp_nistz256_point_add adds |a| to |b| and places the result in |r|. */
|
||||
void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
|
||||
const P256_POINT *b);
|
||||
|
||||
/* ecp_nistz256_point_add_affine adds |a| to |b| and places the result in
|
||||
* |r|. |a| and |b| must not represent the same point unless they are both
|
||||
* infinity. */
|
||||
void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
|
||||
const P256_POINT_AFFINE *b);
|
||||
|
||||
#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
!defined(OPENSSL_SMALL) */
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C++ */
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_HEADER_EC_P256_X86_64_H */
|
||||
@@ -0,0 +1,511 @@
|
||||
/* Copyright (c) 2016, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#if !defined(__STDC_FORMAT_MACROS)
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../bn/internal.h"
|
||||
#include "../test/file_test.h"
|
||||
#include "p256-x86_64.h"
|
||||
|
||||
|
||||
// Disable tests if BORINGSSL_SHARED_LIBRARY is defined. These tests need access
|
||||
// to internal functions.
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
!defined(OPENSSL_SMALL) && !defined(BORINGSSL_SHARED_LIBRARY)
|
||||
|
||||
static bool TestSelectW5() {
|
||||
// Fill a table with some garbage input.
|
||||
P256_POINT table[16];
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
memset(table[i].X, 3 * i, sizeof(table[i].X));
|
||||
memset(table[i].Y, 3 * i + 1, sizeof(table[i].Y));
|
||||
memset(table[i].Z, 3 * i + 2, sizeof(table[i].Z));
|
||||
}
|
||||
|
||||
for (int i = 0; i <= 16; i++) {
|
||||
P256_POINT val;
|
||||
ecp_nistz256_select_w5(&val, table, i);
|
||||
|
||||
P256_POINT expected;
|
||||
if (i == 0) {
|
||||
memset(&expected, 0, sizeof(expected));
|
||||
} else {
|
||||
expected = table[i-1];
|
||||
}
|
||||
|
||||
if (memcmp(&val, &expected, sizeof(P256_POINT)) != 0) {
|
||||
fprintf(stderr, "ecp_nistz256_select_w5(%d) gave the wrong value.\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestSelectW7() {
|
||||
// Fill a table with some garbage input.
|
||||
P256_POINT_AFFINE table[64];
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
memset(table[i].X, 2 * i, sizeof(table[i].X));
|
||||
memset(table[i].Y, 2 * i + 1, sizeof(table[i].Y));
|
||||
}
|
||||
|
||||
for (int i = 0; i <= 64; i++) {
|
||||
P256_POINT_AFFINE val;
|
||||
ecp_nistz256_select_w7(&val, table, i);
|
||||
|
||||
P256_POINT_AFFINE expected;
|
||||
if (i == 0) {
|
||||
memset(&expected, 0, sizeof(expected));
|
||||
} else {
|
||||
expected = table[i-1];
|
||||
}
|
||||
|
||||
if (memcmp(&val, &expected, sizeof(P256_POINT_AFFINE)) != 0) {
|
||||
fprintf(stderr, "ecp_nistz256_select_w7(%d) gave the wrong value.\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetFieldElement(FileTest *t, BN_ULONG out[P256_LIMBS],
|
||||
const char *name) {
|
||||
std::vector<uint8_t> bytes;
|
||||
if (!t->GetBytes(&bytes, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bytes.size() != BN_BYTES * P256_LIMBS) {
|
||||
t->PrintLine("Invalid length: %s", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// |byte| contains bytes in big-endian while |out| should contain |BN_ULONG|s
|
||||
// in little-endian.
|
||||
memset(out, 0, P256_LIMBS * sizeof(BN_ULONG));
|
||||
for (size_t i = 0; i < bytes.size(); i++) {
|
||||
out[P256_LIMBS - 1 - (i / BN_BYTES)] <<= 8;
|
||||
out[P256_LIMBS - 1 - (i / BN_BYTES)] |= bytes[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string FieldElementToString(const BN_ULONG a[P256_LIMBS]) {
|
||||
std::string ret;
|
||||
for (size_t i = P256_LIMBS-1; i < P256_LIMBS; i--) {
|
||||
char buf[2 * BN_BYTES + 1];
|
||||
BIO_snprintf(buf, sizeof(buf), BN_HEX_FMT2, a[i]);
|
||||
ret += buf;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ExpectFieldElementsEqual(FileTest *t, const char *message,
|
||||
const BN_ULONG expected[P256_LIMBS],
|
||||
const BN_ULONG actual[P256_LIMBS]) {
|
||||
if (memcmp(expected, actual, sizeof(BN_ULONG) * P256_LIMBS) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
t->PrintLine("%s", message);
|
||||
t->PrintLine("Expected: %s", FieldElementToString(expected).c_str());
|
||||
t->PrintLine("Actual: %s", FieldElementToString(actual).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool PointToAffine(P256_POINT_AFFINE *out, const P256_POINT *in) {
|
||||
static const uint8_t kP[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
|
||||
bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), z(BN_new());
|
||||
bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
|
||||
if (!x || !y || !z || !p ||
|
||||
!bn_set_words(x.get(), in->X, P256_LIMBS) ||
|
||||
!bn_set_words(y.get(), in->Y, P256_LIMBS) ||
|
||||
!bn_set_words(z.get(), in->Z, P256_LIMBS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Coordinates must be fully-reduced.
|
||||
if (BN_is_negative(x.get()) ||
|
||||
BN_is_negative(y.get()) ||
|
||||
BN_is_negative(z.get()) ||
|
||||
BN_cmp(x.get(), p.get()) >= 0 ||
|
||||
BN_cmp(y.get(), p.get()) >= 0 ||
|
||||
BN_cmp(z.get(), p.get()) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(out, 0, sizeof(P256_POINT_AFFINE));
|
||||
|
||||
if (BN_is_zero(z.get())) {
|
||||
// The point at infinity is represented as (0, 0).
|
||||
return true;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
|
||||
bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
|
||||
if (!ctx || !mont ||
|
||||
!BN_MONT_CTX_set(mont.get(), p.get(), ctx.get()) ||
|
||||
// Invert Z.
|
||||
!BN_from_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
|
||||
!BN_mod_inverse(z.get(), z.get(), p.get(), ctx.get()) ||
|
||||
!BN_to_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
|
||||
// Convert (X, Y, Z) to (X/Z^2, Y/Z^3).
|
||||
!BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
|
||||
ctx.get()) ||
|
||||
!BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
|
||||
ctx.get()) ||
|
||||
!BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
|
||||
ctx.get()) ||
|
||||
!BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
|
||||
ctx.get()) ||
|
||||
!BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
|
||||
ctx.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(out->X, x->d, sizeof(BN_ULONG) * x->top);
|
||||
memcpy(out->Y, y->d, sizeof(BN_ULONG) * y->top);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ExpectPointsEqual(FileTest *t, const char *message,
|
||||
const P256_POINT_AFFINE *expected,
|
||||
const P256_POINT *point) {
|
||||
// There are multiple representations of the same |P256_POINT|, so convert to
|
||||
// |P256_POINT_AFFINE| and compare.
|
||||
P256_POINT_AFFINE affine;
|
||||
if (!PointToAffine(&affine, point)) {
|
||||
t->PrintLine("%s", message);
|
||||
t->PrintLine("Could not convert to affine: (%s, %s, %s)",
|
||||
FieldElementToString(point->X).c_str(),
|
||||
FieldElementToString(point->Y).c_str(),
|
||||
FieldElementToString(point->Z).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(expected, &affine, sizeof(P256_POINT_AFFINE)) != 0) {
|
||||
t->PrintLine("%s", message);
|
||||
t->PrintLine("Expected: (%s, %s)",
|
||||
FieldElementToString(expected->X).c_str(),
|
||||
FieldElementToString(expected->Y).c_str());
|
||||
t->PrintLine("Actual: (%s, %s)", FieldElementToString(affine.X).c_str(),
|
||||
FieldElementToString(affine.Y).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestNegate(FileTest *t) {
|
||||
BN_ULONG a[P256_LIMBS], b[P256_LIMBS];
|
||||
if (!GetFieldElement(t, a, "A") ||
|
||||
!GetFieldElement(t, b, "B")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test that -A = B.
|
||||
BN_ULONG ret[P256_LIMBS];
|
||||
ecp_nistz256_neg(ret, a);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_neg(A) was incorrect.", b,
|
||||
ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, a, sizeof(ret));
|
||||
ecp_nistz256_neg(ret, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "In-place ecp_nistz256_neg(A) was incorrect.", b, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test that -B = A.
|
||||
ecp_nistz256_neg(ret, b);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_neg(B) was incorrect.", a,
|
||||
ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, b, sizeof(ret));
|
||||
ecp_nistz256_neg(ret, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "In-place ecp_nistz256_neg(B) was incorrect.", a, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestMulMont(FileTest *t) {
|
||||
BN_ULONG a[P256_LIMBS], b[P256_LIMBS], result[P256_LIMBS];
|
||||
if (!GetFieldElement(t, a, "A") ||
|
||||
!GetFieldElement(t, b, "B") ||
|
||||
!GetFieldElement(t, result, "Result")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BN_ULONG ret[P256_LIMBS];
|
||||
ecp_nistz256_mul_mont(ret, a, b);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_mul_mont(A, B) was incorrect.",
|
||||
result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecp_nistz256_mul_mont(ret, b, a);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_mul_mont(B, A) was incorrect.",
|
||||
result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, a, sizeof(ret));
|
||||
ecp_nistz256_mul_mont(ret, ret, b);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_mul_mont(ret = A, B) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, a, sizeof(ret));
|
||||
ecp_nistz256_mul_mont(ret, b, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_mul_mont(B, ret = A) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, b, sizeof(ret));
|
||||
ecp_nistz256_mul_mont(ret, a, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_mul_mont(A, ret = B) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, b, sizeof(ret));
|
||||
ecp_nistz256_mul_mont(ret, ret, a);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_mul_mont(ret = B, A) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(a, b, sizeof(a)) == 0) {
|
||||
ecp_nistz256_sqr_mont(ret, a);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_sqr_mont(A) was incorrect.",
|
||||
result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, a, sizeof(ret));
|
||||
ecp_nistz256_sqr_mont(ret, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_sqr_mont(ret = A) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestFromMont(FileTest *t) {
|
||||
BN_ULONG a[P256_LIMBS], result[P256_LIMBS];
|
||||
if (!GetFieldElement(t, a, "A") ||
|
||||
!GetFieldElement(t, result, "Result")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BN_ULONG ret[P256_LIMBS];
|
||||
ecp_nistz256_from_mont(ret, a);
|
||||
if (!ExpectFieldElementsEqual(t, "ecp_nistz256_from_mont(A) was incorrect.",
|
||||
result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(ret, a, sizeof(ret));
|
||||
ecp_nistz256_from_mont(ret, ret);
|
||||
if (!ExpectFieldElementsEqual(
|
||||
t, "ecp_nistz256_from_mont(ret = A) was incorrect.", result, ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestPointAdd(FileTest *t) {
|
||||
P256_POINT a, b;
|
||||
P256_POINT_AFFINE result;
|
||||
if (!GetFieldElement(t, a.X, "A.X") ||
|
||||
!GetFieldElement(t, a.Y, "A.Y") ||
|
||||
!GetFieldElement(t, a.Z, "A.Z") ||
|
||||
!GetFieldElement(t, b.X, "B.X") ||
|
||||
!GetFieldElement(t, b.Y, "B.Y") ||
|
||||
!GetFieldElement(t, b.Z, "B.Z") ||
|
||||
!GetFieldElement(t, result.X, "Result.X") ||
|
||||
!GetFieldElement(t, result.Y, "Result.Y")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
P256_POINT ret;
|
||||
ecp_nistz256_point_add(&ret, &a, &b);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(A, B) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecp_nistz256_point_add(&ret, &b, &a);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(B, A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &a, sizeof(ret));
|
||||
ecp_nistz256_point_add(&ret, &ret, &b);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = A, B) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &a, sizeof(ret));
|
||||
ecp_nistz256_point_add(&ret, &b, &ret);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(B, ret = A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &b, sizeof(ret));
|
||||
ecp_nistz256_point_add(&ret, &a, &ret);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = A, B) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &b, sizeof(ret));
|
||||
ecp_nistz256_point_add(&ret, &ret, &a);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = B, A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
P256_POINT_AFFINE a_affine, b_affine, infinity;
|
||||
memset(&infinity, 0, sizeof(infinity));
|
||||
if (!PointToAffine(&a_affine, &a) ||
|
||||
!PointToAffine(&b_affine, &b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ecp_nistz256_point_add_affine does not work when a == b unless doubling the
|
||||
// point at infinity.
|
||||
if (memcmp(&a_affine, &b_affine, sizeof(a_affine)) != 0 ||
|
||||
memcmp(&a_affine, &infinity, sizeof(a_affine)) == 0) {
|
||||
ecp_nistz256_point_add_affine(&ret, &a, &b_affine);
|
||||
if (!ExpectPointsEqual(t,
|
||||
"ecp_nistz256_point_add_affine(A, B) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &a, sizeof(ret));
|
||||
ecp_nistz256_point_add_affine(&ret, &ret, &b_affine);
|
||||
if (!ExpectPointsEqual(
|
||||
t, "ecp_nistz256_point_add_affine(ret = A, B) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ecp_nistz256_point_add_affine(&ret, &b, &a_affine);
|
||||
if (!ExpectPointsEqual(t,
|
||||
"ecp_nistz256_point_add_affine(B, A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&ret, &b, sizeof(ret));
|
||||
ecp_nistz256_point_add_affine(&ret, &ret, &a_affine);
|
||||
if (!ExpectPointsEqual(
|
||||
t, "ecp_nistz256_point_add_affine(ret = B, A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(&a, &b, sizeof(a)) == 0) {
|
||||
ecp_nistz256_point_double(&ret, &a);
|
||||
if (!ExpectPointsEqual(t, "ecp_nistz256_point_double(A) was incorrect.",
|
||||
&result, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = a;
|
||||
ecp_nistz256_point_double(&ret, &ret);
|
||||
if (!ExpectPointsEqual(
|
||||
t, "In-place ecp_nistz256_point_double(A) was incorrect.", &result,
|
||||
&ret)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s TEST_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!TestSelectW5() ||
|
||||
!TestSelectW7()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return FileTestMain([](FileTest *t, void *) -> bool {
|
||||
if (t->GetParameter() == "Negate") {
|
||||
return TestNegate(t);
|
||||
}
|
||||
if (t->GetParameter() == "MulMont") {
|
||||
return TestMulMont(t);
|
||||
}
|
||||
if (t->GetParameter() == "FromMont") {
|
||||
return TestFromMont(t);
|
||||
}
|
||||
if (t->GetParameter() == "PointAdd") {
|
||||
return TestPointAdd(t);
|
||||
}
|
||||
|
||||
t->PrintLine("Unknown test type: %s", t->GetParameter().c_str());
|
||||
return false;
|
||||
}, nullptr, argv[1]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main() {
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -76,7 +76,7 @@
|
||||
|
||||
|
||||
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
|
||||
EC_KEY *priv_key,
|
||||
const EC_KEY *priv_key,
|
||||
void *(*kdf)(const void *in, size_t inlen, void *out,
|
||||
size_t *outlen)) {
|
||||
const BIGNUM *const priv = EC_KEY_get0_private_key(priv_key);
|
||||
|
||||
@@ -95,15 +95,18 @@ SSL,181,NO_PRIVATE_KEY_ASSIGNED
|
||||
SSL,182,NO_RENEGOTIATION
|
||||
SSL,183,NO_REQUIRED_DIGEST
|
||||
SSL,184,NO_SHARED_CIPHER
|
||||
SSL,266,NO_SHARED_GROUP
|
||||
SSL,185,NULL_SSL_CTX
|
||||
SSL,186,NULL_SSL_METHOD_PASSED
|
||||
SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
|
||||
SSL,268,OLD_SESSION_PRF_HASH_MISMATCH
|
||||
SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
|
||||
SSL,189,OUTPUT_ALIASES_INPUT
|
||||
SSL,190,PARSE_TLSEXT
|
||||
SSL,191,PATH_TOO_LONG
|
||||
SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
|
||||
SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
|
||||
SSL,267,PRE_SHARED_KEY_MUST_BE_LAST
|
||||
SSL,194,PROTOCOL_IS_SHUTDOWN
|
||||
SSL,195,PSK_IDENTITY_NOT_FOUND
|
||||
SSL,196,PSK_NO_CLIENT_CB
|
||||
@@ -156,7 +159,9 @@ SSL,1048,TLSV1_ALERT_UNKNOWN_CA
|
||||
SSL,1090,TLSV1_ALERT_USER_CANCELLED
|
||||
SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
|
||||
SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
SSL,1116,TLSV1_CERTIFICATE_REQUIRED
|
||||
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
|
||||
SSL,1115,TLSV1_UNKNOWN_PSK_IDENTITY
|
||||
SSL,1112,TLSV1_UNRECOGNIZED_NAME
|
||||
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
|
||||
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
|
||||
|
||||
+15
-15
@@ -114,23 +114,23 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
#define R0(a, b, c, d, k, s, t) \
|
||||
{ \
|
||||
a += ((k) + (t)+F((b), (c), (d))); \
|
||||
a = ROTATE(a, s); \
|
||||
};
|
||||
#define R0(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + F((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
} while (0)
|
||||
|
||||
#define R1(a, b, c, d, k, s, t) \
|
||||
{ \
|
||||
a += ((k) + (t)+G((b), (c), (d))); \
|
||||
a = ROTATE(a, s); \
|
||||
};
|
||||
#define R1(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + G((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
} while (0)
|
||||
|
||||
#define R2(a, b, c, d, k, s, t) \
|
||||
{ \
|
||||
a += ((k) + (t)+H((b), (c), (d))); \
|
||||
a = ROTATE(a, s); \
|
||||
};
|
||||
#define R2(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + H((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
} while (0)
|
||||
|
||||
void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) {
|
||||
uint32_t A, B, C, D, l;
|
||||
|
||||
+28
-20
@@ -122,32 +122,40 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
* simplified to the code below. Wei attributes these optimizations
|
||||
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
|
||||
*/
|
||||
#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
|
||||
#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
|
||||
#define H(b,c,d) ((b) ^ (c) ^ (d))
|
||||
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
|
||||
#define F(b, c, d) ((((c) ^ (d)) & (b)) ^ (d))
|
||||
#define G(b, c, d) ((((b) ^ (c)) & (d)) ^ (c))
|
||||
#define H(b, c, d) ((b) ^ (c) ^ (d))
|
||||
#define I(b, c, d) (((~(d)) | (b)) ^ (c))
|
||||
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
#define R0(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+F((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };\
|
||||
#define R0(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + F((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
(a) += (b); \
|
||||
} while (0)
|
||||
|
||||
#define R1(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+G((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
#define R1(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + G((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
(a) += (b); \
|
||||
} while (0)
|
||||
|
||||
#define R2(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+H((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
#define R2(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + H((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
(a) += (b); \
|
||||
} while (0)
|
||||
|
||||
#define R3(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+I((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
#define R3(a, b, c, d, k, s, t) \
|
||||
do { \
|
||||
(a) += ((k) + (t) + I((b), (c), (d))); \
|
||||
(a) = ROTATE(a, s); \
|
||||
(a) += (b); \
|
||||
} while (0)
|
||||
|
||||
#ifndef md5_block_data_order
|
||||
#ifdef X
|
||||
|
||||
@@ -68,14 +68,6 @@
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
OPENSSL_MSVC_PRAGMA(warning(push, 3))
|
||||
#include <windows.h>
|
||||
|
||||
/* Work around a clang-cl bug: SecureZeroMemory() below uses __stosb() but
|
||||
* windows.h only declares that intrinsic and then uses `#pragma intrinsic` for
|
||||
* it. clang-cl doesn't implement `#pragma intrinsic` yet; it instead defines
|
||||
* the function as an always-inline symbol in its intrin.h.
|
||||
* TODO(thakis): Remove this once http://llvm.org/PR19898 is fixed.
|
||||
*/
|
||||
#include <intrin.h>
|
||||
OPENSSL_MSVC_PRAGMA(warning(pop))
|
||||
#else
|
||||
#include <strings.h>
|
||||
|
||||
+14
-14
@@ -74,17 +74,17 @@
|
||||
#endif
|
||||
|
||||
#define PACK(s) ((size_t)(s) << (sizeof(size_t) * 8 - 16))
|
||||
#define REDUCE1BIT(V) \
|
||||
do { \
|
||||
if (sizeof(size_t) == 8) { \
|
||||
uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \
|
||||
V.lo = (V.hi << 63) | (V.lo >> 1); \
|
||||
V.hi = (V.hi >> 1) ^ T; \
|
||||
} else { \
|
||||
uint32_t T = 0xe1000000U & (0 - (uint32_t)(V.lo & 1)); \
|
||||
V.lo = (V.hi << 63) | (V.lo >> 1); \
|
||||
V.hi = (V.hi >> 1) ^ ((uint64_t)T << 32); \
|
||||
} \
|
||||
#define REDUCE1BIT(V) \
|
||||
do { \
|
||||
if (sizeof(size_t) == 8) { \
|
||||
uint64_t T = UINT64_C(0xe100000000000000) & (0 - ((V).lo & 1)); \
|
||||
(V).lo = ((V).hi << 63) | ((V).lo >> 1); \
|
||||
(V).hi = ((V).hi >> 1) ^ T; \
|
||||
} else { \
|
||||
uint32_t T = 0xe1000000U & (0 - (uint32_t)((V).lo & 1)); \
|
||||
(V).lo = ((V).hi << 63) | ((V).lo >> 1); \
|
||||
(V).hi = ((V).hi >> 1) ^ ((uint64_t)T << 32); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four
|
||||
@@ -313,7 +313,7 @@ void gcm_ghash_4bit(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
|
||||
size_t len);
|
||||
#endif
|
||||
|
||||
#define GCM_MUL(ctx, Xi) gcm_gmult_4bit(ctx->Xi.u, ctx->Htable)
|
||||
#define GCM_MUL(ctx, Xi) gcm_gmult_4bit((ctx)->Xi.u, (ctx)->Htable)
|
||||
#if defined(GHASH_ASM)
|
||||
#define GHASH(ctx, in, len) gcm_ghash_4bit((ctx)->Xi.u, (ctx)->Htable, in, len)
|
||||
/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache
|
||||
@@ -418,10 +418,10 @@ void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
|
||||
|
||||
#ifdef GCM_FUNCREF_4BIT
|
||||
#undef GCM_MUL
|
||||
#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)(ctx->Xi.u, ctx->Htable)
|
||||
#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi.u, (ctx)->Htable)
|
||||
#ifdef GHASH
|
||||
#undef GHASH
|
||||
#define GHASH(ctx, in, len) (*gcm_ghash_p)(ctx->Xi.u, ctx->Htable, in, len)
|
||||
#define GHASH(ctx, in, len) (*gcm_ghash_p)((ctx)->Xi.u, (ctx)->Htable, in, len)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64)
|
||||
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM)
|
||||
/* We can assume little-endian. */
|
||||
static uint32_t U8TO32_LE(const uint8_t *m) {
|
||||
uint32_t r;
|
||||
@@ -36,19 +35,6 @@ static uint32_t U8TO32_LE(const uint8_t *m) {
|
||||
}
|
||||
|
||||
static void U32TO8_LE(uint8_t *m, uint32_t v) { memcpy(m, &v, sizeof(v)); }
|
||||
#else
|
||||
static uint32_t U8TO32_LE(const uint8_t *m) {
|
||||
return (uint32_t)m[0] | (uint32_t)m[1] << 8 | (uint32_t)m[2] << 16 |
|
||||
(uint32_t)m[3] << 24;
|
||||
}
|
||||
|
||||
static void U32TO8_LE(uint8_t *m, uint32_t v) {
|
||||
m[0] = v;
|
||||
m[1] = v >> 8;
|
||||
m[2] = v >> 16;
|
||||
m[3] = v >> 24;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; }
|
||||
|
||||
@@ -61,6 +47,11 @@ struct poly1305_state_st {
|
||||
uint8_t key[16];
|
||||
};
|
||||
|
||||
static inline struct poly1305_state_st *poly1305_aligned_state(
|
||||
poly1305_state *state) {
|
||||
return (struct poly1305_state_st *)(((uintptr_t)state + 63) & ~63);
|
||||
}
|
||||
|
||||
/* poly1305_blocks updates |state| given some amount of input data. This
|
||||
* function may only be called with a |len| that is not a multiple of 16 at the
|
||||
* end of the data. Otherwise the input must be buffered into 16 byte blocks. */
|
||||
@@ -159,7 +150,7 @@ poly1305_donna_atmost15bytes:
|
||||
}
|
||||
|
||||
void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
|
||||
struct poly1305_state_st *state = poly1305_aligned_state(statep);
|
||||
uint32_t t0, t1, t2, t3;
|
||||
|
||||
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
|
||||
@@ -207,7 +198,7 @@ void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) {
|
||||
void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
|
||||
size_t in_len) {
|
||||
unsigned int i;
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
|
||||
struct poly1305_state_st *state = poly1305_aligned_state(statep);
|
||||
|
||||
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
|
||||
if (CRYPTO_is_NEON_capable()) {
|
||||
@@ -250,7 +241,7 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
|
||||
}
|
||||
|
||||
void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
|
||||
struct poly1305_state_st *state = poly1305_aligned_state(statep);
|
||||
uint64_t f0, f1, f2, f3;
|
||||
uint32_t g0, g1, g2, g3, g4;
|
||||
uint32_t b, nb;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
include_directories(../../include)
|
||||
|
||||
add_library(
|
||||
pool
|
||||
|
||||
OBJECT
|
||||
|
||||
pool.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
pool_test
|
||||
|
||||
pool_test.cc
|
||||
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(pool_test crypto)
|
||||
add_dependencies(all_tests pool_test)
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2016, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_POOL_INTERNAL_H
|
||||
#define OPENSSL_HEADER_POOL_INTERNAL_H
|
||||
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/thread.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
DECLARE_LHASH_OF(CRYPTO_BUFFER);
|
||||
|
||||
struct crypto_buffer_st {
|
||||
CRYPTO_BUFFER_POOL *pool;
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
CRYPTO_refcount_t references;
|
||||
};
|
||||
|
||||
struct crypto_buffer_pool_st {
|
||||
LHASH_OF(CRYPTO_BUFFER) *bufs;
|
||||
CRYPTO_MUTEX lock;
|
||||
};
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_HEADER_POOL_INTERNAL_H */
|
||||
@@ -0,0 +1,200 @@
|
||||
/* Copyright (c) 2016, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <openssl/pool.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/buf.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/thread.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) {
|
||||
return OPENSSL_hash32(buf->data, buf->len);
|
||||
}
|
||||
|
||||
static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) {
|
||||
if (a->len != b->len) {
|
||||
return 1;
|
||||
}
|
||||
return memcmp(a->data, b->data, a->len);
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) {
|
||||
CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL));
|
||||
if (pool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL));
|
||||
pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp);
|
||||
if (pool->bufs == NULL) {
|
||||
OPENSSL_free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CRYPTO_MUTEX_init(&pool->lock);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) {
|
||||
if (pool == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
CRYPTO_MUTEX_lock_write(&pool->lock);
|
||||
assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0);
|
||||
CRYPTO_MUTEX_unlock_write(&pool->lock);
|
||||
#endif
|
||||
|
||||
lh_CRYPTO_BUFFER_free(pool->bufs);
|
||||
CRYPTO_MUTEX_cleanup(&pool->lock);
|
||||
OPENSSL_free(pool);
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len,
|
||||
CRYPTO_BUFFER_POOL *pool) {
|
||||
if (pool != NULL) {
|
||||
CRYPTO_BUFFER tmp;
|
||||
tmp.data = (uint8_t *) data;
|
||||
tmp.len = len;
|
||||
|
||||
CRYPTO_MUTEX_lock_read(&pool->lock);
|
||||
CRYPTO_BUFFER *const duplicate =
|
||||
lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp);
|
||||
if (duplicate != NULL) {
|
||||
CRYPTO_refcount_inc(&duplicate->references);
|
||||
}
|
||||
CRYPTO_MUTEX_unlock_read(&pool->lock);
|
||||
|
||||
if (duplicate != NULL) {
|
||||
return duplicate;
|
||||
}
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER));
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(buf, 0, sizeof(CRYPTO_BUFFER));
|
||||
|
||||
buf->data = BUF_memdup(data, len);
|
||||
if (len != 0 && buf->data == NULL) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->len = len;
|
||||
buf->references = 1;
|
||||
|
||||
if (pool == NULL) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
buf->pool = pool;
|
||||
|
||||
CRYPTO_MUTEX_lock_write(&pool->lock);
|
||||
CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf);
|
||||
int inserted = 0;
|
||||
if (duplicate == NULL) {
|
||||
CRYPTO_BUFFER *old = NULL;
|
||||
inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf);
|
||||
assert(old == NULL);
|
||||
} else {
|
||||
CRYPTO_refcount_inc(&duplicate->references);
|
||||
}
|
||||
CRYPTO_MUTEX_unlock_write(&pool->lock);
|
||||
|
||||
if (!inserted) {
|
||||
/* We raced to insert |buf| into the pool and lost, or else there was an
|
||||
* error inserting. */
|
||||
OPENSSL_free(buf->data);
|
||||
OPENSSL_free(buf);
|
||||
return duplicate;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER* CRYPTO_BUFFER_new_from_CBS(CBS *cbs, CRYPTO_BUFFER_POOL *pool) {
|
||||
return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool);
|
||||
}
|
||||
|
||||
void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) {
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER_POOL *const pool = buf->pool;
|
||||
if (pool == NULL) {
|
||||
if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) {
|
||||
/* If a reference count of zero is observed, there cannot be a reference
|
||||
* from any pool to this buffer and thus we are able to free this
|
||||
* buffer. */
|
||||
OPENSSL_free(buf->data);
|
||||
OPENSSL_free(buf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CRYPTO_MUTEX_lock_write(&pool->lock);
|
||||
if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) {
|
||||
CRYPTO_MUTEX_unlock_write(&buf->pool->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have an exclusive lock on the pool, therefore no concurrent lookups can
|
||||
* find this buffer and increment the reference count. Thus, if the count is
|
||||
* zero there are and can never be any more references and thus we can free
|
||||
* this buffer. */
|
||||
void *found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf);
|
||||
assert(found != NULL);
|
||||
assert(found == buf);
|
||||
(void)found;
|
||||
CRYPTO_MUTEX_unlock_write(&buf->pool->lock);
|
||||
OPENSSL_free(buf->data);
|
||||
OPENSSL_free(buf);
|
||||
}
|
||||
|
||||
int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) {
|
||||
/* This is safe in the case that |buf->pool| is NULL because it's just
|
||||
* standard reference counting in that case.
|
||||
*
|
||||
* This is also safe if |buf->pool| is non-NULL because, if it were racing
|
||||
* with |CRYPTO_BUFFER_free| then the two callers must have independent
|
||||
* references already and so the reference count will never hit zero. */
|
||||
CRYPTO_refcount_inc(&buf->references);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) {
|
||||
return buf->data;
|
||||
}
|
||||
|
||||
size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) {
|
||||
return buf->len;
|
||||
}
|
||||
|
||||
void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) {
|
||||
CBS_init(out, buf->data, buf->len);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Copyright (c) 2016, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/pool.h>
|
||||
|
||||
|
||||
static bool TestUnpooled() {
|
||||
static const uint8_t kData[4] = {1, 2, 3, 4};
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||
CRYPTO_BUFFER_new(kData, sizeof(kData), nullptr));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CRYPTO_BUFFER_len(buf.get()) != sizeof(kData) ||
|
||||
memcmp(kData, CRYPTO_BUFFER_data(buf.get()), sizeof(kData)) != 0) {
|
||||
fprintf(stderr, "CRYPTO_BUFFER corrupted data.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CRYPTO_BUFFER_up_ref(buf.get());
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf2(buf.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestEmpty() {
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(nullptr, 0, nullptr));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestPool() {
|
||||
bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new());
|
||||
if (!pool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static const uint8_t kData[4] = {1, 2, 3, 4};
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||
CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf2(
|
||||
CRYPTO_BUFFER_new(kData, sizeof(kData), pool.get()));
|
||||
if (!buf2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf.get() != buf2.get()) {
|
||||
fprintf(stderr, "CRYPTO_BUFFER_POOL did not dedup data.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (!TestUnpooled() ||
|
||||
!TestEmpty() ||
|
||||
!TestPool()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -44,4 +44,4 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) {
|
||||
g_num_calls++;
|
||||
}
|
||||
|
||||
#endif /* BORINGSSL_UNSAFE_FUZZER_MODE */
|
||||
#endif /* BORINGSSL_UNSAFE_DETERMINISTIC_MODE */
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ static void rand_thread_state_free(void *state) {
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
|
||||
!defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
!defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
|
||||
|
||||
/* These functions are defined in asm/rdrand-x86_64.pl */
|
||||
extern int CRYPTO_rdrand(uint8_t out[8]);
|
||||
|
||||
+60
-9
@@ -12,9 +12,13 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE /* needed for syscall() on Linux. */
|
||||
#endif
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if !defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
#if !defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
@@ -22,6 +26,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(OPENSSL_LINUX)
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/thread.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -29,6 +37,43 @@
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#if defined(OPENSSL_LINUX)
|
||||
|
||||
#if defined(OPENSSL_X86_64)
|
||||
#define EXPECTED_SYS_getrandom 318
|
||||
#elif defined(OPENSSL_X86)
|
||||
#define EXPECTED_SYS_getrandom 355
|
||||
#elif defined(OPENSSL_AARCH64)
|
||||
#define EXPECTED_SYS_getrandom 278
|
||||
#elif defined(OPENSSL_ARM)
|
||||
#define EXPECTED_SYS_getrandom 384
|
||||
#elif defined(OPENSSL_PPC64LE)
|
||||
#define EXPECTED_SYS_getrandom 359
|
||||
#endif
|
||||
|
||||
#if defined(EXPECTED_SYS_getrandom)
|
||||
#define USE_SYS_getrandom
|
||||
|
||||
#if defined(SYS_getrandom)
|
||||
|
||||
#if SYS_getrandom != EXPECTED_SYS_getrandom
|
||||
#error "system call number for getrandom is not the expected value"
|
||||
#endif
|
||||
|
||||
#else /* SYS_getrandom */
|
||||
|
||||
#define SYS_getrandom EXPECTED_SYS_getrandom
|
||||
|
||||
#endif /* SYS_getrandom */
|
||||
|
||||
#endif /* EXPECTED_SYS_getrandom */
|
||||
|
||||
#if !defined(GRND_NONBLOCK)
|
||||
#define GRND_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_LINUX */
|
||||
|
||||
/* This file implements a PRNG by reading from /dev/urandom, optionally with a
|
||||
* buffer, which is unsafe across |fork|. */
|
||||
|
||||
@@ -71,6 +116,12 @@ static void init_once(void) {
|
||||
int fd = urandom_fd_requested;
|
||||
CRYPTO_STATIC_MUTEX_unlock_read(&requested_lock);
|
||||
|
||||
#if defined(USE_SYS_getrandom)
|
||||
/* Initial test of getrandom to find any unexpected behavior. */
|
||||
uint8_t dummy;
|
||||
syscall(SYS_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);
|
||||
#endif
|
||||
|
||||
if (fd == -2) {
|
||||
do {
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
@@ -144,7 +195,7 @@ static struct rand_buffer *get_thread_local_buffer(void) {
|
||||
if (buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
buf->used = BUF_SIZE; /* To trigger a |read_full| on first use. */
|
||||
buf->used = BUF_SIZE; /* To trigger a |fill_with_entropy| on first use. */
|
||||
if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF, buf,
|
||||
OPENSSL_free)) {
|
||||
OPENSSL_free(buf);
|
||||
@@ -154,14 +205,14 @@ static struct rand_buffer *get_thread_local_buffer(void) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In
|
||||
* the case of an error it returns 0. */
|
||||
static char read_full(int fd, uint8_t *out, size_t len) {
|
||||
/* fill_with_entropy writes |len| bytes of entropy into |out|. It returns one
|
||||
* on success and zero on error. */
|
||||
static char fill_with_entropy(uint8_t *out, size_t len) {
|
||||
ssize_t r;
|
||||
|
||||
while (len > 0) {
|
||||
do {
|
||||
r = read(fd, out, len);
|
||||
r = read(urandom_fd, out, len);
|
||||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r <= 0) {
|
||||
@@ -186,7 +237,7 @@ static void read_from_buffer(struct rand_buffer *buf,
|
||||
out += remaining;
|
||||
requested -= remaining;
|
||||
|
||||
if (!read_full(urandom_fd, buf->rand, BUF_SIZE)) {
|
||||
if (!fill_with_entropy(buf->rand, BUF_SIZE)) {
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
@@ -213,9 +264,9 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!read_full(urandom_fd, out, requested)) {
|
||||
if (!fill_with_entropy(out, requested)) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
|
||||
#endif /* !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE */
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
||||
#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
@@ -50,4 +50,4 @@ void CRYPTO_sysrand(uint8_t *out, size_t requested) {
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
|
||||
#endif /* OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE */
|
||||
|
||||
+55
-40
@@ -119,7 +119,10 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
|
||||
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
#define Xupdate(a, ix, ia, ib, ic, id) \
|
||||
((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1))
|
||||
do { \
|
||||
(a) = ((ia) ^ (ib) ^ (ic) ^ (id)); \
|
||||
(ix) = (a) = ROTATE((a), 1); \
|
||||
} while (0)
|
||||
|
||||
#ifndef SHA1_ASM
|
||||
static
|
||||
@@ -143,34 +146,46 @@ void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d)))
|
||||
#define F_60_79(b, c, d) F_20_39(b, c, d)
|
||||
|
||||
#define BODY_00_15(i, a, b, c, d, e, f, xi) \
|
||||
(f) = xi + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_00_15(i, a, b, c, d, e, f, xi) \
|
||||
do { \
|
||||
(f) = (xi) + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
|
||||
Xupdate(f, xi, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
|
||||
do { \
|
||||
Xupdate(f, xi, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
|
||||
Xupdate(f, xi, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
|
||||
do { \
|
||||
Xupdate(f, xi, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
do { \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_40_59 + ROTATE((a), 5) + F_40_59((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
do { \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) += (e) + K_40_59 + ROTATE((a), 5) + F_40_59((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) = xa + (e) + K_60_79 + ROTATE((a), 5) + F_60_79((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30);
|
||||
#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \
|
||||
do { \
|
||||
Xupdate(f, xa, xa, xb, xc, xd); \
|
||||
(f) = (xa) + (e) + K_60_79 + ROTATE((a), 5) + F_60_79((b), (c), (d)); \
|
||||
(b) = ROTATE((b), 30); \
|
||||
} while (0)
|
||||
|
||||
#ifdef X
|
||||
#undef X
|
||||
@@ -199,51 +214,51 @@ static void sha1_block_data_order(uint32_t *state, const uint8_t *data,
|
||||
E = state[4];
|
||||
|
||||
for (;;) {
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(0) = l;
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(1) = l;
|
||||
BODY_00_15(0, A, B, C, D, E, T, X(0));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(2) = l;
|
||||
BODY_00_15(1, T, A, B, C, D, E, X(1));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(3) = l;
|
||||
BODY_00_15(2, E, T, A, B, C, D, X(2));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(4) = l;
|
||||
BODY_00_15(3, D, E, T, A, B, C, X(3));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(5) = l;
|
||||
BODY_00_15(4, C, D, E, T, A, B, X(4));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(6) = l;
|
||||
BODY_00_15(5, B, C, D, E, T, A, X(5));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(7) = l;
|
||||
BODY_00_15(6, A, B, C, D, E, T, X(6));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(8) = l;
|
||||
BODY_00_15(7, T, A, B, C, D, E, X(7));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(9) = l;
|
||||
BODY_00_15(8, E, T, A, B, C, D, X(8));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(10) = l;
|
||||
BODY_00_15(9, D, E, T, A, B, C, X(9));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(11) = l;
|
||||
BODY_00_15(10, C, D, E, T, A, B, X(10));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(12) = l;
|
||||
BODY_00_15(11, B, C, D, E, T, A, X(11));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(13) = l;
|
||||
BODY_00_15(12, A, B, C, D, E, T, X(12));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(14) = l;
|
||||
BODY_00_15(13, T, A, B, C, D, E, X(13));
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(15) = l;
|
||||
BODY_00_15(14, E, T, A, B, C, D, X(14));
|
||||
BODY_00_15(15, D, E, T, A, B, C, X(15));
|
||||
|
||||
+19
-21
@@ -44,21 +44,20 @@
|
||||
#include <new>
|
||||
|
||||
|
||||
/* This file defines overrides for the standard allocation functions that allow
|
||||
* a given allocation to be made to fail for testing. If the program is run
|
||||
* with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
|
||||
* return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
|
||||
* will signal SIGTRAP rather than return NULL.
|
||||
*
|
||||
* This code is not thread safe. */
|
||||
// This file defines overrides for the standard allocation functions that allow
|
||||
// a given allocation to be made to fail for testing. If the program is run
|
||||
// with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
|
||||
// return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
|
||||
// will signal SIGTRAP rather than return NULL.
|
||||
//
|
||||
// This code is not thread safe.
|
||||
|
||||
static uint64_t current_malloc_count = 0;
|
||||
static uint64_t malloc_number_to_fail = 0;
|
||||
static char failure_enabled = 0, break_on_fail = 0;
|
||||
static int in_call = 0;
|
||||
static bool failure_enabled = false, break_on_fail = false, in_call = false;
|
||||
|
||||
extern "C" {
|
||||
/* These are other names for the standard allocation functions. */
|
||||
// These are other names for the standard allocation functions.
|
||||
extern void *__libc_malloc(size_t size);
|
||||
extern void *__libc_calloc(size_t num_elems, size_t size);
|
||||
extern void *__libc_realloc(void *ptr, size_t size);
|
||||
@@ -75,16 +74,15 @@ static void cpp_new_handler() {
|
||||
return;
|
||||
}
|
||||
|
||||
/* should_fail_allocation returns true if the current allocation should fail. */
|
||||
static int should_fail_allocation() {
|
||||
static int init = 0;
|
||||
char should_fail;
|
||||
// should_fail_allocation returns true if the current allocation should fail.
|
||||
static bool should_fail_allocation() {
|
||||
static bool init = false;
|
||||
|
||||
if (in_call) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
in_call = 1;
|
||||
in_call = true;
|
||||
|
||||
if (!init) {
|
||||
const char *env = getenv("MALLOC_NUMBER_TO_FAIL");
|
||||
@@ -92,22 +90,22 @@ static int should_fail_allocation() {
|
||||
char *endptr;
|
||||
malloc_number_to_fail = strtoull(env, &endptr, 10);
|
||||
if (*endptr == 0) {
|
||||
failure_enabled = 1;
|
||||
failure_enabled = true;
|
||||
atexit(exit_handler);
|
||||
std::set_new_handler(cpp_new_handler);
|
||||
}
|
||||
}
|
||||
break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL"));
|
||||
init = 1;
|
||||
init = true;
|
||||
}
|
||||
|
||||
in_call = 0;
|
||||
in_call = false;
|
||||
|
||||
if (!failure_enabled) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
should_fail = (current_malloc_count == malloc_number_to_fail);
|
||||
bool should_fail = (current_malloc_count == malloc_number_to_fail);
|
||||
current_malloc_count++;
|
||||
|
||||
if (should_fail && break_on_fail) {
|
||||
|
||||
@@ -207,7 +207,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
|
||||
pkey = X509_get_pubkey(x);
|
||||
if (pkey == NULL) {
|
||||
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
|
||||
BIO_print_errors(bp);
|
||||
ERR_print_errors(bp);
|
||||
} else {
|
||||
EVP_PKEY_print_public(bp, pkey, 16, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
+566
-260
@@ -17,298 +17,375 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pool.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
namespace bssl {
|
||||
|
||||
static const char kCrossSigningRootPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICcTCCAdqgAwIBAgIIagJHiPvE0MowDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwo3qFvSB9Zmlbpzn9wJp\n"
|
||||
"ikI75Rxkatez8VkLqyxbOhPYl2Haz8F5p1gDG96dCI6jcLGgu3AKT9uhEQyyUko5\n"
|
||||
"EKYasazSeA9CQrdyhPg0mkTYVETnPM1W/ebid1YtqQbq1CMWlq2aTDoSGAReGFKP\n"
|
||||
"RTdXAbuAXzpCfi/d8LqV13UCAwEAAaN6MHgwDgYDVR0PAQH/BAQDAgIEMB0GA1Ud\n"
|
||||
"JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MBkGA1Ud\n"
|
||||
"DgQSBBBHKHC7V3Z/3oLvEZx0RZRwMBsGA1UdIwQUMBKAEEcocLtXdn/egu8RnHRF\n"
|
||||
"lHAwDQYJKoZIhvcNAQELBQADgYEAnglibsy6mGtpIXivtlcz4zIEnHw/lNW+r/eC\n"
|
||||
"CY7evZTmOoOuC/x9SS3MF9vawt1HFUummWM6ZgErqVBOXIB4//ykrcCgf5ZbF5Hr\n"
|
||||
"+3EFprKhBqYiXdD8hpBkrBoXwn85LPYWNd2TceCrx0YtLIprE2R5MB2RIq8y4Jk3\n"
|
||||
"YFXvkME=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICcTCCAdqgAwIBAgIIagJHiPvE0MowDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwo3qFvSB9Zmlbpzn9wJp\n"
|
||||
"ikI75Rxkatez8VkLqyxbOhPYl2Haz8F5p1gDG96dCI6jcLGgu3AKT9uhEQyyUko5\n"
|
||||
"EKYasazSeA9CQrdyhPg0mkTYVETnPM1W/ebid1YtqQbq1CMWlq2aTDoSGAReGFKP\n"
|
||||
"RTdXAbuAXzpCfi/d8LqV13UCAwEAAaN6MHgwDgYDVR0PAQH/BAQDAgIEMB0GA1Ud\n"
|
||||
"JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MBkGA1Ud\n"
|
||||
"DgQSBBBHKHC7V3Z/3oLvEZx0RZRwMBsGA1UdIwQUMBKAEEcocLtXdn/egu8RnHRF\n"
|
||||
"lHAwDQYJKoZIhvcNAQELBQADgYEAnglibsy6mGtpIXivtlcz4zIEnHw/lNW+r/eC\n"
|
||||
"CY7evZTmOoOuC/x9SS3MF9vawt1HFUummWM6ZgErqVBOXIB4//ykrcCgf5ZbF5Hr\n"
|
||||
"+3EFprKhBqYiXdD8hpBkrBoXwn85LPYWNd2TceCrx0YtLIprE2R5MB2RIq8y4Jk3\n"
|
||||
"YFXvkME=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kRootCAPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICVTCCAb6gAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwLjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwIBcNMTUwMTAx\n"
|
||||
"MDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMC4xGjAYBgNVBAoTEUJvcmluZ1NTTCBU\n"
|
||||
"RVNUSU5HMRAwDgYDVQQDEwdSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
|
||||
"iQKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/VImi2XeJM\n"
|
||||
"2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2m8PX+plZ\n"
|
||||
"w7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQABo3oweDAO\n"
|
||||
"BgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8G\n"
|
||||
"A1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEEA31wH7QC+4HH5UBCeMWQEwGwYDVR0j\n"
|
||||
"BBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOBgQDXylEK77Za\n"
|
||||
"kKeY6ZerrScWyZhrjIGtHFu09qVpdJEzrk87k2G7iHHR9CAvSofCgEExKtWNS9dN\n"
|
||||
"+9WiZp/U48iHLk7qaYXdEuO07No4BYtXn+lkOykE+FUxmA4wvOF1cTd2tdj3MzX2\n"
|
||||
"kfGIBAYhzGZWhY3JbhIfTEfY1PNM1pWChQ==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICVTCCAb6gAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwLjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwIBcNMTUwMTAx\n"
|
||||
"MDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMC4xGjAYBgNVBAoTEUJvcmluZ1NTTCBU\n"
|
||||
"RVNUSU5HMRAwDgYDVQQDEwdSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
|
||||
"iQKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/VImi2XeJM\n"
|
||||
"2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2m8PX+plZ\n"
|
||||
"w7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQABo3oweDAO\n"
|
||||
"BgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8G\n"
|
||||
"A1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEEA31wH7QC+4HH5UBCeMWQEwGwYDVR0j\n"
|
||||
"BBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOBgQDXylEK77Za\n"
|
||||
"kKeY6ZerrScWyZhrjIGtHFu09qVpdJEzrk87k2G7iHHR9CAvSofCgEExKtWNS9dN\n"
|
||||
"+9WiZp/U48iHLk7qaYXdEuO07No4BYtXn+lkOykE+FUxmA4wvOF1cTd2tdj3MzX2\n"
|
||||
"kfGIBAYhzGZWhY3JbhIfTEfY1PNM1pWChQ==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kRootCrossSignedPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICYzCCAcygAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowLjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwgZ8wDQYJKoZI\n"
|
||||
"hvcNAQEBBQADgY0AMIGJAoGBAOkOfxEM5lrmhoNw9lEHLgJ4EfWyJJI47iZiAseU\n"
|
||||
"8T6hd2rAj9UiaLZd4kza4IURNcKSckmNgbSIl2u3/LJEW9lNBnD5DMaP6bPfo2qE\n"
|
||||
"bENZvp2y0Habw9f6mVnDuOXzUwO9SdazzKJD/q3CC7kBuFYplAMkpw0oISmprpRb\n"
|
||||
"SvmfAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEFBQcD\n"
|
||||
"AQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQQDfXAftAL7gc\n"
|
||||
"flQEJ4xZATAbBgNVHSMEFDASgBBHKHC7V3Z/3oLvEZx0RZRwMA0GCSqGSIb3DQEB\n"
|
||||
"CwUAA4GBAErTxYJ0en9HVRHAAr5OO5wuk5Iq3VMc79TMyQLCXVL8YH8Uk7KEwv+q\n"
|
||||
"9MEKZv2eR/Vfm4HlXlUuIqfgUXbwrAYC/YVVX86Wnbpy/jc73NYVCq8FEZeO+0XU\n"
|
||||
"90SWAPDdp+iL7aZdimnMtG1qlM1edmz8AKbrhN/R3IbA2CL0nCWV\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICYzCCAcygAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxHjAcBgNVBAMTFUNyb3NzLXNpZ25pbmcgUm9v\n"
|
||||
"dCBDQTAgFw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowLjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxEDAOBgNVBAMTB1Jvb3QgQ0EwgZ8wDQYJKoZI\n"
|
||||
"hvcNAQEBBQADgY0AMIGJAoGBAOkOfxEM5lrmhoNw9lEHLgJ4EfWyJJI47iZiAseU\n"
|
||||
"8T6hd2rAj9UiaLZd4kza4IURNcKSckmNgbSIl2u3/LJEW9lNBnD5DMaP6bPfo2qE\n"
|
||||
"bENZvp2y0Habw9f6mVnDuOXzUwO9SdazzKJD/q3CC7kBuFYplAMkpw0oISmprpRb\n"
|
||||
"SvmfAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEFBQcD\n"
|
||||
"AQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQQDfXAftAL7gc\n"
|
||||
"flQEJ4xZATAbBgNVHSMEFDASgBBHKHC7V3Z/3oLvEZx0RZRwMA0GCSqGSIb3DQEB\n"
|
||||
"CwUAA4GBAErTxYJ0en9HVRHAAr5OO5wuk5Iq3VMc79TMyQLCXVL8YH8Uk7KEwv+q\n"
|
||||
"9MEKZv2eR/Vfm4HlXlUuIqfgUXbwrAYC/YVVX86Wnbpy/jc73NYVCq8FEZeO+0XU\n"
|
||||
"90SWAPDdp+iL7aZdimnMtG1qlM1edmz8AKbrhN/R3IbA2CL0nCWV\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kIntermediatePEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICXjCCAcegAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMC4xGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRAwDgYDVQQDEwdSb290IENBMCAXDTE1MDEw\n"
|
||||
"MTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjA2MRowGAYDVQQKExFCb3JpbmdTU0wg\n"
|
||||
"VEVTVElORzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEB\n"
|
||||
"AQUAA4GNADCBiQKBgQC7YtI0l8ocTYJ0gKyXTtPL4iMJCNY4OcxXl48jkncVG1Hl\n"
|
||||
"blicgNUa1r9m9YFtVkxvBinb8dXiUpEGhVg4awRPDcatlsBSEBuJkiZGYbRcAmSu\n"
|
||||
"CmZYnf6u3aYQ18SU8WqVERPpE4cwVVs+6kwlzRw0+XDoZAczu8ZezVhCUc6NbQID\n"
|
||||
"AQABo3oweDAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n"
|
||||
"AQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEIwaaKi1dttdV3sfjRSy\n"
|
||||
"BqMwGwYDVR0jBBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOB\n"
|
||||
"gQCvnolNWEHuQS8PFVVyuLR+FKBeUUdrVbSfHSzTqNAqQGp0C9fk5oCzDq6ZgTfY\n"
|
||||
"ESXM4cJhb3IAnW0UM0NFsYSKQJ50JZL2L3z5ZLQhHdbs4RmODGoC40BVdnJ4/qgB\n"
|
||||
"aGSh09eQRvAVmbVCviDK2ipkWNegdyI19jFfNP5uIkGlYg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICXjCCAcegAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMC4xGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRAwDgYDVQQDEwdSb290IENBMCAXDTE1MDEw\n"
|
||||
"MTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjA2MRowGAYDVQQKExFCb3JpbmdTU0wg\n"
|
||||
"VEVTVElORzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMIGfMA0GCSqGSIb3DQEB\n"
|
||||
"AQUAA4GNADCBiQKBgQC7YtI0l8ocTYJ0gKyXTtPL4iMJCNY4OcxXl48jkncVG1Hl\n"
|
||||
"blicgNUa1r9m9YFtVkxvBinb8dXiUpEGhVg4awRPDcatlsBSEBuJkiZGYbRcAmSu\n"
|
||||
"CmZYnf6u3aYQ18SU8WqVERPpE4cwVVs+6kwlzRw0+XDoZAczu8ZezVhCUc6NbQID\n"
|
||||
"AQABo3oweDAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n"
|
||||
"AQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEEIwaaKi1dttdV3sfjRSy\n"
|
||||
"BqMwGwYDVR0jBBQwEoAQQDfXAftAL7gcflQEJ4xZATANBgkqhkiG9w0BAQsFAAOB\n"
|
||||
"gQCvnolNWEHuQS8PFVVyuLR+FKBeUUdrVbSfHSzTqNAqQGp0C9fk5oCzDq6ZgTfY\n"
|
||||
"ESXM4cJhb3IAnW0UM0NFsYSKQJ50JZL2L3z5ZLQhHdbs4RmODGoC40BVdnJ4/qgB\n"
|
||||
"aGSh09eQRvAVmbVCviDK2ipkWNegdyI19jFfNP5uIkGlYg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kIntermediateSelfSignedPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICZjCCAc+gAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDYxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwgZ8wDQYJ\n"
|
||||
"KoZIhvcNAQEBBQADgY0AMIGJAoGBALti0jSXyhxNgnSArJdO08viIwkI1jg5zFeX\n"
|
||||
"jyOSdxUbUeVuWJyA1RrWv2b1gW1WTG8GKdvx1eJSkQaFWDhrBE8Nxq2WwFIQG4mS\n"
|
||||
"JkZhtFwCZK4KZlid/q7dphDXxJTxapURE+kThzBVWz7qTCXNHDT5cOhkBzO7xl7N\n"
|
||||
"WEJRzo1tAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEF\n"
|
||||
"BQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQjBpoqLV2\n"
|
||||
"211Xex+NFLIGozAbBgNVHSMEFDASgBCMGmiotXbbXVd7H40UsgajMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4GBALcccSrAQ0/EqQBsx0ZDTUydHXXNP2DrUkpUKmAXIe8McqIVSlkT\n"
|
||||
"6H4xz7z8VRKBo9j+drjjtCw2i0CQc8aOLxRb5WJ8eVLnaW2XRlUqAzhF0CrulfVI\n"
|
||||
"E4Vs6ZLU+fra1WAuIj6qFiigRja+3YkZArG8tMA9vtlhTX/g7YBZIkqH\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICZjCCAc+gAwIBAgIJAKJMH+7rscPcMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDYxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwgZ8wDQYJ\n"
|
||||
"KoZIhvcNAQEBBQADgY0AMIGJAoGBALti0jSXyhxNgnSArJdO08viIwkI1jg5zFeX\n"
|
||||
"jyOSdxUbUeVuWJyA1RrWv2b1gW1WTG8GKdvx1eJSkQaFWDhrBE8Nxq2WwFIQG4mS\n"
|
||||
"JkZhtFwCZK4KZlid/q7dphDXxJTxapURE+kThzBVWz7qTCXNHDT5cOhkBzO7xl7N\n"
|
||||
"WEJRzo1tAgMBAAGjejB4MA4GA1UdDwEB/wQEAwICBDAdBgNVHSUEFjAUBggrBgEF\n"
|
||||
"BQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQjBpoqLV2\n"
|
||||
"211Xex+NFLIGozAbBgNVHSMEFDASgBCMGmiotXbbXVd7H40UsgajMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4GBALcccSrAQ0/EqQBsx0ZDTUydHXXNP2DrUkpUKmAXIe8McqIVSlkT\n"
|
||||
"6H4xz7z8VRKBo9j+drjjtCw2i0CQc8aOLxRb5WJ8eVLnaW2XRlUqAzhF0CrulfVI\n"
|
||||
"E4Vs6ZLU+fra1WAuIj6qFiigRja+3YkZArG8tMA9vtlhTX/g7YBZIkqH\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kLeafPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg\n"
|
||||
"Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y\n"
|
||||
"aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3\n"
|
||||
"DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c\n"
|
||||
"oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j\n"
|
||||
"5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh\n"
|
||||
"TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG\n"
|
||||
"CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0\n"
|
||||
"4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB\n"
|
||||
"gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y\n"
|
||||
"rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU\n"
|
||||
"xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg\n"
|
||||
"Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y\n"
|
||||
"aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3\n"
|
||||
"DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c\n"
|
||||
"oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j\n"
|
||||
"5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh\n"
|
||||
"TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG\n"
|
||||
"CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0\n"
|
||||
"4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB\n"
|
||||
"gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y\n"
|
||||
"rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU\n"
|
||||
"xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kLeafNoKeyUsagePEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICNTCCAZ6gAwIBAgIJAIFQGaLQ0G2mMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDcxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRkwFwYDVQQDExBldmlsLmV4YW1wbGUuY29tMIGfMA0G\n"
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOKoZe75NPz77EOaMMl4/0s3PyQw++zJvp\n"
|
||||
"ejHAxZiTPCJgMbEHLrSzNoHdopg+CLUH5bE4wTXM8w9Inv5P8OAFJt7gJuPUunmk\n"
|
||||
"j+NoU3QfzOR6BroePcz1vXX9jyVHRs087M/sLqWRHu9IR+/A+UTcBaWaFiDVUxtJ\n"
|
||||
"YOwFMwjNPQIDAQABo0gwRjAMBgNVHRMBAf8EAjAAMBkGA1UdDgQSBBBJfLEUWHq1\n"
|
||||
"27rZ1AVx2J5GMBsGA1UdIwQUMBKAEIwaaKi1dttdV3sfjRSyBqMwDQYJKoZIhvcN\n"
|
||||
"AQELBQADgYEALVKN2Y3LZJOtu6SxFIYKxbLaXhTGTdIjxipZhmbBRDFjbZjZZOTe\n"
|
||||
"6Oo+VDNPYco4rBexK7umYXJyfTqoY0E8dbiImhTcGTEj7OAB3DbBomgU1AYe+t2D\n"
|
||||
"uwBqh4Y3Eto+Zn4pMVsxGEfUpjzjZDel7bN1/oU/9KWPpDfywfUmjgk=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICNTCCAZ6gAwIBAgIJAIFQGaLQ0G2mMA0GCSqGSIb3DQEBCwUAMDYxGjAYBgNV\n"
|
||||
"BAoTEUJvcmluZ1NTTCBURVNUSU5HMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0Ew\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDcxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRkwFwYDVQQDExBldmlsLmV4YW1wbGUuY29tMIGfMA0G\n"
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOKoZe75NPz77EOaMMl4/0s3PyQw++zJvp\n"
|
||||
"ejHAxZiTPCJgMbEHLrSzNoHdopg+CLUH5bE4wTXM8w9Inv5P8OAFJt7gJuPUunmk\n"
|
||||
"j+NoU3QfzOR6BroePcz1vXX9jyVHRs087M/sLqWRHu9IR+/A+UTcBaWaFiDVUxtJ\n"
|
||||
"YOwFMwjNPQIDAQABo0gwRjAMBgNVHRMBAf8EAjAAMBkGA1UdDgQSBBBJfLEUWHq1\n"
|
||||
"27rZ1AVx2J5GMBsGA1UdIwQUMBKAEIwaaKi1dttdV3sfjRSyBqMwDQYJKoZIhvcN\n"
|
||||
"AQELBQADgYEALVKN2Y3LZJOtu6SxFIYKxbLaXhTGTdIjxipZhmbBRDFjbZjZZOTe\n"
|
||||
"6Oo+VDNPYco4rBexK7umYXJyfTqoY0E8dbiImhTcGTEj7OAB3DbBomgU1AYe+t2D\n"
|
||||
"uwBqh4Y3Eto+Zn4pMVsxGEfUpjzjZDel7bN1/oU/9KWPpDfywfUmjgk=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kForgeryPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICZzCCAdCgAwIBAgIIdTlMzQoKkeMwDQYJKoZIhvcNAQELBQAwNzEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGTAXBgNVBAMTEGV2aWwuZXhhbXBsZS5jb20w\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDoxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRwwGgYDVQQDExNmb3JnZXJ5LmV4YW1wbGUuY29tMIGf\n"
|
||||
"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADTwruBQZGb7Ay6s9HiYv5d1lwtEy\n"
|
||||
"xQdA2Sy8Rn8uA20Q4KgqwVY7wzIZ+z5Butrsmwb70gdG1XU+yRaDeE7XVoW6jSpm\n"
|
||||
"0sw35/5vJbTcL4THEFbnX0OPZnvpuZDFUkvVtq5kxpDWsVyM24G8EEq7kPih3Sa3\n"
|
||||
"OMhXVXF8kso6UQIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI\n"
|
||||
"KwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEEYJ/WHM\n"
|
||||
"8p64erPWIg4/liwwGwYDVR0jBBQwEoAQSXyxFFh6tdu62dQFcdieRjANBgkqhkiG\n"
|
||||
"9w0BAQsFAAOBgQA+zH7bHPElWRWJvjxDqRexmYLn+D3Aivs8XgXQJsM94W0EzSUf\n"
|
||||
"DSLfRgaQwcb2gg2xpDFoG+W0vc6O651uF23WGt5JaFFJJxqjII05IexfCNhuPmp4\n"
|
||||
"4UZAXPttuJXpn74IY1tuouaM06B3vXKZR+/ityKmfJvSwxacmFcK+2ziAg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICZzCCAdCgAwIBAgIIdTlMzQoKkeMwDQYJKoZIhvcNAQELBQAwNzEaMBgGA1UE\n"
|
||||
"ChMRQm9yaW5nU1NMIFRFU1RJTkcxGTAXBgNVBAMTEGV2aWwuZXhhbXBsZS5jb20w\n"
|
||||
"IBcNMTUwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMDoxGjAYBgNVBAoTEUJv\n"
|
||||
"cmluZ1NTTCBURVNUSU5HMRwwGgYDVQQDExNmb3JnZXJ5LmV4YW1wbGUuY29tMIGf\n"
|
||||
"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADTwruBQZGb7Ay6s9HiYv5d1lwtEy\n"
|
||||
"xQdA2Sy8Rn8uA20Q4KgqwVY7wzIZ+z5Butrsmwb70gdG1XU+yRaDeE7XVoW6jSpm\n"
|
||||
"0sw35/5vJbTcL4THEFbnX0OPZnvpuZDFUkvVtq5kxpDWsVyM24G8EEq7kPih3Sa3\n"
|
||||
"OMhXVXF8kso6UQIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI\n"
|
||||
"KwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEEYJ/WHM\n"
|
||||
"8p64erPWIg4/liwwGwYDVR0jBBQwEoAQSXyxFFh6tdu62dQFcdieRjANBgkqhkiG\n"
|
||||
"9w0BAQsFAAOBgQA+zH7bHPElWRWJvjxDqRexmYLn+D3Aivs8XgXQJsM94W0EzSUf\n"
|
||||
"DSLfRgaQwcb2gg2xpDFoG+W0vc6O651uF23WGt5JaFFJJxqjII05IexfCNhuPmp4\n"
|
||||
"4UZAXPttuJXpn74IY1tuouaM06B3vXKZR+/ityKmfJvSwxacmFcK+2ziAg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kExamplePSSCert is an example RSA-PSS self-signed certificate, signed with
|
||||
// the default hash functions.
|
||||
static const char kExamplePSSCert[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICYjCCAcagAwIBAgIJAI3qUyT6SIfzMBIGCSqGSIb3DQEBCjAFogMCAWowRTEL\n"
|
||||
"MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy\n"
|
||||
"bmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDEwMDkxOTA5NTVaFw0xNTEwMDkxOTA5\n"
|
||||
"NTVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK\n"
|
||||
"DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A\n"
|
||||
"MIGJAoGBAPi4bIO0vNmoV8CltFl2jFQdeesiUgR+0zfrQf2D+fCmhRU0dXFahKg8\n"
|
||||
"0u9aTtPel4rd/7vPCqqGkr64UOTNb4AzMHYTj8p73OxaymPHAyXvqIqDWHYg+hZ3\n"
|
||||
"13mSYwFIGth7Z/FSVUlO1m5KXNd6NzYM3t2PROjCpywrta9kS2EHAgMBAAGjUDBO\n"
|
||||
"MB0GA1UdDgQWBBTQQfuJQR6nrVrsNF1JEflVgXgfEzAfBgNVHSMEGDAWgBTQQfuJ\n"
|
||||
"QR6nrVrsNF1JEflVgXgfEzAMBgNVHRMEBTADAQH/MBIGCSqGSIb3DQEBCjAFogMC\n"
|
||||
"AWoDgYEASUy2RZcgNbNQZA0/7F+V1YTLEXwD16bm+iSVnzGwtexmQVEYIZG74K/w\n"
|
||||
"xbdZQdTbpNJkp1QPjPfh0zsatw6dmt5QoZ8K8No0DjR9dgf+Wvv5WJvJUIQBoAVN\n"
|
||||
"Z0IL+OQFz6+LcTHxD27JJCebrATXZA0wThGTQDm7crL+a+SujBY=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICYjCCAcagAwIBAgIJAI3qUyT6SIfzMBIGCSqGSIb3DQEBCjAFogMCAWowRTEL\n"
|
||||
"MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy\n"
|
||||
"bmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDEwMDkxOTA5NTVaFw0xNTEwMDkxOTA5\n"
|
||||
"NTVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK\n"
|
||||
"DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A\n"
|
||||
"MIGJAoGBAPi4bIO0vNmoV8CltFl2jFQdeesiUgR+0zfrQf2D+fCmhRU0dXFahKg8\n"
|
||||
"0u9aTtPel4rd/7vPCqqGkr64UOTNb4AzMHYTj8p73OxaymPHAyXvqIqDWHYg+hZ3\n"
|
||||
"13mSYwFIGth7Z/FSVUlO1m5KXNd6NzYM3t2PROjCpywrta9kS2EHAgMBAAGjUDBO\n"
|
||||
"MB0GA1UdDgQWBBTQQfuJQR6nrVrsNF1JEflVgXgfEzAfBgNVHSMEGDAWgBTQQfuJ\n"
|
||||
"QR6nrVrsNF1JEflVgXgfEzAMBgNVHRMEBTADAQH/MBIGCSqGSIb3DQEBCjAFogMC\n"
|
||||
"AWoDgYEASUy2RZcgNbNQZA0/7F+V1YTLEXwD16bm+iSVnzGwtexmQVEYIZG74K/w\n"
|
||||
"xbdZQdTbpNJkp1QPjPfh0zsatw6dmt5QoZ8K8No0DjR9dgf+Wvv5WJvJUIQBoAVN\n"
|
||||
"Z0IL+OQFz6+LcTHxD27JJCebrATXZA0wThGTQDm7crL+a+SujBY=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kBadPSSCertPEM is a self-signed RSA-PSS certificate with bad parameters.
|
||||
static const char kBadPSSCertPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdjCCAjqgAwIBAgIJANcwZLyfEv7DMD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n"
|
||||
"AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3jAnMSUwIwYD\n"
|
||||
"VQQDDBxUZXN0IEludmFsaWQgUFNTIGNlcnRpZmljYXRlMB4XDTE1MTEwNDE2MDIz\n"
|
||||
"NVoXDTE1MTIwNDE2MDIzNVowJzElMCMGA1UEAwwcVGVzdCBJbnZhbGlkIFBTUyBj\n"
|
||||
"ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMTaM7WH\n"
|
||||
"qVCAGAIA+zL1KWvvASTrhlq+1ePdO7wsrWX2KiYoTYrJYTnxhLnn0wrHqApt79nL\n"
|
||||
"IBG7cfShyZqFHOY/IzlYPMVt+gPo293gw96Fds5JBsjhjkyGnOyr9OUntFqvxDbT\n"
|
||||
"IIFU7o9IdxD4edaqjRv+fegVE+B79pDk4s0ujsk6dULtCg9Rst0ucGFo19mr+b7k\n"
|
||||
"dbfn8pZ72ZNDJPueVdrUAWw9oll61UcYfk75XdrLk6JlL41GrYHc8KlfXf43gGQq\n"
|
||||
"QfrpHkg4Ih2cI6Wt2nhFGAzrlcorzLliQIUJRIhM8h4IgDfpBpaPdVQLqS2pFbXa\n"
|
||||
"5eQjqiyJwak2vJ8CAwEAAaNQME4wHQYDVR0OBBYEFCt180N4oGUt5LbzBwQ4Ia+2\n"
|
||||
"4V97MB8GA1UdIwQYMBaAFCt180N4oGUt5LbzBwQ4Ia+24V97MAwGA1UdEwQFMAMB\n"
|
||||
"Af8wMQYJKoZIhvcNAQEKMCSgDTALBglghkgBZQMEAgGhDTALBgkqhkiG9w0BAQii\n"
|
||||
"BAICAN4DggEBAAjBtm90lGxgddjc4Xu/nbXXFHVs2zVcHv/mqOZoQkGB9r/BVgLb\n"
|
||||
"xhHrFZ2pHGElbUYPfifdS9ztB73e1d4J+P29o0yBqfd4/wGAc/JA8qgn6AAEO/Xn\n"
|
||||
"plhFeTRJQtLZVl75CkHXgUGUd3h+ADvKtcBuW9dSUncaUrgNKR8u/h/2sMG38RWY\n"
|
||||
"DzBddC/66YTa3r7KkVUfW7yqRQfELiGKdcm+bjlTEMsvS+EhHup9CzbpoCx2Fx9p\n"
|
||||
"NPtFY3yEObQhmL1JyoCRWqBE75GzFPbRaiux5UpEkns+i3trkGssZzsOuVqHNTNZ\n"
|
||||
"lC9+9hPHIoc9UMmAQNo1vGIW3NWVoeGbaJ8=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdjCCAjqgAwIBAgIJANcwZLyfEv7DMD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI\n"
|
||||
"AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3jAnMSUwIwYD\n"
|
||||
"VQQDDBxUZXN0IEludmFsaWQgUFNTIGNlcnRpZmljYXRlMB4XDTE1MTEwNDE2MDIz\n"
|
||||
"NVoXDTE1MTIwNDE2MDIzNVowJzElMCMGA1UEAwwcVGVzdCBJbnZhbGlkIFBTUyBj\n"
|
||||
"ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMTaM7WH\n"
|
||||
"qVCAGAIA+zL1KWvvASTrhlq+1ePdO7wsrWX2KiYoTYrJYTnxhLnn0wrHqApt79nL\n"
|
||||
"IBG7cfShyZqFHOY/IzlYPMVt+gPo293gw96Fds5JBsjhjkyGnOyr9OUntFqvxDbT\n"
|
||||
"IIFU7o9IdxD4edaqjRv+fegVE+B79pDk4s0ujsk6dULtCg9Rst0ucGFo19mr+b7k\n"
|
||||
"dbfn8pZ72ZNDJPueVdrUAWw9oll61UcYfk75XdrLk6JlL41GrYHc8KlfXf43gGQq\n"
|
||||
"QfrpHkg4Ih2cI6Wt2nhFGAzrlcorzLliQIUJRIhM8h4IgDfpBpaPdVQLqS2pFbXa\n"
|
||||
"5eQjqiyJwak2vJ8CAwEAAaNQME4wHQYDVR0OBBYEFCt180N4oGUt5LbzBwQ4Ia+2\n"
|
||||
"4V97MB8GA1UdIwQYMBaAFCt180N4oGUt5LbzBwQ4Ia+24V97MAwGA1UdEwQFMAMB\n"
|
||||
"Af8wMQYJKoZIhvcNAQEKMCSgDTALBglghkgBZQMEAgGhDTALBgkqhkiG9w0BAQii\n"
|
||||
"BAICAN4DggEBAAjBtm90lGxgddjc4Xu/nbXXFHVs2zVcHv/mqOZoQkGB9r/BVgLb\n"
|
||||
"xhHrFZ2pHGElbUYPfifdS9ztB73e1d4J+P29o0yBqfd4/wGAc/JA8qgn6AAEO/Xn\n"
|
||||
"plhFeTRJQtLZVl75CkHXgUGUd3h+ADvKtcBuW9dSUncaUrgNKR8u/h/2sMG38RWY\n"
|
||||
"DzBddC/66YTa3r7KkVUfW7yqRQfELiGKdcm+bjlTEMsvS+EhHup9CzbpoCx2Fx9p\n"
|
||||
"NPtFY3yEObQhmL1JyoCRWqBE75GzFPbRaiux5UpEkns+i3trkGssZzsOuVqHNTNZ\n"
|
||||
"lC9+9hPHIoc9UMmAQNo1vGIW3NWVoeGbaJ8=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kRSAKey[] =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
|
||||
"kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
|
||||
"KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
|
||||
"AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
|
||||
"i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
|
||||
"WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
|
||||
"m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
|
||||
"QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
|
||||
"aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
|
||||
"LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
|
||||
"104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
|
||||
"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
|
||||
"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
|
||||
"kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
|
||||
"KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
|
||||
"AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
|
||||
"i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
|
||||
"WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
|
||||
"m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
|
||||
"QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
|
||||
"aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
|
||||
"LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
|
||||
"104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
|
||||
"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
|
||||
"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
// kCRLTestRoot is a test root certificate. It has private key:
|
||||
//
|
||||
// -----BEGIN RSA PRIVATE KEY-----
|
||||
// MIIEpAIBAAKCAQEAo16WiLWZuaymsD8n5SKPmxV1y6jjgr3BS/dUBpbrzd1aeFzN
|
||||
// lI8l2jfAnzUyp+I21RQ+nh/MhqjGElkTtK9xMn1Y+S9GMRh+5R/Du0iCb1tCZIPY
|
||||
// 07Tgrb0KMNWe0v2QKVVruuYSgxIWodBfxlKO64Z8AJ5IbnWpuRqO6rctN9qUoMlT
|
||||
// IAB6dL4G0tDJ/PGFWOJYwOMEIX54bly2wgyYJVBKiRRt4f7n8H922qmvPNA9idmX
|
||||
// 9G1VAtgV6x97XXi7ULORIQvn9lVQF6nTYDBJhyuPB+mLThbLP2o9orxGx7aCtnnB
|
||||
// ZUIxUvHNOI0FaSaZH7Fi0xsZ/GkG2HZe7ImPJwIDAQABAoIBAQCJF9MTHfHGkk+/
|
||||
// DwCXlA0Wg0e6hBuHl10iNobYkMWIl/xXjOknhYiqOqb181py76472SVC5ERprC+r
|
||||
// Lf0PXzqKuA117mnkwT2bYLCL9Skf8WEhoFLQNbVlloF6wYjqXcYgKYKh8HgQbZl4
|
||||
// aLg2YQl2NADTNABsUWj/4H2WEelsODVviqfFs725lFg9KHDI8zxAZXLzDt/M9uVL
|
||||
// GxJiX12tr0AwaeAFZ1oPM/y+LznM3N3+Ht3jHHw3jZ/u8Z1RdAmdpu3bZ6tbwGBr
|
||||
// 9edsH5rKkm9aBvMrY7eX5VHqaqyRNFyG152ZOJh4XiiFG7EmgTPCpaHo50Y018Re
|
||||
// grVtk+FBAoGBANY3lY+V8ZOwMxSHes+kTnoimHO5Ob7nxrOC71i27x+4HHsYUeAr
|
||||
// /zOOghiDIn+oNkuiX5CIOWZKx159Bp65CPpCbTb/fh+HYnSgXFgCw7XptycO7LXM
|
||||
// 5GwR5jSfpfzBFdYxjxoUzDMFBwTEYRTm0HkUHkH+s+ajjw5wqqbcGLcfAoGBAMM8
|
||||
// DKW6Tb66xsf708f0jonAjKYTLZ+WOcwsBEWSFHoY8dUjvW5gqx5acHTEsc5ZTeh4
|
||||
// BCFLa+Mn9cuJWVJNs09k7Xb2PNl92HQ4GN2vbdkJhExbkT6oLDHg1hVD0w8KLfz1
|
||||
// lTAW6pS+6CdOHMEJpvqx89EgU/1GgIQ1fXYczE75AoGAKeJoXdDFkUjsU+FBhAPu
|
||||
// TDcjc80Nm2QaF9NMFR5/lsYa236f06MGnQAKM9zADBHJu/Qdl1brUjLg1HrBppsr
|
||||
// RDNkw1IlSOjhuUf5hkPUHGd8Jijm440SRIcjabqla8wdBupdvo2+d2NOQgJbsQiI
|
||||
// ToQ+fkzcxAXK3Nnuo/1436UCgYBjLH7UNOZHS8OsVM0I1r8NVKVdu4JCfeJQR8/H
|
||||
// s2P5ffBir+wLRMnH+nMDreMQiibcPxMCArkERAlE4jlgaJ38Z62E76KLbLTmnJRt
|
||||
// EC9Bv+bXjvAiHvWMRMUbOj/ddPNVez7Uld+FvdBaHwDWQlvzHzBWfBCOKSEhh7Z6
|
||||
// qDhUqQKBgQDPMDx2i5rfmQp3imV9xUcCkIRsyYQVf8Eo7NV07IdUy/otmksgn4Zt
|
||||
// Lbf3v2dvxOpTNTONWjp2c+iUQo8QxJCZr5Sfb21oQ9Ktcrmc/CY7LeBVDibXwxdM
|
||||
// vRG8kBzvslFWh7REzC3u06GSVhyKDfW93kN2cKVwGoahRlhj7oHuZQ==
|
||||
// -----END RSA PRIVATE KEY-----
|
||||
static const char kCRLTestRoot[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDbzCCAlegAwIBAgIJAODri7v0dDUFMA0GCSqGSIb3DQEBCwUAME4xCzAJBgNV\n"
|
||||
"BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW\n"
|
||||
"aWV3MRIwEAYDVQQKDAlCb3JpbmdTU0wwHhcNMTYwOTI2MTUwNjI2WhcNMjYwOTI0\n"
|
||||
"MTUwNjI2WjBOMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\n"
|
||||
"A1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJQm9yaW5nU1NMMIIBIjANBgkq\n"
|
||||
"hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo16WiLWZuaymsD8n5SKPmxV1y6jjgr3B\n"
|
||||
"S/dUBpbrzd1aeFzNlI8l2jfAnzUyp+I21RQ+nh/MhqjGElkTtK9xMn1Y+S9GMRh+\n"
|
||||
"5R/Du0iCb1tCZIPY07Tgrb0KMNWe0v2QKVVruuYSgxIWodBfxlKO64Z8AJ5IbnWp\n"
|
||||
"uRqO6rctN9qUoMlTIAB6dL4G0tDJ/PGFWOJYwOMEIX54bly2wgyYJVBKiRRt4f7n\n"
|
||||
"8H922qmvPNA9idmX9G1VAtgV6x97XXi7ULORIQvn9lVQF6nTYDBJhyuPB+mLThbL\n"
|
||||
"P2o9orxGx7aCtnnBZUIxUvHNOI0FaSaZH7Fi0xsZ/GkG2HZe7ImPJwIDAQABo1Aw\n"
|
||||
"TjAdBgNVHQ4EFgQUWPt3N5cZ/CRvubbrkqfBnAqhq94wHwYDVR0jBBgwFoAUWPt3\n"
|
||||
"N5cZ/CRvubbrkqfBnAqhq94wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
|
||||
"AQEAORu6M0MOwXy+3VEBwNilfTxyqDfruQsc1jA4PT8Oe8zora1WxE1JB4q2FJOz\n"
|
||||
"EAuM3H/NXvEnBuN+ITvKZAJUfm4NKX97qmjMJwLKWe1gVv+VQTr63aR7mgWJReQN\n"
|
||||
"XdMztlVeZs2dppV6uEg3ia1X0G7LARxGpA9ETbMyCpb39XxlYuTClcbA5ftDN99B\n"
|
||||
"3Xg9KNdd++Ew22O3HWRDvdDpTO/JkzQfzi3sYwUtzMEonENhczJhGf7bQMmvL/w5\n"
|
||||
"24Wxj4Z7KzzWIHsNqE/RIs6RV3fcW61j/mRgW2XyoWnMVeBzvcJr9NXp4VQYmFPw\n"
|
||||
"amd8GKMZQvP0ufGnUn7D7uartA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDbzCCAlegAwIBAgIJAODri7v0dDUFMA0GCSqGSIb3DQEBCwUAME4xCzAJBgNV\n"
|
||||
"BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW\n"
|
||||
"aWV3MRIwEAYDVQQKDAlCb3JpbmdTU0wwHhcNMTYwOTI2MTUwNjI2WhcNMjYwOTI0\n"
|
||||
"MTUwNjI2WjBOMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\n"
|
||||
"A1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJQm9yaW5nU1NMMIIBIjANBgkq\n"
|
||||
"hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo16WiLWZuaymsD8n5SKPmxV1y6jjgr3B\n"
|
||||
"S/dUBpbrzd1aeFzNlI8l2jfAnzUyp+I21RQ+nh/MhqjGElkTtK9xMn1Y+S9GMRh+\n"
|
||||
"5R/Du0iCb1tCZIPY07Tgrb0KMNWe0v2QKVVruuYSgxIWodBfxlKO64Z8AJ5IbnWp\n"
|
||||
"uRqO6rctN9qUoMlTIAB6dL4G0tDJ/PGFWOJYwOMEIX54bly2wgyYJVBKiRRt4f7n\n"
|
||||
"8H922qmvPNA9idmX9G1VAtgV6x97XXi7ULORIQvn9lVQF6nTYDBJhyuPB+mLThbL\n"
|
||||
"P2o9orxGx7aCtnnBZUIxUvHNOI0FaSaZH7Fi0xsZ/GkG2HZe7ImPJwIDAQABo1Aw\n"
|
||||
"TjAdBgNVHQ4EFgQUWPt3N5cZ/CRvubbrkqfBnAqhq94wHwYDVR0jBBgwFoAUWPt3\n"
|
||||
"N5cZ/CRvubbrkqfBnAqhq94wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
|
||||
"AQEAORu6M0MOwXy+3VEBwNilfTxyqDfruQsc1jA4PT8Oe8zora1WxE1JB4q2FJOz\n"
|
||||
"EAuM3H/NXvEnBuN+ITvKZAJUfm4NKX97qmjMJwLKWe1gVv+VQTr63aR7mgWJReQN\n"
|
||||
"XdMztlVeZs2dppV6uEg3ia1X0G7LARxGpA9ETbMyCpb39XxlYuTClcbA5ftDN99B\n"
|
||||
"3Xg9KNdd++Ew22O3HWRDvdDpTO/JkzQfzi3sYwUtzMEonENhczJhGf7bQMmvL/w5\n"
|
||||
"24Wxj4Z7KzzWIHsNqE/RIs6RV3fcW61j/mRgW2XyoWnMVeBzvcJr9NXp4VQYmFPw\n"
|
||||
"amd8GKMZQvP0ufGnUn7D7uartA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kCRLTestLeaf[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDkDCCAnigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UEBhMCVVMx\n"
|
||||
"EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEjAQ\n"
|
||||
"BgNVBAoMCUJvcmluZ1NTTDAeFw0xNjA5MjYxNTA4MzFaFw0xNzA5MjYxNTA4MzFa\n"
|
||||
"MEsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQKDAlC\n"
|
||||
"b3JpbmdTU0wxEzARBgNVBAMMCmJvcmluZy5zc2wwggEiMA0GCSqGSIb3DQEBAQUA\n"
|
||||
"A4IBDwAwggEKAoIBAQDc5v1S1M0W+QWM+raWfO0LH8uvqEwuJQgODqMaGnSlWUx9\n"
|
||||
"8iQcnWfjyPja3lWg9K62hSOFDuSyEkysKHDxijz5R93CfLcfnVXjWQDJe7EJTTDP\n"
|
||||
"ozEvxN6RjAeYv7CF000euYr3QT5iyBjg76+bon1p0jHZBJeNPP1KqGYgyxp+hzpx\n"
|
||||
"e0gZmTlGAXd8JQK4v8kpdYwD6PPifFL/jpmQpqOtQmH/6zcLjY4ojmqpEdBqIKIX\n"
|
||||
"+saA29hMq0+NK3K+wgg31RU+cVWxu3tLOIiesETkeDgArjWRS1Vkzbi4v9SJxtNu\n"
|
||||
"OZuAxWiynRJw3JwH/OFHYZIvQqz68ZBoj96cepjPAgMBAAGjezB5MAkGA1UdEwQC\n"
|
||||
"MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl\n"
|
||||
"MB0GA1UdDgQWBBTGn0OVVh/aoYt0bvEKG+PIERqnDzAfBgNVHSMEGDAWgBRY+3c3\n"
|
||||
"lxn8JG+5tuuSp8GcCqGr3jANBgkqhkiG9w0BAQsFAAOCAQEAd2nM8gCQN2Dc8QJw\n"
|
||||
"XSZXyuI3DBGGCHcay/3iXu0JvTC3EiQo8J6Djv7WLI0N5KH8mkm40u89fJAB2lLZ\n"
|
||||
"ShuHVtcC182bOKnePgwp9CNwQ21p0rDEu/P3X46ZvFgdxx82E9xLa0tBB8PiPDWh\n"
|
||||
"lV16jbaKTgX5AZqjnsyjR5o9/mbZVupZJXx5Syq+XA8qiJfstSYJs4KyKK9UOjql\n"
|
||||
"ICkJVKpi2ahDBqX4MOH4SLfzVk8pqSpviS6yaA1RXqjpkxiN45WWaXDldVHMSkhC\n"
|
||||
"5CNXsXi4b1nAntu89crwSLA3rEwzCWeYj+BX7e1T9rr3oJdwOU/2KQtW1js1yQUG\n"
|
||||
"tjJMFw==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDkDCCAnigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UEBhMCVVMx\n"
|
||||
"EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEjAQ\n"
|
||||
"BgNVBAoMCUJvcmluZ1NTTDAeFw0xNjA5MjYxNTA4MzFaFw0xNzA5MjYxNTA4MzFa\n"
|
||||
"MEsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQKDAlC\n"
|
||||
"b3JpbmdTU0wxEzARBgNVBAMMCmJvcmluZy5zc2wwggEiMA0GCSqGSIb3DQEBAQUA\n"
|
||||
"A4IBDwAwggEKAoIBAQDc5v1S1M0W+QWM+raWfO0LH8uvqEwuJQgODqMaGnSlWUx9\n"
|
||||
"8iQcnWfjyPja3lWg9K62hSOFDuSyEkysKHDxijz5R93CfLcfnVXjWQDJe7EJTTDP\n"
|
||||
"ozEvxN6RjAeYv7CF000euYr3QT5iyBjg76+bon1p0jHZBJeNPP1KqGYgyxp+hzpx\n"
|
||||
"e0gZmTlGAXd8JQK4v8kpdYwD6PPifFL/jpmQpqOtQmH/6zcLjY4ojmqpEdBqIKIX\n"
|
||||
"+saA29hMq0+NK3K+wgg31RU+cVWxu3tLOIiesETkeDgArjWRS1Vkzbi4v9SJxtNu\n"
|
||||
"OZuAxWiynRJw3JwH/OFHYZIvQqz68ZBoj96cepjPAgMBAAGjezB5MAkGA1UdEwQC\n"
|
||||
"MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl\n"
|
||||
"MB0GA1UdDgQWBBTGn0OVVh/aoYt0bvEKG+PIERqnDzAfBgNVHSMEGDAWgBRY+3c3\n"
|
||||
"lxn8JG+5tuuSp8GcCqGr3jANBgkqhkiG9w0BAQsFAAOCAQEAd2nM8gCQN2Dc8QJw\n"
|
||||
"XSZXyuI3DBGGCHcay/3iXu0JvTC3EiQo8J6Djv7WLI0N5KH8mkm40u89fJAB2lLZ\n"
|
||||
"ShuHVtcC182bOKnePgwp9CNwQ21p0rDEu/P3X46ZvFgdxx82E9xLa0tBB8PiPDWh\n"
|
||||
"lV16jbaKTgX5AZqjnsyjR5o9/mbZVupZJXx5Syq+XA8qiJfstSYJs4KyKK9UOjql\n"
|
||||
"ICkJVKpi2ahDBqX4MOH4SLfzVk8pqSpviS6yaA1RXqjpkxiN45WWaXDldVHMSkhC\n"
|
||||
"5CNXsXi4b1nAntu89crwSLA3rEwzCWeYj+BX7e1T9rr3oJdwOU/2KQtW1js1yQUG\n"
|
||||
"tjJMFw==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char kBasicCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBpzCBkAIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoA4wDDAKBgNV\n"
|
||||
"HRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAnrBKKgvd9x9zwK9rtUvVeFeJ7+LN\n"
|
||||
"ZEAc+a5oxpPNEsJx6hXoApYEbzXMxuWBQoCs5iEBycSGudct21L+MVf27M38KrWo\n"
|
||||
"eOkq0a2siqViQZO2Fb/SUFR0k9zb8xl86Zf65lgPplALun0bV/HT7MJcl04Tc4os\n"
|
||||
"dsAReBs5nqTGNEd5AlC1iKHvQZkM//MD51DspKnDpsDiUVi54h9C1SpfZmX8H2Vv\n"
|
||||
"diyu0fZ/bPAM3VAGawatf/SyWfBMyKpoPXEG39oAzmjjOj8en82psn7m474IGaho\n"
|
||||
"/vBbhl1ms5qQiLYPjm4YELtnXQoFyC72tBjbdFd/ZE9k4CNKDbxFUXFbkw==\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBpzCBkAIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoA4wDDAKBgNV\n"
|
||||
"HRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAnrBKKgvd9x9zwK9rtUvVeFeJ7+LN\n"
|
||||
"ZEAc+a5oxpPNEsJx6hXoApYEbzXMxuWBQoCs5iEBycSGudct21L+MVf27M38KrWo\n"
|
||||
"eOkq0a2siqViQZO2Fb/SUFR0k9zb8xl86Zf65lgPplALun0bV/HT7MJcl04Tc4os\n"
|
||||
"dsAReBs5nqTGNEd5AlC1iKHvQZkM//MD51DspKnDpsDiUVi54h9C1SpfZmX8H2Vv\n"
|
||||
"diyu0fZ/bPAM3VAGawatf/SyWfBMyKpoPXEG39oAzmjjOj8en82psn7m474IGaho\n"
|
||||
"/vBbhl1ms5qQiLYPjm4YELtnXQoFyC72tBjbdFd/ZE9k4CNKDbxFUXFbkw==\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
static const char kRevokedCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBvjCBpwIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEyNDRaFw0xNjEwMjYxNTEyNDRaMBUwEwICEAAX\n"
|
||||
"DTE2MDkyNjE1MTIyNlqgDjAMMAoGA1UdFAQDAgECMA0GCSqGSIb3DQEBCwUAA4IB\n"
|
||||
"AQCUGaM4DcWzlQKrcZvI8TMeR8BpsvQeo5BoI/XZu2a8h//PyRyMwYeaOM+3zl0d\n"
|
||||
"sjgCT8b3C1FPgT+P2Lkowv7rJ+FHJRNQkogr+RuqCSPTq65ha4WKlRGWkMFybzVH\n"
|
||||
"NloxC+aU3lgp/NlX9yUtfqYmJek1CDrOOGPrAEAwj1l/BUeYKNGqfBWYJQtPJu+5\n"
|
||||
"OaSvIYGpETCZJscUWODmLEb/O3DM438vLvxonwGqXqS0KX37+CHpUlyhnSovxXxp\n"
|
||||
"Pz4aF+L7OtczxL0GYtD2fR9B7TDMqsNmHXgQrixvvOY7MUdLGbd4RfJL3yA53hyO\n"
|
||||
"xzfKY2TzxLiOmctG0hXFkH5J\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBvjCBpwIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEyNDRaFw0xNjEwMjYxNTEyNDRaMBUwEwICEAAX\n"
|
||||
"DTE2MDkyNjE1MTIyNlqgDjAMMAoGA1UdFAQDAgECMA0GCSqGSIb3DQEBCwUAA4IB\n"
|
||||
"AQCUGaM4DcWzlQKrcZvI8TMeR8BpsvQeo5BoI/XZu2a8h//PyRyMwYeaOM+3zl0d\n"
|
||||
"sjgCT8b3C1FPgT+P2Lkowv7rJ+FHJRNQkogr+RuqCSPTq65ha4WKlRGWkMFybzVH\n"
|
||||
"NloxC+aU3lgp/NlX9yUtfqYmJek1CDrOOGPrAEAwj1l/BUeYKNGqfBWYJQtPJu+5\n"
|
||||
"OaSvIYGpETCZJscUWODmLEb/O3DM438vLvxonwGqXqS0KX37+CHpUlyhnSovxXxp\n"
|
||||
"Pz4aF+L7OtczxL0GYtD2fR9B7TDMqsNmHXgQrixvvOY7MUdLGbd4RfJL3yA53hyO\n"
|
||||
"xzfKY2TzxLiOmctG0hXFkH5J\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
static const char kBadIssuerCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBwjCBqwIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEWMBQGA1UECgwN\n"
|
||||
"Tm90IEJvcmluZ1NTTBcNMTYwOTI2MTUxMjQ0WhcNMTYxMDI2MTUxMjQ0WjAVMBMC\n"
|
||||
"AhAAFw0xNjA5MjYxNTEyMjZaoA4wDDAKBgNVHRQEAwIBAjANBgkqhkiG9w0BAQsF\n"
|
||||
"AAOCAQEAlBmjOA3Fs5UCq3GbyPEzHkfAabL0HqOQaCP12btmvIf/z8kcjMGHmjjP\n"
|
||||
"t85dHbI4Ak/G9wtRT4E/j9i5KML+6yfhRyUTUJKIK/kbqgkj06uuYWuFipURlpDB\n"
|
||||
"cm81RzZaMQvmlN5YKfzZV/clLX6mJiXpNQg6zjhj6wBAMI9ZfwVHmCjRqnwVmCUL\n"
|
||||
"TybvuTmkryGBqREwmSbHFFjg5ixG/ztwzON/Ly78aJ8Bql6ktCl9+/gh6VJcoZ0q\n"
|
||||
"L8V8aT8+Ghfi+zrXM8S9BmLQ9n0fQe0wzKrDZh14EK4sb7zmOzFHSxm3eEXyS98g\n"
|
||||
"Od4cjsc3ymNk88S4jpnLRtIVxZB+SQ==\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBwjCBqwIBATANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEWMBQGA1UECgwN\n"
|
||||
"Tm90IEJvcmluZ1NTTBcNMTYwOTI2MTUxMjQ0WhcNMTYxMDI2MTUxMjQ0WjAVMBMC\n"
|
||||
"AhAAFw0xNjA5MjYxNTEyMjZaoA4wDDAKBgNVHRQEAwIBAjANBgkqhkiG9w0BAQsF\n"
|
||||
"AAOCAQEAlBmjOA3Fs5UCq3GbyPEzHkfAabL0HqOQaCP12btmvIf/z8kcjMGHmjjP\n"
|
||||
"t85dHbI4Ak/G9wtRT4E/j9i5KML+6yfhRyUTUJKIK/kbqgkj06uuYWuFipURlpDB\n"
|
||||
"cm81RzZaMQvmlN5YKfzZV/clLX6mJiXpNQg6zjhj6wBAMI9ZfwVHmCjRqnwVmCUL\n"
|
||||
"TybvuTmkryGBqREwmSbHFFjg5ixG/ztwzON/Ly78aJ8Bql6ktCl9+/gh6VJcoZ0q\n"
|
||||
"L8V8aT8+Ghfi+zrXM8S9BmLQ9n0fQe0wzKrDZh14EK4sb7zmOzFHSxm3eEXyS98g\n"
|
||||
"Od4cjsc3ymNk88S4jpnLRtIVxZB+SQ==\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kKnownCriticalCRL is kBasicCRL but with a critical issuing distribution point
|
||||
// extension.
|
||||
static const char kKnownCriticalCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBujCBowIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoCEwHzAKBgNV\n"
|
||||
"HRQEAwIBATARBgNVHRwBAf8EBzAFoQMBAf8wDQYJKoZIhvcNAQELBQADggEBAA+3\n"
|
||||
"i+5e5Ub8sccfgOBs6WVJFI9c8gvJjrJ8/dYfFIAuCyeocs7DFXn1n13CRZ+URR/Q\n"
|
||||
"mVWgU28+xeusuSPYFpd9cyYTcVyNUGNTI3lwgcE/yVjPaOmzSZKdPakApRxtpKKQ\n"
|
||||
"NN/56aQz3bnT/ZSHQNciRB8U6jiD9V30t0w+FDTpGaG+7bzzUH3UVF9xf9Ctp60A\n"
|
||||
"3mfLe0scas7owSt4AEFuj2SPvcE7yvdOXbu+IEv21cEJUVExJAbhvIweHXh6yRW+\n"
|
||||
"7VVeiNzdIjkZjyTmAzoXGha4+wbxXyBRbfH+XWcO/H+8nwyG8Gktdu2QB9S9nnIp\n"
|
||||
"o/1TpfOMSGhMyMoyPrk=\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kUnknownCriticalCRL is kBasicCRL but with an unknown critical extension.
|
||||
static const char kUnknownCriticalCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBvDCBpQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoCMwITAKBgNV\n"
|
||||
"HRQEAwIBATATBgwqhkiG9xIEAYS3CQABAf8EADANBgkqhkiG9w0BAQsFAAOCAQEA\n"
|
||||
"GvBP0xqL509InMj/3493YVRV+ldTpBv5uTD6jewzf5XdaxEQ/VjTNe5zKnxbpAib\n"
|
||||
"Kf7cwX0PMSkZjx7k7kKdDlEucwVvDoqC+O9aJcqVmM6GDyNb9xENxd0XCXja6MZC\n"
|
||||
"yVgP4AwLauB2vSiEprYJyI1APph3iAEeDm60lTXX/wBM/tupQDDujKh2GPyvBRfJ\n"
|
||||
"+wEDwGg3ICwvu4gO4zeC5qnFR+bpL9t5tOMAQnVZ0NWv+k7mkd2LbHdD44dxrfXC\n"
|
||||
"nhtfERx99SDmC/jtUAJrGhtCO8acr7exCeYcduN7KKCm91OeCJKK6OzWst0Og1DB\n"
|
||||
"kwzzU2rL3G65CrZ7H0SZsQ==\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kUnknownCriticalCRL2 is kBasicCRL but with a critical issuing distribution
|
||||
// point extension followed by an unknown critical extension
|
||||
static const char kUnknownCriticalCRL2[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoDYwNDAKBgNV\n"
|
||||
"HRQEAwIBATARBgNVHRwBAf8EBzAFoQMBAf8wEwYMKoZIhvcSBAGEtwkAAQH/BAAw\n"
|
||||
"DQYJKoZIhvcNAQELBQADggEBACTcpQC8jXL12JN5YzOcQ64ubQIe0XxRAd30p7qB\n"
|
||||
"BTXGpgqBjrjxRfLms7EBYodEXB2oXMsDq3km0vT1MfYdsDD05S+SQ9CDsq/pUfaC\n"
|
||||
"E2WNI5p8WircRnroYvbN2vkjlRbMd1+yNITohXYXCJwjEOAWOx3XIM10bwPYBv4R\n"
|
||||
"rDobuLHoMgL3yHgMHmAkP7YpkBucNqeBV8cCdeAZLuhXFWi6yfr3r/X18yWbC/r2\n"
|
||||
"2xXdkrSqXLFo7ToyP8YKTgiXpya4x6m53biEYwa2ULlas0igL6DK7wjYZX95Uy7H\n"
|
||||
"GKljn9weIYiMPV/BzGymwfv2EW0preLwtyJNJPaxbdin6Jc=\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// CertFromPEM parses the given, NUL-terminated pem block and returns an
|
||||
// |X509*|.
|
||||
@@ -335,9 +412,10 @@ static bssl::UniquePtr<EVP_PKEY> PrivateKeyFromPEM(const char *pem) {
|
||||
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509*),
|
||||
// CertsToStack converts a vector of |X509*| to an OpenSSL STACK_OF(X509),
|
||||
// bumping the reference counts for each certificate in question.
|
||||
static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
|
||||
static bssl::UniquePtr<STACK_OF(X509)> CertsToStack(
|
||||
const std::vector<X509 *> &certs) {
|
||||
bssl::UniquePtr<STACK_OF(X509)> stack(sk_X509_new_null());
|
||||
if (!stack) {
|
||||
return nullptr;
|
||||
@@ -349,12 +427,13 @@ static STACK_OF(X509)* CertsToStack(const std::vector<X509*> &certs) {
|
||||
X509_up_ref(cert);
|
||||
}
|
||||
|
||||
return stack.release();
|
||||
return stack;
|
||||
}
|
||||
|
||||
// CRLsToStack converts a vector of |X509_CRL*| to an OpenSSL STACK_OF(X509_CRL*),
|
||||
// bumping the reference counts for each CRL in question.
|
||||
static STACK_OF(X509_CRL)* CRLsToStack(const std::vector<X509_CRL*> &crls) {
|
||||
// CRLsToStack converts a vector of |X509_CRL*| to an OpenSSL
|
||||
// STACK_OF(X509_CRL), bumping the reference counts for each CRL in question.
|
||||
static bssl::UniquePtr<STACK_OF(X509_CRL)> CRLsToStack(
|
||||
const std::vector<X509_CRL *> &crls) {
|
||||
bssl::UniquePtr<STACK_OF(X509_CRL)> stack(sk_X509_CRL_new_null());
|
||||
if (!stack) {
|
||||
return nullptr;
|
||||
@@ -366,7 +445,7 @@ static STACK_OF(X509_CRL)* CRLsToStack(const std::vector<X509_CRL*> &crls) {
|
||||
X509_CRL_up_ref(crl);
|
||||
}
|
||||
|
||||
return stack.release();
|
||||
return stack;
|
||||
}
|
||||
|
||||
static int Verify(X509 *leaf, const std::vector<X509 *> &roots,
|
||||
@@ -522,13 +601,21 @@ static bool TestCRL() {
|
||||
bssl::UniquePtr<X509_CRL> basic_crl(CRLFromPEM(kBasicCRL));
|
||||
bssl::UniquePtr<X509_CRL> revoked_crl(CRLFromPEM(kRevokedCRL));
|
||||
bssl::UniquePtr<X509_CRL> bad_issuer_crl(CRLFromPEM(kBadIssuerCRL));
|
||||
bssl::UniquePtr<X509_CRL> known_critical_crl(CRLFromPEM(kKnownCriticalCRL));
|
||||
bssl::UniquePtr<X509_CRL> unknown_critical_crl(
|
||||
CRLFromPEM(kUnknownCriticalCRL));
|
||||
bssl::UniquePtr<X509_CRL> unknown_critical_crl2(
|
||||
CRLFromPEM(kUnknownCriticalCRL2));
|
||||
|
||||
if (!root ||
|
||||
!leaf ||
|
||||
!basic_crl ||
|
||||
!revoked_crl ||
|
||||
!bad_issuer_crl) {
|
||||
fprintf(stderr, "Failed to parse certificates\n");
|
||||
!bad_issuer_crl ||
|
||||
!known_critical_crl ||
|
||||
!unknown_critical_crl ||
|
||||
!unknown_critical_crl2) {
|
||||
fprintf(stderr, "Failed to parse certificates and CRLs.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -558,6 +645,26 @@ static bool TestCRL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Verify(leaf.get(), {root.get()}, {root.get()}, {known_critical_crl.get()},
|
||||
X509_V_FLAG_CRL_CHECK) != X509_V_OK) {
|
||||
fprintf(stderr, "CRL with known critical extension was rejected.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Verify(leaf.get(), {root.get()}, {root.get()},
|
||||
{unknown_critical_crl.get()}, X509_V_FLAG_CRL_CHECK) !=
|
||||
X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION) {
|
||||
fprintf(stderr, "CRL with unknown critical extension was accepted.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Verify(leaf.get(), {root.get()}, {root.get()},
|
||||
{unknown_critical_crl2.get()}, X509_V_FLAG_CRL_CHECK) !=
|
||||
X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION) {
|
||||
fprintf(stderr, "CRL with unknown critical extension (2) was accepted.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -639,6 +746,201 @@ static bool TestSignCtx() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool PEMToDER(bssl::UniquePtr<uint8_t> *out, size_t *out_len,
|
||||
const char *pem) {
|
||||
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
|
||||
if (!bio) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char *name, *header;
|
||||
uint8_t *data;
|
||||
long data_len;
|
||||
if (!PEM_read_bio(bio.get(), &name, &header, &data, &data_len)) {
|
||||
fprintf(stderr, "failed to read PEM data.\n");
|
||||
return false;
|
||||
}
|
||||
OPENSSL_free(name);
|
||||
OPENSSL_free(header);
|
||||
|
||||
out->reset(data);
|
||||
*out_len = data_len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestFromBuffer() {
|
||||
size_t data_len;
|
||||
bssl::UniquePtr<uint8_t> data;
|
||||
if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||
CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
|
||||
if (!root) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *enc_pointer = root->cert_info->enc.enc;
|
||||
const uint8_t *buf_pointer = CRYPTO_BUFFER_data(buf.get());
|
||||
if (enc_pointer < buf_pointer ||
|
||||
enc_pointer >= buf_pointer + CRYPTO_BUFFER_len(buf.get())) {
|
||||
fprintf(stderr, "TestFromBuffer: enc does not alias the buffer.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
buf.reset();
|
||||
|
||||
/* This ensures the X509 took a reference to |buf|, otherwise this will be a
|
||||
* reference to free memory and ASAN should notice. */
|
||||
if (enc_pointer[0] != CBS_ASN1_SEQUENCE) {
|
||||
fprintf(stderr, "TestFromBuffer: enc data is not a SEQUENCE.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestFromBufferTrailingData() {
|
||||
size_t data_len;
|
||||
bssl::UniquePtr<uint8_t> data;
|
||||
if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> trailing_data(new uint8_t[data_len + 1]);
|
||||
memcpy(trailing_data.get(), data.get(), data_len);
|
||||
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf_trailing_data(
|
||||
CRYPTO_BUFFER_new(trailing_data.get(), data_len + 1, nullptr));
|
||||
if (!buf_trailing_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<X509> root_trailing_data(
|
||||
X509_parse_from_buffer(buf_trailing_data.get()));
|
||||
if (root_trailing_data) {
|
||||
fprintf(stderr, "TestFromBuffer: trailing data was not rejected.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestFromBufferModified() {
|
||||
size_t data_len;
|
||||
bssl::UniquePtr<uint8_t> data;
|
||||
if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||
CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
|
||||
if (!root) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<ASN1_INTEGER> fourty_two(ASN1_INTEGER_new());
|
||||
ASN1_INTEGER_set(fourty_two.get(), 42);
|
||||
X509_set_serialNumber(root.get(), fourty_two.get());
|
||||
|
||||
if (i2d_X509(root.get(), nullptr) != static_cast<long>(data_len)) {
|
||||
fprintf(stderr,
|
||||
"TestFromBufferModified: i2d_X509 gives different answer before "
|
||||
"marking as modified.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
X509_CINF_set_modified(root->cert_info);
|
||||
|
||||
if (i2d_X509(root.get(), nullptr) == static_cast<long>(data_len)) {
|
||||
fprintf(stderr,
|
||||
"TestFromBufferModified: i2d_X509 gives same answer after marking "
|
||||
"as modified.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestFromBufferReused() {
|
||||
size_t data_len;
|
||||
bssl::UniquePtr<uint8_t> data;
|
||||
if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||
CRYPTO_BUFFER_new(data.get(), data_len, nullptr));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<X509> root(X509_parse_from_buffer(buf.get()));
|
||||
if (!root) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t data2_len;
|
||||
bssl::UniquePtr<uint8_t> data2;
|
||||
if (!PEMToDER(&data2, &data2_len, kLeafPEM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
X509 *x509p = root.get();
|
||||
const uint8_t *inp = data2.get();
|
||||
X509 *ret = d2i_X509(&x509p, &inp, data2_len);
|
||||
if (ret != root.get()) {
|
||||
fprintf(stderr,
|
||||
"TestFromBufferReused: d2i_X509 parsed into a different object.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root->buf != nullptr) {
|
||||
fprintf(stderr,
|
||||
"TestFromBufferReused: d2i_X509 didn't clear |buf| pointer.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Free |data2| and ensure that |root| took its own copy. Otherwise the
|
||||
// following will trigger a use-after-free.
|
||||
data2.reset();
|
||||
|
||||
uint8_t *i2d = nullptr;
|
||||
int i2d_len = i2d_X509(root.get(), &i2d);
|
||||
if (i2d_len < 0) {
|
||||
return false;
|
||||
}
|
||||
bssl::UniquePtr<uint8_t> i2d_storage(i2d);
|
||||
|
||||
if (!PEMToDER(&data2, &data2_len, kLeafPEM)) {
|
||||
return false;
|
||||
}
|
||||
if (i2d_len != static_cast<long>(data2_len) ||
|
||||
memcmp(data2.get(), i2d, i2d_len) != 0) {
|
||||
fprintf(stderr, "TestFromBufferReused: i2d gave wrong result.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root->buf != NULL) {
|
||||
fprintf(stderr, "TestFromBufferReused: X509.buf was not cleared.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int Main() {
|
||||
CRYPTO_library_init();
|
||||
|
||||
@@ -646,7 +948,11 @@ static int Main() {
|
||||
!TestCRL() ||
|
||||
!TestPSS() ||
|
||||
!TestBadPSSParameters() ||
|
||||
!TestSignCtx()) {
|
||||
!TestSignCtx() ||
|
||||
!TestFromBuffer() ||
|
||||
!TestFromBufferTrailingData() ||
|
||||
!TestFromBufferModified() ||
|
||||
!TestFromBufferReused()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -227,8 +227,8 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
|
||||
/* Macro to test if a field should be copied from src to dest */
|
||||
|
||||
#define test_x509_verify_param_copy(field, def) \
|
||||
(to_overwrite || \
|
||||
((src->field != def) && (to_default || (dest->field == def))))
|
||||
(to_overwrite || \
|
||||
((src->field != (def)) && (to_default || (dest->field == (def)))))
|
||||
|
||||
/* As above but for ID fields */
|
||||
|
||||
@@ -513,7 +513,7 @@ const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
|
||||
static const X509_VERIFY_PARAM_ID _empty_id =
|
||||
{ NULL, 0U, NULL, NULL, 0, NULL, 0 };
|
||||
|
||||
#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
|
||||
#define vpm_empty_id ((X509_VERIFY_PARAM_ID *)&_empty_id)
|
||||
|
||||
/*
|
||||
* Default verify parameters: these are used for various applications and can
|
||||
|
||||
+4
-2
@@ -283,7 +283,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
if ((nid == NID_issuing_distribution_point)
|
||||
|| (nid == NID_authority_key_identifier)
|
||||
|| (nid == NID_delta_crl))
|
||||
break;;
|
||||
continue;
|
||||
crl->flags |= EXFLAG_CRITICAL;
|
||||
break;
|
||||
}
|
||||
@@ -299,7 +299,9 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
break;
|
||||
|
||||
case ASN1_OP_FREE_POST:
|
||||
if (crl->meth->crl_free) {
|
||||
/* |crl->meth| may be NULL if constructing the object failed before
|
||||
* |ASN1_OP_NEW_POST| was run. */
|
||||
if (crl->meth && crl->meth->crl_free) {
|
||||
if (!crl->meth->crl_free(crl))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ static int x509_name_canon(X509_NAME *a)
|
||||
STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
||||
X509_NAME_ENTRY *entry, *tmpentry = NULL;
|
||||
int set = -1, ret = 0;
|
||||
int set = -1, ret = 0, len;
|
||||
size_t i;
|
||||
|
||||
if (a->canon_enc) {
|
||||
@@ -386,7 +386,11 @@ static int x509_name_canon(X509_NAME *a)
|
||||
|
||||
/* Finally generate encoding */
|
||||
|
||||
a->canon_enclen = i2d_name_canon(intname, NULL);
|
||||
len = i2d_name_canon(intname, NULL);
|
||||
if (len < 0) {
|
||||
goto err;
|
||||
}
|
||||
a->canon_enclen = len;
|
||||
|
||||
p = OPENSSL_malloc(a->canon_enclen);
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/pool.h>
|
||||
#include <openssl/thread.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
@@ -103,9 +104,15 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
ret->akid = NULL;
|
||||
ret->aux = NULL;
|
||||
ret->crldp = NULL;
|
||||
ret->buf = NULL;
|
||||
CRYPTO_new_ex_data(&ret->ex_data);
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_PRE:
|
||||
CRYPTO_BUFFER_free(ret->buf);
|
||||
ret->buf = NULL;
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
if (ret->name != NULL)
|
||||
OPENSSL_free(ret->name);
|
||||
@@ -121,6 +128,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
policy_cache_free(ret->policy_cache);
|
||||
GENERAL_NAMES_free(ret->altname);
|
||||
NAME_CONSTRAINTS_free(ret->nc);
|
||||
CRYPTO_BUFFER_free(ret->buf);
|
||||
|
||||
if (ret->name != NULL)
|
||||
OPENSSL_free(ret->name);
|
||||
@@ -142,6 +150,31 @@ IMPLEMENT_ASN1_FUNCTIONS(X509)
|
||||
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
|
||||
|
||||
X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) {
|
||||
X509 *x509 = X509_new();
|
||||
if (x509 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
x509->cert_info->enc.alias_only_on_next_parse = 1;
|
||||
|
||||
const uint8_t *inp = CRYPTO_BUFFER_data(buf);
|
||||
X509 *x509p = x509;
|
||||
X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf));
|
||||
if (ret == NULL ||
|
||||
(inp - CRYPTO_BUFFER_data(buf)) != (ptrdiff_t) CRYPTO_BUFFER_len(buf)) {
|
||||
X509_free(x509);
|
||||
return NULL;
|
||||
}
|
||||
assert(x509p == x509);
|
||||
assert(ret == x509);
|
||||
|
||||
CRYPTO_BUFFER_up_ref(buf);
|
||||
ret->buf = buf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int X509_up_ref(X509 *x)
|
||||
{
|
||||
CRYPTO_refcount_inc(&x->references);
|
||||
|
||||
@@ -180,8 +180,8 @@ struct X509_POLICY_TREE_st {
|
||||
|
||||
/* Useful macros */
|
||||
|
||||
#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
|
||||
#define node_critical(node) node_data_critical(node->data)
|
||||
#define node_data_critical(data) ((data)->flags & POLICY_DATA_FLAG_CRITICAL)
|
||||
#define node_critical(node) node_data_critical((node)->data)
|
||||
|
||||
/* Internal functions */
|
||||
|
||||
|
||||
@@ -647,7 +647,7 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
|
||||
* key types.
|
||||
*/
|
||||
#define KU_TLS \
|
||||
KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
|
||||
(KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT)
|
||||
|
||||
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
|
||||
int ca)
|
||||
|
||||
@@ -79,15 +79,15 @@ static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
|
||||
do { \
|
||||
unsigned long ll; \
|
||||
ll = (c)->h[0]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[4]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
|
||||
|
||||
|
||||
+16
-16
@@ -86,51 +86,51 @@ static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
|
||||
D = h[3];
|
||||
E = h[4];
|
||||
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(0) = l;
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(1) = l;
|
||||
RIP1(A, B, C, D, E, WL00, SL00);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(2) = l;
|
||||
RIP1(E, A, B, C, D, WL01, SL01);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(3) = l;
|
||||
RIP1(D, E, A, B, C, WL02, SL02);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(4) = l;
|
||||
RIP1(C, D, E, A, B, WL03, SL03);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(5) = l;
|
||||
RIP1(B, C, D, E, A, WL04, SL04);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(6) = l;
|
||||
RIP1(A, B, C, D, E, WL05, SL05);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(7) = l;
|
||||
RIP1(E, A, B, C, D, WL06, SL06);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(8) = l;
|
||||
RIP1(D, E, A, B, C, WL07, SL07);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(9) = l;
|
||||
RIP1(C, D, E, A, B, WL08, SL08);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(10) = l;
|
||||
RIP1(B, C, D, E, A, WL09, SL09);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(11) = l;
|
||||
RIP1(A, B, C, D, E, WL10, SL10);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(12) = l;
|
||||
RIP1(E, A, B, C, D, WL11, SL11);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(13) = l;
|
||||
RIP1(D, E, A, B, C, WL12, SL12);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(14) = l;
|
||||
RIP1(C, D, E, A, B, WL13, SL13);
|
||||
(void)HOST_c2l(data, l);
|
||||
HOST_c2l(data, l);
|
||||
X(15) = l;
|
||||
RIP1(B, C, D, E, A, WL14, SL14);
|
||||
RIP1(A, B, C, D, E, WL15, SL15);
|
||||
|
||||
@@ -64,3 +64,13 @@ add_executable(
|
||||
|
||||
target_link_libraries(read_pem Fuzzer)
|
||||
target_link_libraries(read_pem crypto)
|
||||
|
||||
add_executable(
|
||||
ssl_ctx_api
|
||||
|
||||
ssl_ctx_api.cc
|
||||
)
|
||||
|
||||
target_link_libraries(ssl_ctx_api Fuzzer)
|
||||
target_link_libraries(ssl_ctx_api crypto)
|
||||
target_link_libraries(ssl_ctx_api ssl)
|
||||
|
||||
+4
-3
@@ -12,12 +12,12 @@
|
||||
* 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/mem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len) {
|
||||
const uint8_t *bufp = buf;
|
||||
X509 *x509 = d2i_X509(NULL, &bufp, len);
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
X509 *x509 = d2i_X509(NULL, &buf, len);
|
||||
if (x509 != NULL) {
|
||||
/* Extract the public key. */
|
||||
EVP_PKEY_free(X509_get_pubkey(x509));
|
||||
@@ -28,5 +28,6 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len) {
|
||||
OPENSSL_free(der);
|
||||
}
|
||||
X509_free(x509);
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-1
@@ -15,6 +15,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
@@ -257,7 +258,7 @@ struct GlobalState {
|
||||
|
||||
static GlobalState g_state;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len) {
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
RAND_reset_for_fuzzing();
|
||||
|
||||
// TODO(davidben): Extract an SSL_SESSION from |buf| and offer it for
|
||||
@@ -290,5 +291,6 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len) {
|
||||
}
|
||||
SSL_free(client);
|
||||
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user