Break FIPS tests differently.

FIPS validation requires showing that the continuous and start-up tests
are effective by breaking them. Traditionally BoringSSL used #defines
that tweaked the expected values. However, 140-3 now requires that the
inputs be changed, not the expected outputs.

Also, the number of tests is going to increase. Since slower platforms
already took too long to compile BoringSSL n times (once for each test
to break) we want something faster too.

Therefore all the known-answer tests (KATs) are changed such that a Go
program can find and replace the input value in order to break them.
Thus we only need to recompile once to disable the integrity test.

The runtime tests still need a #define to break, but that #define is now
put in a header file so that only the module need be recompiled, not
everything as in the previous system.

Change-Id: Ib621198e6ad02253e29af0ccd978e3c3830ad54c
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51329
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
fips-20220613
Adam Langley 3 years ago committed by Boringssl LUCI CQ
parent f8235e4993
commit d04c32a3d8
  1. 25
      crypto/fipsmodule/FIPS.md
  2. 3
      crypto/fipsmodule/bcm.c
  3. 5
      crypto/fipsmodule/ec/ec_key.c
  4. 38
      crypto/fipsmodule/fips_break_test.h
  5. 5
      crypto/fipsmodule/rand/rand.c
  6. 5
      crypto/fipsmodule/rsa/rsa.c
  7. 664
      crypto/fipsmodule/self_check/self_check.c
  8. 89
      util/fipstools/break-kat.go
  9. 117
      util/fipstools/break-tests-android.sh
  10. 53
      util/fipstools/break-tests.sh
  11. 40
      util/fipstools/test-break-kat.sh

@ -20,22 +20,15 @@ CAVP results are calculated by `util/fipstools/cavp`, but that binary is almost
1. `-oracle-bin`: points to the location of `util/fipstools/cavp`
2. `-no-fax`: this is needed to suppress checking of the FAX files, which are only included in sample sets.
## Breaking power-on and continuous tests
In order to demonstrate failures of the various FIPS 140 tests, BoringSSL can be built in ways that will trigger such failures. This is controlled by passing `-DFIPS_BREAK_TEST=`(test to break) to CMake, where the following tests can be specified:
1. AES\_CBC
1. AES\_GCM
1. DES
1. SHA\_1
1. SHA\_256
1. SHA\_512
1. RSA\_SIG
1. ECDSA\_SIG
1. DRBG
1. RSA\_PWCT
1. ECDSA\_PWCT
1. TLS\_KDF
## Breaking known-answer and continuous tests
Each known-answer test (KAT) uses a unique, random input value. `util/fipstools/break-kat.go` contains a listing of those values and can be used to corrupt a given test in a binary. Since changes to the KAT input values will invalidate the integrity test, `BORINGSSL_FIPS_BREAK_TESTS` can be defined in `fips_break_tests.h` to disable it for the purposes of testing.
Some FIPS tests cannot be broken by replacing a known string in the binary. For those, when `BORINGSSL_FIPS_BREAK_TESTS` is defined, the environment variable `BORINGSSL_FIPS_BREAK_TEST` can be set to one of a number of values in order to break the corresponding test:
1. `RSA_PWCT`
1. `ECDSA_PWCT`
1. `CRNG`
## Breaking the integrity test

@ -29,6 +29,7 @@
#include <openssl/sha.h>
#include "../internal.h"
#include "fips_break_test.h"
#include "aes/aes.c"
#include "aes/aes_nohw.c"
@ -243,7 +244,9 @@ BORINGSSL_bcm_power_on_self_test(void) {
const uint8_t *expected = BORINGSSL_bcm_text_hash;
if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) {
#if !defined(BORINGSSL_FIPS_BREAK_TESTS)
goto err;
#endif
}
OPENSSL_cleanse(result, sizeof(result)); // FIPS 140-3, AS05.10.

@ -79,6 +79,7 @@
#include "internal.h"
#include "../delocate.h"
#include "../fips_break_test.h"
#include "../../internal.h"
@ -339,9 +340,9 @@ int EC_KEY_check_fips(const EC_KEY *key) {
if (key->priv_key) {
uint8_t data[16] = {0};
ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key);
#if defined(BORINGSSL_FIPS_BREAK_ECDSA_PWCT)
if (boringssl_fips_break_test("ECDSA_PWCT")) {
data[0] = ~data[0];
#endif
}
int ok = sig != NULL &&
ECDSA_do_verify(data, sizeof(data), sig, key);
ECDSA_SIG_free(sig);

@ -0,0 +1,38 @@
/* Copyright (c) 2022, 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_CRYPTO_FIPSMODULE_FIPS_BREAK_TEST_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_FIPS_BREAK_TEST_H
#include <openssl/base.h>
#include <stdlib.h>
#include <string.h>
#if defined(BORINGSSL_FIPS_BREAK_TESTS)
OPENSSL_INLINE int boringssl_fips_break_test(const char *test) {
const char *const value = getenv("BORINGSSL_FIPS_BREAK_TEST");
return value != NULL && strcmp(value, test) == 0;
}
#else
OPENSSL_INLINE int boringssl_fips_break_test(const char *test) {
return 0;
}
#endif // BORINGSSL_FIPS_BREAK_TESTS
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_FIPS_BREAK_TEST_H

@ -30,6 +30,7 @@
#include "fork_detect.h"
#include "../../internal.h"
#include "../delocate.h"
#include "../fips_break_test.h"
// It's assumed that the operating system always has an unfailing source of
@ -170,11 +171,11 @@ void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len,
CRYPTO_sysrand_for_seed(out_entropy, out_entropy_len);
}
#if defined(BORINGSSL_FIPS_BREAK_CRNG)
if (boringssl_fips_break_test("CRNG")) {
// This breaks the "continuous random number generator test" defined in FIPS
// 140-2, section 4.9.2, and implemented in |rand_get_seed|.
OPENSSL_memset(out_entropy, 0, out_entropy_len);
#endif
}
}
// In passive entropy mode, entropy is supplied from outside of the module via

@ -72,6 +72,7 @@
#include "../bn/internal.h"
#include "../delocate.h"
#include "../fips_break_test.h"
#include "../../internal.h"
#include "internal.h"
@ -905,9 +906,9 @@ int RSA_check_fips(RSA *key) {
ret = 0;
goto cleanup;
}
#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT)
if (boringssl_fips_break_test("RSA_PWCT")) {
data[0] = ~data[0];
#endif
}
if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
ret = 0;

@ -72,6 +72,28 @@ static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) {
return *out != NULL;
}
static int serialize_ecdsa_sig(uint8_t *out, size_t out_len,
const ECDSA_SIG *sig) {
if ((out_len & 1) || //
!BN_bn2bin_padded(out, out_len / 2, sig->r) ||
!BN_bn2bin_padded(out + out_len / 2, out_len / 2, sig->s)) {
return 0;
}
return 1;
}
static ECDSA_SIG *parse_ecdsa_sig(const uint8_t *in, size_t in_len) {
ECDSA_SIG *ret = ECDSA_SIG_new();
if (!ret || //
(in_len & 1) ||
BN_bin2bn(in, in_len/2, ret->r) == NULL ||
BN_bin2bn(in + in_len/2, in_len/2, ret->s) == NULL) {
ECDSA_SIG_free(ret);
ret = NULL;
}
return ret;
}
static RSA *self_test_rsa_key(void) {
static const uint8_t kN[] = {
0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc,
@ -275,134 +297,6 @@ err:
}
static int boringssl_self_test_slow(void) {
static const uint8_t kExampleDigest[32] = {
0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb,
0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb,
0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, 0x0f,
};
static const uint8_t kRSASignature[256] = {
0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33,
0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d,
0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5,
0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6,
0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9,
0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63,
0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29,
0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff,
0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68,
0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8,
0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14,
0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9,
0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3,
0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a,
0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4,
0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5,
0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae,
0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e,
0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b,
0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf,
0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d,
0xd2, 0x0c, 0xb1,
#if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG)
0x64
#else
0x00
#endif
};
const uint8_t kECDSASigS[32] = {
0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6,
0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a,
0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8,
};
// kP256Point is SHA256("Primitive Z Computation KAT")×G within P-256.
const uint8_t kP256Point[65] = {
0x04, 0x4e, 0xc1, 0x94, 0x8c, 0x5c, 0xf4, 0x37, 0x35, 0x0d, 0xa3,
0xf9, 0x55, 0xf9, 0x8b, 0x26, 0x23, 0x5c, 0x43, 0xe0, 0x83, 0x51,
0x2b, 0x0d, 0x4b, 0x56, 0x24, 0xc3, 0xe4, 0xa5, 0xa8, 0xe2, 0xe9,
0x95, 0xf2, 0xc4, 0xb9, 0xb7, 0x48, 0x7d, 0x2a, 0xae, 0xc5, 0xc0,
0x0a, 0xcc, 0x1b, 0xd0, 0xec, 0xb8, 0xdc, 0xbe, 0x0c, 0xbe, 0x52,
0x79, 0x93, 0x7c, 0x0b, 0x92, 0x2b, 0x7f, 0x17, 0xa5, 0x80,
};
// kP256Scalar is SHA256("Primitive Z Computation KAT scalar").
const uint8_t kP256Scalar[32] = {
0xe7, 0x60, 0x44, 0x91, 0x26, 0x9a, 0xfb, 0x5b, 0x10, 0x2d, 0x6e,
0xa5, 0x2c, 0xb5, 0x9f, 0xeb, 0x70, 0xae, 0xde, 0x6c, 0xe3, 0xbf,
0xb3, 0xe0, 0x10, 0x54, 0x85, 0xab, 0xd8, 0x61, 0xd7, 0x7b,
};
// kP256PointResult is |kP256Scalar|×|kP256Point|.
const uint8_t kP256PointResult[65] = {
0x04, 0xf1, 0x63, 0x00, 0x88, 0xc5, 0xd5, 0xe9, 0x05, 0x52, 0xac,
0xb6, 0xec, 0x68, 0x76, 0xb8, 0x73, 0x7f, 0x0f, 0x72, 0x34, 0xe6,
0xbb, 0x30, 0x32, 0x22, 0x37, 0xb6, 0x2a, 0x80, 0xe8, 0x9e, 0x6e,
0x6f, 0x36, 0x02, 0xe7, 0x21, 0xd2, 0x31, 0xdb, 0x94, 0x63, 0xb7,
0xd8, 0x19, 0x0e, 0xc2, 0xc0, 0xa7, 0x2f, 0x15, 0x49, 0x1a, 0xa2,
0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a,
#if !defined(BORINGSSL_FIPS_BREAK_Z_COMPUTATION)
0x0c,
#else
0x00,
#endif
};
// kFFDHE2048PublicValueData is an arbitrary public value, mod
// kFFDHE2048Data. (The private key happens to be 4096.)
const BN_ULONG kFFDHE2048PublicValueData[] = {
TOBN(0x187be36b, 0xd38a4fa1), TOBN(0x0a152f39, 0x6458f3b8),
TOBN(0x0570187e, 0xc422eeb7), TOBN(0x18af7482, 0x91173f2a),
TOBN(0xe9fdac6a, 0xcff4eaaa), TOBN(0xf6afebb7, 0x6e589d6c),
TOBN(0xf92f8e9a, 0xb7e33fb0), TOBN(0x70acf2aa, 0x4cf36ddd),
TOBN(0x561ab426, 0xd07137fd), TOBN(0x5f57d037, 0x430ee91e),
TOBN(0xe3e768c8, 0x60d10b8a), TOBN(0xb14884d8, 0xa18af8ce),
TOBN(0xf8a98014, 0xa12b74e4), TOBN(0x748d407c, 0x3437b7a8),
TOBN(0x627588c4, 0x9875d5a7), TOBN(0xdd24a127, 0x53c8f09d),
TOBN(0x85a997d5, 0x0cd51aec), TOBN(0x44f0c619, 0xce348458),
TOBN(0x9b894b24, 0x5f6b69a1), TOBN(0xae1302f2, 0xf6d4777e),
TOBN(0xe6678eeb, 0x375db18e), TOBN(0x2674e1d6, 0x4fbcbdc8),
TOBN(0xb297a823, 0x6fa93d28), TOBN(0x6a12fb70, 0x7c8c0510),
TOBN(0x5c6d1aeb, 0xdb06f65b), TOBN(0xe8c2954e, 0x4c1804ca),
TOBN(0x06bdeac1, 0xf5500fa7), TOBN(0x6a315604, 0x189cd76b),
TOBN(0xbae7b0b3, 0x6e362dc0), TOBN(0xa57c73bd, 0xdc70fb82),
TOBN(0xfaff50d2, 0x9d573457), TOBN(0x352bd399, 0xbe84058e),
};
const uint8_t kDHOutput[2048 / 8] = {
0x2a, 0xe6, 0xd3, 0xa6, 0x13, 0x58, 0x8e, 0xce, 0x53, 0xaa, 0xf6, 0x5d,
0x9a, 0xae, 0x02, 0x12, 0xf5, 0x80, 0x3d, 0x06, 0x09, 0x76, 0xac, 0x57,
0x37, 0x9e, 0xab, 0x38, 0x62, 0x25, 0x05, 0x1d, 0xf3, 0xa9, 0x39, 0x60,
0xf6, 0xae, 0x90, 0xed, 0x1e, 0xad, 0x6e, 0xe9, 0xe3, 0xba, 0x27, 0xf6,
0xdb, 0x54, 0xdf, 0xe2, 0xbd, 0xbb, 0x7f, 0xf1, 0x81, 0xac, 0x1a, 0xfa,
0xdb, 0x87, 0x07, 0x98, 0x76, 0x90, 0x21, 0xf2, 0xae, 0xda, 0x0d, 0x84,
0x97, 0x64, 0x0b, 0xbf, 0xb8, 0x8d, 0x10, 0x46, 0xe2, 0xd5, 0xca, 0x1b,
0xbb, 0xe5, 0x37, 0xb2, 0x3b, 0x35, 0xd3, 0x1b, 0x65, 0xea, 0xae, 0xf2,
0x03, 0xe2, 0xb6, 0xde, 0x22, 0xb7, 0x86, 0x49, 0x79, 0xfe, 0xd7, 0x16,
0xf7, 0xdc, 0x9c, 0x59, 0xf5, 0xb7, 0x70, 0xc0, 0x53, 0x42, 0x6f, 0xb1,
0xd2, 0x4e, 0x00, 0x25, 0x4b, 0x2d, 0x5a, 0x9b, 0xd0, 0xe9, 0x27, 0x43,
0xcc, 0x00, 0x66, 0xea, 0x94, 0x7a, 0x0b, 0xb9, 0x89, 0x0c, 0x5e, 0x94,
0xb8, 0x3a, 0x78, 0x9c, 0x4d, 0x84, 0xe6, 0x32, 0x2c, 0x38, 0x7c, 0xf7,
0x43, 0x9c, 0xd8, 0xb8, 0x1c, 0xce, 0x24, 0x91, 0x20, 0x67, 0x7a, 0x54,
0x1f, 0x7e, 0x86, 0x7f, 0xa1, 0xc1, 0x03, 0x4e, 0x2c, 0x26, 0x71, 0xb2,
0x06, 0x30, 0xb3, 0x6c, 0x15, 0xcc, 0xac, 0x25, 0xe5, 0x37, 0x3f, 0x24,
0x8f, 0x2a, 0x89, 0x5e, 0x3d, 0x43, 0x94, 0xc9, 0x36, 0xae, 0x40, 0x00,
0x6a, 0x0d, 0xb0, 0x6e, 0x8b, 0x2e, 0x70, 0x57, 0xe1, 0x88, 0x53, 0xd6,
0x06, 0x80, 0x2a, 0x4e, 0x5a, 0xf0, 0x1e, 0xaa, 0xcb, 0xab, 0x06, 0x0e,
0x27, 0x0f, 0xd9, 0x88, 0xd9, 0x01, 0xe3, 0x07, 0xeb, 0xdf, 0xc3, 0x12,
0xe3, 0x40, 0x88, 0x7b, 0x5f, 0x59, 0x78, 0x6e, 0x26, 0x20, 0xc3, 0xdf,
0xc8, 0xe4, 0x5e,
#if !defined(BORINGSSL_FIPS_BREAK_FFC_DH)
0xb8,
#else
0x00,
#endif
};
const uint8_t kECDSASigR[32] = {
0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0,
0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02,
0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5,
#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG)
0x0c,
#else
0x00,
#endif
};
int ret = 0;
RSA *rsa_key = NULL;
EC_KEY *ec_key = NULL;
@ -411,6 +305,8 @@ static int boringssl_self_test_slow(void) {
EC_POINT *ec_point_out = NULL;
BIGNUM *ec_scalar = NULL;
ECDSA_SIG *sig = NULL;
DH *dh = NULL;
BIGNUM *ffdhe2048_value = NULL;
uint8_t output[256];
rsa_key = self_test_rsa_key();
@ -418,26 +314,85 @@ static int boringssl_self_test_slow(void) {
fprintf(stderr, "RSA KeyGen failed\n");
goto err;
}
// RSA Sign KAT
unsigned sig_len;
// Disable blinding for the power-on tests because it's not needed and
// triggers an entropy draw.
rsa_key->flags |= RSA_FLAG_NO_BLINDING;
if (!RSA_sign(NID_sha256, kExampleDigest, sizeof(kExampleDigest), output,
// RSA Sign KAT
static const uint8_t kRSASignDigest[32] = {
0xd2, 0xb5, 0x6e, 0x53, 0x30, 0x6f, 0x72, 0x0d, 0x79, 0x29, 0xd8,
0x70, 0x8b, 0xf4, 0x6f, 0x1c, 0x22, 0x30, 0x03, 0x05, 0x58, 0x2b,
0x11, 0x5b, 0xed, 0xca, 0xc7, 0x22, 0xd8, 0xaa, 0x5a, 0xb2,
};
static const uint8_t kRSASignSignature[256] = {
0x64, 0xce, 0xdd, 0x91, 0x27, 0xb0, 0x4f, 0xb9, 0x14, 0xea, 0xc0, 0xb4,
0xa2, 0x06, 0xc5, 0xd8, 0x40, 0x0f, 0x6c, 0x54, 0xac, 0xf7, 0x02, 0xde,
0x26, 0xbb, 0xfd, 0x33, 0xe5, 0x2f, 0x4d, 0xb1, 0x53, 0xc4, 0xff, 0xd0,
0x5f, 0xea, 0x15, 0x89, 0x83, 0x4c, 0xe3, 0x80, 0x0b, 0xe9, 0x13, 0x82,
0x1d, 0x71, 0x92, 0x1a, 0x03, 0x60, 0x2c, 0xaf, 0xe2, 0x16, 0xc7, 0x43,
0x3f, 0xde, 0x6b, 0x94, 0xfd, 0x6e, 0x08, 0x7b, 0x11, 0xf1, 0x34, 0x52,
0xe5, 0xc0, 0x97, 0x66, 0x4a, 0xe0, 0x91, 0x45, 0xc8, 0xb1, 0x3d, 0x6a,
0x54, 0xc1, 0x32, 0x0f, 0x32, 0xad, 0x25, 0x11, 0x3e, 0x49, 0xad, 0x41,
0xce, 0x7b, 0xca, 0x95, 0x6b, 0x54, 0x5e, 0x86, 0x1b, 0xce, 0xfa, 0x2a,
0x60, 0xe8, 0xfa, 0xbb, 0x23, 0xb2, 0x41, 0xbc, 0x7c, 0x98, 0xec, 0x73,
0x20, 0xed, 0xb3, 0xcf, 0xab, 0x07, 0x24, 0x85, 0x6a, 0x2a, 0x61, 0x76,
0x28, 0xf8, 0x00, 0x80, 0xeb, 0xd9, 0x3a, 0x63, 0xe2, 0x01, 0xb1, 0xee,
0x6d, 0xe9, 0x73, 0xe9, 0xb6, 0x75, 0x2e, 0xf9, 0x81, 0xd9, 0xa8, 0x79,
0xf6, 0x8f, 0xe3, 0x02, 0x7d, 0xf6, 0xea, 0xdc, 0x35, 0xe4, 0x62, 0x0d,
0x91, 0xba, 0x3e, 0x7d, 0x8b, 0x82, 0xbf, 0x15, 0x74, 0x6a, 0x4e, 0x29,
0xf8, 0x9b, 0x2c, 0x94, 0x8d, 0xa7, 0x00, 0x4d, 0x7b, 0xbf, 0x35, 0x07,
0xeb, 0xdd, 0x10, 0xef, 0xd5, 0x2f, 0xe6, 0x98, 0x4b, 0x7e, 0x24, 0x80,
0xe2, 0x01, 0xf2, 0x66, 0xb7, 0xd3, 0x93, 0xfe, 0x2a, 0xb3, 0x74, 0xed,
0xec, 0x4b, 0xb1, 0x5f, 0x5f, 0xee, 0x85, 0x44, 0xa7, 0x26, 0xdf, 0xc1,
0x2e, 0x7a, 0xf3, 0xa5, 0x8f, 0xf8, 0x64, 0xda, 0x65, 0xad, 0x91, 0xe2,
0x90, 0x94, 0x20, 0x16, 0xb8, 0x61, 0xa5, 0x0a, 0x7d, 0xb4, 0xbf, 0xc0,
0x10, 0xaf, 0x72, 0x67,
};
unsigned sig_len;
if (!RSA_sign(NID_sha256, kRSASignDigest, sizeof(kRSASignDigest), output,
&sig_len, rsa_key) ||
!check_test(kRSASignature, output, sizeof(kRSASignature),
"RSA Sign KAT")) {
!check_test(kRSASignSignature, output, sizeof(kRSASignSignature),
"RSA-sign KAT")) {
fprintf(stderr, "RSA signing test failed.\n");
goto err;
}
// RSA Verify KAT
if (!RSA_verify(NID_sha256, kExampleDigest, sizeof(kExampleDigest),
kRSASignature, sizeof(kRSASignature), rsa_key)) {
fprintf(stderr, "RSA Verify KAT failed.\n");
static const uint8_t kRSAVerifyDigest[32] = {
0x09, 0x65, 0x2f, 0xd8, 0xed, 0x9d, 0xc2, 0x6d, 0xbc, 0xbf, 0xf2,
0xa7, 0xa5, 0xed, 0xe1, 0x37, 0x13, 0x78, 0x21, 0x36, 0xcf, 0x8d,
0x22, 0x3d, 0xab, 0x93, 0xb4, 0x12, 0xa8, 0xb5, 0x15, 0x53,
};
static const uint8_t kRSAVerifySignature[256] = {
0xab, 0xe2, 0xcb, 0xc1, 0x3d, 0x6b, 0xd3, 0x9d, 0x48, 0xdb, 0x53, 0x34,
0xdd, 0xbf, 0x8d, 0x07, 0x0a, 0x93, 0xbd, 0xcb, 0x10, 0x4e, 0x2c, 0xc5,
0xd0, 0xee, 0x48, 0x6e, 0xe2, 0x95, 0xf6, 0xb3, 0x1b, 0xda, 0x12, 0x6c,
0x41, 0x89, 0x0b, 0x98, 0xb7, 0x3e, 0x70, 0xe6, 0xb6, 0x5d, 0x82, 0xf9,
0x5c, 0x66, 0x31, 0x21, 0x75, 0x5a, 0x90, 0x74, 0x4c, 0x8d, 0x1c, 0x21,
0x14, 0x8a, 0x19, 0x60, 0xbe, 0x0e, 0xca, 0x44, 0x6e, 0x9f, 0xf4, 0x97,
0xf1, 0x34, 0x5c, 0x53, 0x7e, 0xf8, 0x11, 0x9b, 0x9a, 0x43, 0x98, 0xe9,
0x5c, 0x5c, 0x6d, 0xe2, 0xb1, 0xc9, 0x55, 0x90, 0x5c, 0x52, 0x99, 0xd8,
0xce, 0x7a, 0x3b, 0x6a, 0xb7, 0x63, 0x80, 0xd9, 0xba, 0xbd, 0xd1, 0x5f,
0x61, 0x02, 0x37, 0xe1, 0xf3, 0xf2, 0xaa, 0x1c, 0x1f, 0x1e, 0x77, 0x0b,
0x62, 0xfb, 0xb5, 0x96, 0x38, 0x1b, 0x2e, 0xbd, 0xd7, 0x7e, 0xce, 0xf9,
0xc9, 0x0d, 0x4c, 0x92, 0xf7, 0xb6, 0xb0, 0x5f, 0xed, 0x29, 0x36, 0x28,
0x5f, 0xa9, 0x48, 0x26, 0xe6, 0x20, 0x55, 0x32, 0x2a, 0x33, 0xb6, 0xf0,
0x4c, 0x74, 0xce, 0x69, 0xe5, 0xd8, 0xd7, 0x37, 0xfb, 0x83, 0x8b, 0x79,
0xd2, 0xd4, 0x8e, 0x3d, 0xaf, 0x71, 0x38, 0x75, 0x31, 0x88, 0x25, 0x31,
0xa9, 0x5a, 0xc9, 0x64, 0xd0, 0x2e, 0xa4, 0x13, 0xbf, 0x85, 0x95, 0x29,
0x82, 0xbb, 0xc0, 0x89, 0x52, 0x7d, 0xaf, 0xf5, 0xb8, 0x45, 0xc9, 0xa0,
0xf4, 0xd1, 0x4e, 0xf1, 0x95, 0x6d, 0x9c, 0x3a, 0xca, 0xe8, 0x82, 0xd1,
0x2d, 0xa6, 0x6d, 0xa0, 0xf3, 0x57, 0x94, 0xf5, 0xee, 0x32, 0x23, 0x23,
0x33, 0x51, 0x7d, 0xb9, 0x31, 0x52, 0x32, 0xa1, 0x83, 0xb9, 0x91, 0x65,
0x4d, 0xbe, 0xa4, 0x16, 0x15, 0x34, 0x5c, 0x88, 0x53, 0x25, 0x92, 0x67,
0x44, 0xa5, 0x39, 0x15,
};
if (!RSA_verify(NID_sha256, kRSAVerifyDigest, sizeof(kRSAVerifyDigest),
kRSAVerifySignature, sizeof(kRSAVerifySignature), rsa_key)) {
fprintf(stderr, "RSA-verify KAT failed.\n");
goto err;
}
@ -449,34 +404,86 @@ static int boringssl_self_test_slow(void) {
// ECDSA Sign/Verify KAT
static const uint8_t kECDSASignDigest[32] = {
0x1e, 0x35, 0x93, 0x0b, 0xe8, 0x60, 0xd0, 0x94, 0x2c, 0xa7, 0xbb,
0xd6, 0xf6, 0xde, 0xd8, 0x7f, 0x15, 0x7e, 0x4d, 0xe2, 0x4f, 0x81,
0xed, 0x4b, 0x87, 0x5c, 0x0e, 0x01, 0x8e, 0x89, 0xa8, 0x1f,
};
static const uint8_t kECDSASignSig[64] = {
0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0,
0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02,
0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x68,
0x04, 0x73, 0x40, 0x94, 0xb2, 0xd1, 0x90, 0xac, 0x2d, 0x0c, 0xd7,
0xa5, 0x7f, 0x2f, 0x2e, 0xb2, 0x62, 0xb0, 0x09, 0x16, 0xe1, 0xa6,
0x70, 0xb5, 0xbb, 0x0d, 0xfd, 0x8e, 0x0c, 0x02, 0x3f,
};
// The 'k' value for ECDSA is fixed to avoid an entropy draw.
uint8_t ecdsa_k[32] = {0};
ecdsa_k[31] = 42;
sig = ecdsa_sign_with_nonce_for_known_answer_test(
kExampleDigest, sizeof(kExampleDigest), ec_key, ecdsa_k,
kECDSASignDigest, sizeof(kECDSASignDigest), ec_key, ecdsa_k,
sizeof(ecdsa_k));
uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)];
uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)];
uint8_t ecdsa_sign_output[64];
if (sig == NULL ||
BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) ||
!BN_bn2bin(sig->r, ecdsa_r_bytes) ||
BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) ||
!BN_bn2bin(sig->s, ecdsa_s_bytes) ||
!check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") ||
!check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) {
fprintf(stderr, "ECDSA signature KAT failed.\n");
!serialize_ecdsa_sig(ecdsa_sign_output, sizeof(ecdsa_sign_output), sig) ||
!check_test(kECDSASignSig, ecdsa_sign_output, sizeof(ecdsa_sign_output),
"ECDSA-sign signature")) {
fprintf(stderr, "ECDSA-sign KAT failed.\n");
goto err;
}
if (!ECDSA_do_verify(kExampleDigest, sizeof(kExampleDigest), sig,
ec_key)) {
fprintf(stderr, "ECDSA verification KAT failed.\n");
static const uint8_t kECDSAVerifyDigest[32] = {
0x78, 0x7c, 0x50, 0x5c, 0x60, 0xc9, 0xe4, 0x13, 0x6c, 0xe4, 0x48,
0xba, 0x93, 0xff, 0x71, 0xfa, 0x9c, 0x18, 0xf4, 0x17, 0x09, 0x4f,
0xdf, 0x5a, 0xe2, 0x75, 0xc0, 0xcc, 0xd2, 0x67, 0x97, 0xad,
};
static const uint8_t kECDSAVerifySig[64] = {
0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0,
0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02,
0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x2d,
0x36, 0xe5, 0x79, 0x97, 0x90, 0xbf, 0xbe, 0x21, 0x83, 0xd3, 0x3e,
0x96, 0xf3, 0xc5, 0x1f, 0x6a, 0x23, 0x2f, 0x2a, 0x24, 0x48, 0x8c,
0x8e, 0x5f, 0x64, 0xc3, 0x7e, 0xa2, 0xcf, 0x05, 0x29,
};
ECDSA_SIG_free(sig);
sig = parse_ecdsa_sig(kECDSAVerifySig, sizeof(kECDSAVerifySig));
if (!sig || !ECDSA_do_verify(kECDSAVerifyDigest, sizeof(kECDSAVerifyDigest),
sig, ec_key)) {
fprintf(stderr, "ECDSA-verify KAT failed.\n");
goto err;
}
// Primitive Z Computation KAT (IG 9.6).
// kP256Point is SHA256("Primitive Z Computation KAT")×G within P-256.
static const uint8_t kP256Point[65] = {
0x04, 0x4e, 0xc1, 0x94, 0x8c, 0x5c, 0xf4, 0x37, 0x35, 0x0d, 0xa3,
0xf9, 0x55, 0xf9, 0x8b, 0x26, 0x23, 0x5c, 0x43, 0xe0, 0x83, 0x51,
0x2b, 0x0d, 0x4b, 0x56, 0x24, 0xc3, 0xe4, 0xa5, 0xa8, 0xe2, 0xe9,
0x95, 0xf2, 0xc4, 0xb9, 0xb7, 0x48, 0x7d, 0x2a, 0xae, 0xc5, 0xc0,
0x0a, 0xcc, 0x1b, 0xd0, 0xec, 0xb8, 0xdc, 0xbe, 0x0c, 0xbe, 0x52,
0x79, 0x93, 0x7c, 0x0b, 0x92, 0x2b, 0x7f, 0x17, 0xa5, 0x80,
};
// kP256Scalar is SHA256("Primitive Z Computation KAT scalar").
static const uint8_t kP256Scalar[32] = {
0xe7, 0x60, 0x44, 0x91, 0x26, 0x9a, 0xfb, 0x5b, 0x10, 0x2d, 0x6e,
0xa5, 0x2c, 0xb5, 0x9f, 0xeb, 0x70, 0xae, 0xde, 0x6c, 0xe3, 0xbf,
0xb3, 0xe0, 0x10, 0x54, 0x85, 0xab, 0xd8, 0x61, 0xd7, 0x7b,
};
// kP256PointResult is |kP256Scalar|×|kP256Point|.
static const uint8_t kP256PointResult[65] = {
0x04, 0xf1, 0x63, 0x00, 0x88, 0xc5, 0xd5, 0xe9, 0x05, 0x52, 0xac,
0xb6, 0xec, 0x68, 0x76, 0xb8, 0x73, 0x7f, 0x0f, 0x72, 0x34, 0xe6,
0xbb, 0x30, 0x32, 0x22, 0x37, 0xb6, 0x2a, 0x80, 0xe8, 0x9e, 0x6e,
0x6f, 0x36, 0x02, 0xe7, 0x21, 0xd2, 0x31, 0xdb, 0x94, 0x63, 0xb7,
0xd8, 0x19, 0x0e, 0xc2, 0xc0, 0xa7, 0x2f, 0x15, 0x49, 0x1a, 0xa2,
0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a, 0x0c,
};
ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (ec_group == NULL) {
fprintf(stderr, "Failed to create P-256 group.\n");
@ -496,29 +503,68 @@ static int boringssl_self_test_slow(void) {
z_comp_result, sizeof(z_comp_result), NULL) ||
!check_test(kP256PointResult, z_comp_result, sizeof(z_comp_result),
"Z Computation Result")) {
fprintf(stderr, "Z Computation KAT failed.\n");
fprintf(stderr, "Z-computation KAT failed.\n");
goto err;
}
// FFC Diffie-Hellman KAT
BIGNUM *const ffdhe2048_value = BN_new();
DH *const dh = self_test_dh();
int dh_ok = 0;
if (ffdhe2048_value && dh) {
// kFFDHE2048PublicValueData is an arbitrary public value, mod
// kFFDHE2048Data. (The private key happens to be 4096.)
static const BN_ULONG kFFDHE2048PublicValueData[] = {
TOBN(0x187be36b, 0xd38a4fa1), TOBN(0x0a152f39, 0x6458f3b8),
TOBN(0x0570187e, 0xc422eeb7), TOBN(0x18af7482, 0x91173f2a),
TOBN(0xe9fdac6a, 0xcff4eaaa), TOBN(0xf6afebb7, 0x6e589d6c),
TOBN(0xf92f8e9a, 0xb7e33fb0), TOBN(0x70acf2aa, 0x4cf36ddd),
TOBN(0x561ab426, 0xd07137fd), TOBN(0x5f57d037, 0x430ee91e),
TOBN(0xe3e768c8, 0x60d10b8a), TOBN(0xb14884d8, 0xa18af8ce),
TOBN(0xf8a98014, 0xa12b74e4), TOBN(0x748d407c, 0x3437b7a8),
TOBN(0x627588c4, 0x9875d5a7), TOBN(0xdd24a127, 0x53c8f09d),
TOBN(0x85a997d5, 0x0cd51aec), TOBN(0x44f0c619, 0xce348458),
TOBN(0x9b894b24, 0x5f6b69a1), TOBN(0xae1302f2, 0xf6d4777e),
TOBN(0xe6678eeb, 0x375db18e), TOBN(0x2674e1d6, 0x4fbcbdc8),
TOBN(0xb297a823, 0x6fa93d28), TOBN(0x6a12fb70, 0x7c8c0510),
TOBN(0x5c6d1aeb, 0xdb06f65b), TOBN(0xe8c2954e, 0x4c1804ca),
TOBN(0x06bdeac1, 0xf5500fa7), TOBN(0x6a315604, 0x189cd76b),
TOBN(0xbae7b0b3, 0x6e362dc0), TOBN(0xa57c73bd, 0xdc70fb82),
TOBN(0xfaff50d2, 0x9d573457), TOBN(0x352bd399, 0xbe84058e),
};
static const uint8_t kDHOutput[2048 / 8] = {
0x2a, 0xe6, 0xd3, 0xa6, 0x13, 0x58, 0x8e, 0xce, 0x53, 0xaa, 0xf6, 0x5d,
0x9a, 0xae, 0x02, 0x12, 0xf5, 0x80, 0x3d, 0x06, 0x09, 0x76, 0xac, 0x57,
0x37, 0x9e, 0xab, 0x38, 0x62, 0x25, 0x05, 0x1d, 0xf3, 0xa9, 0x39, 0x60,
0xf6, 0xae, 0x90, 0xed, 0x1e, 0xad, 0x6e, 0xe9, 0xe3, 0xba, 0x27, 0xf6,
0xdb, 0x54, 0xdf, 0xe2, 0xbd, 0xbb, 0x7f, 0xf1, 0x81, 0xac, 0x1a, 0xfa,
0xdb, 0x87, 0x07, 0x98, 0x76, 0x90, 0x21, 0xf2, 0xae, 0xda, 0x0d, 0x84,
0x97, 0x64, 0x0b, 0xbf, 0xb8, 0x8d, 0x10, 0x46, 0xe2, 0xd5, 0xca, 0x1b,
0xbb, 0xe5, 0x37, 0xb2, 0x3b, 0x35, 0xd3, 0x1b, 0x65, 0xea, 0xae, 0xf2,
0x03, 0xe2, 0xb6, 0xde, 0x22, 0xb7, 0x86, 0x49, 0x79, 0xfe, 0xd7, 0x16,
0xf7, 0xdc, 0x9c, 0x59, 0xf5, 0xb7, 0x70, 0xc0, 0x53, 0x42, 0x6f, 0xb1,
0xd2, 0x4e, 0x00, 0x25, 0x4b, 0x2d, 0x5a, 0x9b, 0xd0, 0xe9, 0x27, 0x43,
0xcc, 0x00, 0x66, 0xea, 0x94, 0x7a, 0x0b, 0xb9, 0x89, 0x0c, 0x5e, 0x94,
0xb8, 0x3a, 0x78, 0x9c, 0x4d, 0x84, 0xe6, 0x32, 0x2c, 0x38, 0x7c, 0xf7,
0x43, 0x9c, 0xd8, 0xb8, 0x1c, 0xce, 0x24, 0x91, 0x20, 0x67, 0x7a, 0x54,
0x1f, 0x7e, 0x86, 0x7f, 0xa1, 0xc1, 0x03, 0x4e, 0x2c, 0x26, 0x71, 0xb2,
0x06, 0x30, 0xb3, 0x6c, 0x15, 0xcc, 0xac, 0x25, 0xe5, 0x37, 0x3f, 0x24,
0x8f, 0x2a, 0x89, 0x5e, 0x3d, 0x43, 0x94, 0xc9, 0x36, 0xae, 0x40, 0x00,
0x6a, 0x0d, 0xb0, 0x6e, 0x8b, 0x2e, 0x70, 0x57, 0xe1, 0x88, 0x53, 0xd6,
0x06, 0x80, 0x2a, 0x4e, 0x5a, 0xf0, 0x1e, 0xaa, 0xcb, 0xab, 0x06, 0x0e,
0x27, 0x0f, 0xd9, 0x88, 0xd9, 0x01, 0xe3, 0x07, 0xeb, 0xdf, 0xc3, 0x12,
0xe3, 0x40, 0x88, 0x7b, 0x5f, 0x59, 0x78, 0x6e, 0x26, 0x20, 0xc3, 0xdf,
0xc8, 0xe4, 0x5e, 0xb8,
};
ffdhe2048_value = BN_new();
if (ffdhe2048_value) {
bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData,
OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData));
uint8_t dh_out[sizeof(kDHOutput)];
dh_ok =
sizeof(dh_out) == DH_size(dh) &&
DH_compute_key_padded(dh_out, ffdhe2048_value, dh) == sizeof(dh_out) &&
check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH");
}
BN_free(ffdhe2048_value);
DH_free(dh);
if (!dh_ok) {
dh = self_test_dh();
uint8_t dh_out[sizeof(kDHOutput)];
if (dh == NULL || ffdhe2048_value == NULL || sizeof(dh_out) != DH_size(dh) ||
DH_compute_key_padded(dh_out, ffdhe2048_value, dh) != sizeof(dh_out) ||
!check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH")) {
fprintf(stderr, "FFDH failed.\n");
goto err;
}
@ -533,6 +579,8 @@ err:
EC_GROUP_free(ec_group);
BN_free(ec_scalar);
ECDSA_SIG_free(sig);
DH_free(dh);
BN_free(ffdhe2048_value);
return ret;
}
@ -541,62 +589,59 @@ static const uint8_t kPlaintext[64] =
"BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!";
int boringssl_self_test_sha256(void) {
static const uint8_t kInput[16] = {
0xff, 0x3b, 0x85, 0x7d, 0xa7, 0x23, 0x6a, 0x2b,
0xaa, 0x0f, 0x39, 0x6b, 0x51, 0x52, 0x22, 0x17,
};
static const uint8_t kPlaintextSHA256[32] = {
0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb,
0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb,
0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce,
#if !defined(BORINGSSL_FIPS_BREAK_SHA_256)
0x0f
#else
0x00
#endif
0x7f, 0xe4, 0xd5, 0xf1, 0xa1, 0xe3, 0x82, 0x87, 0xd9, 0x58, 0xf5,
0x11, 0xc7, 0x1d, 0x5e, 0x27, 0x5e, 0xcc, 0xd2, 0x66, 0xcf, 0xb9,
0xc8, 0xc6, 0x60, 0xd8, 0x92, 0x1e, 0x57, 0xfd, 0x46, 0x75,
};
uint8_t output[SHA256_DIGEST_LENGTH];
// SHA-256 KAT
SHA256(kPlaintext, sizeof(kPlaintext), output);
SHA256(kInput, sizeof(kInput), output);
return check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256),
"SHA-256 KAT");
}
int boringssl_self_test_sha512(void) {
static const uint8_t kInput[16] = {
0x21, 0x25, 0x12, 0xf8, 0xd2, 0xad, 0x83, 0x22,
0x78, 0x1c, 0x6c, 0x4d, 0x69, 0xa9, 0xda, 0xa1,
};
static const uint8_t kPlaintextSHA512[64] = {
0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e,
0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74,
0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c,
0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c,
0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b,
0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68,
#if !defined(BORINGSSL_FIPS_BREAK_SHA_512)
0x14
#else
0x00
#endif
0x29, 0x3c, 0x94, 0x35, 0x4e, 0x98, 0x83, 0xe5, 0xc2, 0x78, 0x36,
0x7a, 0xe5, 0x18, 0x90, 0xbf, 0x35, 0x41, 0x01, 0x64, 0x19, 0x8d,
0x26, 0xeb, 0xe1, 0xf8, 0x2f, 0x04, 0x8e, 0xfa, 0x8b, 0x2b, 0xc6,
0xb2, 0x9d, 0x5d, 0x46, 0x76, 0x5a, 0xc8, 0xb5, 0x25, 0xa3, 0xea,
0x52, 0x84, 0x47, 0x6d, 0x6d, 0xf4, 0xc9, 0x71, 0xf3, 0x3d, 0x89,
0x4c, 0x3b, 0x20, 0x8c, 0x5b, 0x75, 0xe8, 0xf8, 0x7c,
};
uint8_t output[SHA512_DIGEST_LENGTH];
// SHA-512 KAT
SHA512(kPlaintext, sizeof(kPlaintext), output);
SHA512(kInput, sizeof(kInput), output);
return check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512),
"SHA-512 KAT");
}
int boringssl_self_test_hmac_sha256(void) {
static const uint8_t kInput[16] = {
0xda, 0xd9, 0x12, 0x93, 0xdf, 0xcf, 0x2a, 0x7c,
0x8e, 0xcd, 0x13, 0xfe, 0x35, 0x3f, 0xa7, 0x5b,
};
static const uint8_t kPlaintextHMACSHA256[32] = {
0x08, 0x0b, 0xa8, 0x16, 0xdf, 0xcb, 0x7a, 0xa0, 0xdc, 0xc7, 0x8d,
0xb5, 0x4b, 0x68, 0xb0, 0x3b, 0x92, 0x03, 0x0f, 0xb7, 0xe2, 0x1e,
0x42, 0x63, 0x0c, 0xf3, 0x64, 0xf9, 0xad, 0xe0, 0x66,
#if !defined(BORINGSSL_FIPS_BREAK_HMAC_SHA_256)
0x85
#else
0x00
#endif
0x36, 0x5f, 0x5b, 0xd5, 0xf5, 0xeb, 0xfd, 0xc7, 0x6e, 0x53, 0xa5,
0x73, 0x6d, 0x73, 0x20, 0x13, 0xaa, 0xd3, 0xbc, 0x86, 0x4b, 0xb8,
0x84, 0x94, 0x16, 0x46, 0x88, 0x9c, 0x48, 0xee, 0xa9, 0x0e,
};
uint8_t output[EVP_MAX_MD_SIZE];
unsigned output_len;
HMAC(EVP_sha256(), kPlaintext, sizeof(kPlaintext), kPlaintext,
sizeof(kPlaintext), output, &output_len);
HMAC(EVP_sha256(), kInput, sizeof(kInput), kInput, sizeof(kInput), output,
&output_len);
return output_len == sizeof(kPlaintextHMACSHA256) &&
check_test(kPlaintextHMACSHA256, output, sizeof(kPlaintextHMACSHA256),
"HMAC-SHA-256 KAT");
@ -605,93 +650,6 @@ int boringssl_self_test_hmac_sha256(void) {
int BORINGSSL_self_test(void) {
static const uint8_t kAESKey[16] = "BoringCrypto Key";
static const uint8_t kAESIV[16] = {0};
static const uint8_t kAESCBCCiphertext[64] = {
0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b,
0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c,
0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45,
0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad,
0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55,
0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8,
#if !defined(BORINGSSL_FIPS_BREAK_AES_CBC)
0x35
#else
0x00
#endif
};
static const uint8_t kAESGCMCiphertext[80] = {
0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9,
0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82,
0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa,
0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4,
0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33,
0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61,
0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64,
#if !defined(BORINGSSL_FIPS_BREAK_AES_GCM)
0x0d
#else
0x00
#endif
};
static const uint8_t kPlaintextSHA1[20] = {
0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd,
0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8,
#if !defined(BORINGSSL_FIPS_BREAK_SHA_1)
0x28
#else
0x00
#endif
};
const uint8_t kDRBGEntropy[48] =
"BCM Known Answer Test DBRG Initial Entropy ";
const uint8_t kDRBGPersonalization[18] = "BCMPersonalization";
const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD ";
const uint8_t kDRBGOutput[64] = {
0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5,
0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1,
0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9,
0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32,
0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d,
0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22,
#if !defined(BORINGSSL_FIPS_BREAK_DRBG)
0x95
#else
0x00
#endif
};
const uint8_t kDRBGEntropy2[48] =
"BCM Known Answer Test DBRG Reseed Entropy ";
const uint8_t kDRBGReseedOutput[64] = {
0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8,
0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2,
0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6,
0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e,
0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b,
0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4,
};
const uint8_t kTLSOutput[32] = {
0x67, 0x85, 0xde, 0x60, 0xfc, 0x0a, 0x83, 0xe9, 0xa2, 0x2a, 0xb3,
0xf0, 0x27, 0x0c, 0xba, 0xf7, 0xfa, 0x82, 0x3d, 0x14, 0x77, 0x1d,
0x86, 0x29, 0x79, 0x39, 0x77, 0x8a, 0xd5, 0x0e, 0x9d,
#if !defined(BORINGSSL_FIPS_BREAK_TLS_KDF)
0x32,
#else
0x00,
#endif
};
const uint8_t kTLSSecret[32] = {
0xbf, 0xe4, 0xb7, 0xe0, 0x26, 0x55, 0x5f, 0x6a, 0xdf, 0x5d, 0x27,
0xd6, 0x89, 0x99, 0x2a, 0xd6, 0xf7, 0x65, 0x66, 0x07, 0x4b, 0x55,
0x5f, 0x64, 0x55, 0xcd, 0xd5, 0x77, 0xa4, 0xc7, 0x09, 0x61,
};
const char kTLSLabel[] = "FIPS self test";
const uint8_t kTLSSeed1[16] = {
0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2,
0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65,
};
const uint8_t kTLSSeed2[16] = {
0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c,
0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81,
};
EVP_AEAD_CTX aead_ctx;
EVP_AEAD_CTX_zero(&aead_ctx);
@ -702,28 +660,48 @@ int BORINGSSL_self_test(void) {
uint8_t output[256];
// AES-CBC Encryption KAT
static const uint8_t kAESCBCEncPlaintext[32] = {
0x07, 0x86, 0x09, 0xa6, 0xc5, 0xac, 0x25, 0x44, 0x69, 0x9a, 0xdf,
0x68, 0x2f, 0xa3, 0x77, 0xf9, 0xbe, 0x8a, 0xb6, 0xae, 0xf5, 0x63,
0xe8, 0xc5, 0x6a, 0x36, 0xb8, 0x4f, 0x55, 0x7f, 0xad, 0xd3,
};
static const uint8_t kAESCBCEncCiphertext[sizeof(kAESCBCEncPlaintext)] = {
0x56, 0x46, 0xc1, 0x41, 0xf4, 0x13, 0xd6, 0xff, 0x62, 0x92, 0x41,
0x7a, 0x26, 0xc6, 0x86, 0xbd, 0x30, 0x5f, 0xb6, 0x57, 0xa7, 0xd2,
0x50, 0x3a, 0xc5, 0x5e, 0x8e, 0x93, 0x40, 0xf2, 0x10, 0xd8,
};
memcpy(aes_iv, kAESIV, sizeof(kAESIV));
if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
fprintf(stderr, "AES_set_encrypt_key failed.\n");
goto err;
}
AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv,
AES_ENCRYPT);
if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext),
"AES-CBC Encryption KAT")) {
AES_cbc_encrypt(kAESCBCEncPlaintext, output, sizeof(kAESCBCEncPlaintext),
&aes_key, aes_iv, AES_ENCRYPT);
if (!check_test(kAESCBCEncCiphertext, output, sizeof(kAESCBCEncCiphertext),
"AES-CBC-encrypt KAT")) {
goto err;
}
// AES-CBC Decryption KAT
static const uint8_t kAESCBCDecCiphertext[32] = {
0x34, 0x7a, 0xa5, 0xa0, 0x24, 0xb2, 0x82, 0x57, 0xb3, 0x65, 0x10,
0xbe, 0x58, 0x3d, 0x4f, 0x47, 0xad, 0xb7, 0xbb, 0xee, 0xdc, 0x60,
0x05, 0xbb, 0xbd, 0x0d, 0x0a, 0x9f, 0x06, 0xbb, 0x7b, 0x10,
};
static const uint8_t kAESCBCDecPlaintext[sizeof(kAESCBCDecCiphertext)] = {
0x51, 0xa7, 0xa0, 0x1f, 0x6b, 0x79, 0x6c, 0xcd, 0x48, 0x03, 0xa1,
0x41, 0xdc, 0x56, 0xa6, 0xc2, 0x16, 0xb5, 0xd1, 0xd3, 0xb7, 0x06,
0xb2, 0x25, 0x6f, 0xa6, 0xd0, 0xd2, 0x0e, 0x6f, 0x19, 0xb5,
};
memcpy(aes_iv, kAESIV, sizeof(kAESIV));
if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) {
fprintf(stderr, "AES_set_decrypt_key failed.\n");
goto err;
}
AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext),
AES_cbc_encrypt(kAESCBCDecCiphertext, output, sizeof(kAESCBCDecCiphertext),
&aes_key, aes_iv, AES_DECRYPT);
if (!check_test(kPlaintext, output, sizeof(kPlaintext),
"AES-CBC Decryption KAT")) {
if (!check_test(kAESCBCDecPlaintext, output, sizeof(kAESCBCDecPlaintext),
"AES-CBC-decrypt KAT")) {
goto err;
}
@ -737,29 +715,62 @@ int BORINGSSL_self_test(void) {
}
// AES-GCM Encryption KAT
static const uint8_t kAESGCMEncPlaintext[32] = {
0x8f, 0xcc, 0x40, 0x99, 0x80, 0x8e, 0x75, 0xca, 0xaf, 0xf5, 0x82,
0x89, 0x88, 0x48, 0xa8, 0x8d, 0x80, 0x8b, 0x55, 0xab, 0x4e, 0x93,
0x70, 0x79, 0x7d, 0x94, 0x0b, 0xe8, 0xcc, 0x1d, 0x78, 0x84,
};
static const uint8_t kAESGCMCiphertext[sizeof(kAESGCMEncPlaintext) + 16] = {
0x87, 0x7b, 0xd5, 0x8d, 0x96, 0x3e, 0x4b, 0xe6, 0x64, 0x94, 0x40, 0x2f,
0x61, 0x9b, 0x7e, 0x56, 0x52, 0x7d, 0xa4, 0x5a, 0xf9, 0xa6, 0xe2, 0xdb,
0x1c, 0x63, 0x2e, 0x97, 0x93, 0x0f, 0xfb, 0xed, 0xb5, 0x9e, 0x1c, 0x20,
0xb2, 0xb0, 0x58, 0xda, 0x48, 0x07, 0x2d, 0xbd, 0x96, 0x0d, 0x34, 0xc6,
};
if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce,
EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
kPlaintext, sizeof(kPlaintext), NULL, 0) ||
kAESGCMEncPlaintext, sizeof(kAESGCMEncPlaintext), NULL,
0) ||
!check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext),
"AES-GCM Encryption KAT")) {
"AES-GCM-encrypt KAT")) {
fprintf(stderr, "EVP_AEAD_CTX_seal for AES-128-GCM failed.\n");
goto err;
}
// AES-GCM Decryption KAT
static const uint8_t kAESGCMDecCiphertext[48] = {
0x35, 0xf3, 0x05, 0x8f, 0x87, 0x57, 0x60, 0xff, 0x09, 0xd3, 0x12, 0x0f,
0x70, 0xc4, 0xbc, 0x9e, 0xd7, 0xa8, 0x68, 0x72, 0xe1, 0x34, 0x52, 0x20,
0x21, 0x76, 0xf7, 0x37, 0x1a, 0xe0, 0x4f, 0xaa, 0xe1, 0xdd, 0x39, 0x19,
0x20, 0xf5, 0xd1, 0x39, 0x53, 0xd8, 0x96, 0x78, 0x59, 0x94, 0x82, 0x3c,
};
static const uint8_t kAESGCMDecPlaintext[sizeof(kAESGCMDecCiphertext) - 16] =
{
0x3d, 0x44, 0x90, 0x9b, 0x91, 0xe7, 0x5e, 0xd3, 0xc2, 0xb2, 0xd0,
0xa9, 0x99, 0x17, 0x6a, 0x45, 0x05, 0x5e, 0x99, 0x83, 0x56, 0x01,
0xc0, 0x82, 0x40, 0x81, 0xd2, 0x48, 0x45, 0xf2, 0xcc, 0xc3,
};
if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce,
EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()),
kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL,
0) ||
!check_test(kPlaintext, output, sizeof(kPlaintext),
"AES-GCM Decryption KAT")) {
fprintf(stderr, "EVP_AEAD_CTX_open for AES-128-GCM failed.\n");
kAESGCMDecCiphertext, sizeof(kAESGCMDecCiphertext),
NULL, 0) ||
!check_test(kAESGCMDecPlaintext, output, sizeof(kAESGCMDecPlaintext),
"AES-GCM-decrypt KAT")) {
fprintf(stderr,
"AES-GCM-decrypt KAT failed because EVP_AEAD_CTX_open failed.\n");
goto err;
}
// SHA-1 KAT
SHA1(kPlaintext, sizeof(kPlaintext), output);
if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1),
static const uint8_t kSHA1Input[16] = {
0x13, 0x2f, 0xd9, 0xba, 0xd5, 0xc1, 0x82, 0x62,
0x63, 0xba, 0xfb, 0xb6, 0x99, 0xf7, 0x07, 0xa5,
};
static const uint8_t kSHA1Digest[20] = {
0x94, 0x19, 0x55, 0x93, 0x0a, 0x58, 0x29, 0x38, 0xeb, 0xf5,
0x09, 0x11, 0x6d, 0x1a, 0xfd, 0x0f, 0x1e, 0x11, 0xe3, 0xcb,
};
SHA1(kSHA1Input, sizeof(kSHA1Input), output);
if (!check_test(kSHA1Digest, output, sizeof(kSHA1Digest),
"SHA-1 KAT")) {
goto err;
}
@ -771,18 +782,48 @@ int BORINGSSL_self_test(void) {
}
// DBRG KAT
static const uint8_t kDRBGEntropy[48] = {
0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, 0xe5,
0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, 0xbb, 0x4a,
0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, 0x40, 0xc2, 0xb5, 0x0b,
0xab, 0xe1, 0x4a, 0xae, 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27,
};
static const uint8_t kDRBGPersonalization[18] = "BCMPersonalization";
static const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD ";
static const uint8_t kDRBGOutput[64] = {
0x19, 0x1f, 0x2b, 0x49, 0x76, 0x85, 0xfd, 0x51, 0xb6, 0x56, 0xbc,
0x1c, 0x7d, 0xd5, 0xdd, 0x44, 0x76, 0xa3, 0x5e, 0x17, 0x9b, 0x8e,
0xb8, 0x98, 0x65, 0x12, 0xca, 0x35, 0x6c, 0xa0, 0x6f, 0xa0, 0x22,
0xe4, 0xf6, 0xd8, 0x43, 0xed, 0x4e, 0x2d, 0x97, 0x39, 0x43, 0x3b,
0x57, 0xfc, 0x23, 0x3f, 0x71, 0x0a, 0xe0, 0xed, 0xfe, 0xd5, 0xb8,
0x67, 0x7a, 0x00, 0x39, 0xb2, 0x6e, 0xa9, 0x25, 0x97,
};
static const uint8_t kDRBGEntropy2[48] = {
0xc7, 0x16, 0x1c, 0xa3, 0x6c, 0x23, 0x09, 0xb7, 0x16, 0xe9, 0x85, 0x9b,
0xb9, 0x6c, 0x6d, 0x49, 0xbd, 0xc8, 0x35, 0x21, 0x03, 0xa1, 0x8c, 0xd2,
0x4e, 0xf4, 0x2e, 0xc9, 0x7e, 0xf4, 0x6b, 0xf4, 0x46, 0xeb, 0x1a, 0x45,
0x76, 0xc1, 0x86, 0xe9, 0x35, 0x18, 0x03, 0x76, 0x3a, 0x79, 0x12, 0xfe,
};
static const uint8_t kDRBGReseedOutput[64] = {
0x00, 0xf2, 0x05, 0xaa, 0xfd, 0x11, 0x6c, 0x77, 0xbc, 0x81, 0x86,
0x99, 0xca, 0x51, 0xcf, 0x80, 0x15, 0x9f, 0x02, 0x9e, 0x0b, 0xcd,
0x26, 0xc8, 0x4b, 0x87, 0x8a, 0x15, 0x1a, 0xdd, 0xf2, 0xf3, 0xeb,
0x94, 0x0b, 0x08, 0xc8, 0xc9, 0x57, 0xa4, 0x0b, 0x4b, 0x0f, 0x13,
0xde, 0x7c, 0x0c, 0x6a, 0xac, 0x34, 0x4a, 0x9a, 0xf2, 0xd0, 0x83,
0x02, 0x05, 0x17, 0xc9, 0x81, 0x8f, 0x2a, 0x81, 0x92,
};
CTR_DRBG_STATE drbg;
if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization,
sizeof(kDRBGPersonalization)) ||
!CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD,
sizeof(kDRBGAD)) ||
!check_test(kDRBGOutput, output, sizeof(kDRBGOutput),
"DBRG Generate KAT") ||
"DRBG Generate KAT") ||
!CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) ||
!CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD,
sizeof(kDRBGAD)) ||
!check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput),
"DRBG Reseed KAT")) {
"DRBG-reseed KAT")) {
fprintf(stderr, "CTR-DRBG failed.\n");
goto err;
}
@ -795,12 +836,31 @@ int BORINGSSL_self_test(void) {
}
// TLS KDF KAT
static const uint8_t kTLSSecret[32] = {
0xab, 0xc3, 0x65, 0x7b, 0x09, 0x4c, 0x76, 0x28, 0xa0, 0xb2, 0x82,
0x99, 0x6f, 0xe7, 0x5a, 0x75, 0xf4, 0x98, 0x4f, 0xd9, 0x4d, 0x4e,
0xcc, 0x2f, 0xcf, 0x53, 0xa2, 0xc4, 0x69, 0xa3, 0xf7, 0x31,
};
static const char kTLSLabel[] = "FIPS self test";
static const uint8_t kTLSSeed1[16] = {
0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2,
0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65,
};
static const uint8_t kTLSSeed2[16] = {
0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c,
0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81,
};
static const uint8_t kTLSOutput[32] = {
0xe2, 0x1d, 0xd6, 0xc2, 0x68, 0xc7, 0x57, 0x03, 0x2c, 0x2c, 0xeb,
0xbb, 0xb8, 0xa9, 0x7d, 0xe9, 0xee, 0xe6, 0xc9, 0x47, 0x83, 0x0a,
0xbd, 0x11, 0x60, 0x5d, 0xd5, 0x2c, 0x47, 0xb6, 0x05, 0x88,
};
uint8_t tls_output[sizeof(kTLSOutput)];
if (!CRYPTO_tls1_prf(EVP_sha256(), tls_output, sizeof(tls_output), kTLSSecret,
sizeof(kTLSSecret), kTLSLabel, sizeof(kTLSLabel),
kTLSSeed1, sizeof(kTLSSeed1), kTLSSeed2,
sizeof(kTLSSeed2)) ||
!check_test(kTLSOutput, tls_output, sizeof(kTLSOutput), "TLS KDF KAT")) {
!check_test(kTLSOutput, tls_output, sizeof(kTLSOutput), "TLS-KDF KAT")) {
fprintf(stderr, "TLS KDF failed.\n");
goto err;
}

@ -0,0 +1,89 @@
// break-kat corrupts a known-answer-test input in a binary and writes the
// corrupted binary to stdout. This is used to demonstrate that the KATs in the
// binary notice the error.
package main
import (
"bytes"
"encoding/hex"
"flag"
"fmt"
"io/ioutil"
"os"
"sort"
)
var (
kats = map[string]string{
"HMAC-SHA-256": "dad91293dfcf2a7c8ecd13fe353fa75b",
"AES-CBC-encrypt": "078609a6c5ac2544699adf682fa377f9be8ab6aef563e8c56a36b84f557fadd3",
"AES-CBC-decrypt": "347aa5a024b28257b36510be583d4f47adb7bbeedc6005bbbd0d0a9f06bb7b10",
"AES-GCM-encrypt": "8fcc4099808e75caaff582898848a88d808b55ab4e9370797d940be8cc1d7884",
"AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c",
"DRBG": "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27",
"DRBG-reseed": "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe",
"SHA-1": "132fd9bad5c1826263bafbb699f707a5",
"SHA-256": "ff3b857da7236a2baa0f396b51522217",
"SHA-512": "212512f8d2ad8322781c6c4d69a9daa1",
"TLS-KDF": "abc3657b094c7628a0b282996fe75a75f4984fd94d4ecc2fcf53a2c469a3f731",
"RSA-sign": "d2b56e53306f720d7929d8708bf46f1c22300305582b115bedcac722d8aa5ab2",
"RSA-verify": "abe2cbc13d6bd39d48db5334ddbf8d070a93bdcb104e2cc5d0ee486ee295f6b31bda126c41890b98b73e70e6b65d82f95c663121755a90744c8d1c21148a1960be0eca446e9ff497f1345c537ef8119b9a4398e95c5c6de2b1c955905c5299d8ce7a3b6ab76380d9babdd15f610237e1f3f2aa1c1f1e770b62fbb596381b2ebdd77ecef9c90d4c92f7b6b05fed2936285fa94826e62055322a33b6f04c74ce69e5d8d737fb838b79d2d48e3daf71387531882531a95ac964d02ea413bf85952982bbc089527daff5b845c9a0f4d14ef1956d9c3acae882d12da66da0f35794f5ee32232333517db9315232a183b991654dbea41615345c885325926744a53915",
"ECDSA-sign": "1e35930be860d0942ca7bbd6f6ded87f157e4de24f81ed4b875c0e018e89a81f",
"ECDSA-verify": "6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c2d36e5799790bfbe2183d33e96f3c51f6a232f2a24488c8e5f64c37ea2cf0529",
"Z-computation": "e7604491269afb5b102d6ea52cb59feb70aede6ce3bfb3e0105485abd861d77b",
"FFDH": "a14f8ad36be37b18b8f35864392f150ab7ee22c47e1870052a3f17918274af18aaeaf4cf6aacfde96c9d586eb7ebaff6b03fe3b79a8e2ff9dd6df34caaf2ac70fd3771d026b41a561ee90e4337d0575f8a0bd160c868e7e3cef88aa1d88448b1e4742ba11480a9f8a8b737347c408d74a7d57598c48875629df0c85327a124ddec1ad50cd597a985588434ce19c6f044a1696b5f244b899b7e77d4f6f20213ae8eb15d37eb8e67e6c8bdbc4fd6e17426283da96f23a897b210058c7c70fb126a5bf606dbeb1a6d5cca04184c4e95c2e8a70f50f5c1eabd066bd79c180456316ac02d366eb3b0e7ba82fb70dcbd737ca55734579dd250fffa8e0584be99d32b35",
}
listTests = flag.Bool("list-tests", false, "List known test values and exit")
)
func main() {
flag.Parse()
if *listTests {
for _, kat := range sortedKATs() {
fmt.Println(kat)
}
os.Exit(0)
}
if flag.NArg() != 2 || kats[flag.Arg(1)] == "" {
fmt.Fprintln(os.Stderr, "Usage: break-kat <binary path> <test to break> > output")
fmt.Fprintln(os.Stderr, "Possible values for <test to break>:")
for _, kat := range sortedKATs() {
fmt.Fprintln(os.Stderr, " ", kat)
}
os.Exit(1)
}
inPath := flag.Arg(0)
test := flag.Arg(1)
testInputValue, err := hex.DecodeString(kats[test])
if err != nil {
panic("invalid kat data: " + err.Error())
}
binaryContents, err := ioutil.ReadFile(inPath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
i := bytes.Index(binaryContents, testInputValue)
if i < 0 {
fmt.Fprintln(os.Stderr, "Expected test input value was not found in binary.")
os.Exit(3)
}
binaryContents[i] ^= 1
os.Stdout.Write(binaryContents)
}
func sortedKATs() []string {
var ret []string
for kat := range kats {
ret = append(ret, kat)
}
sort.Strings(ret)
return ret
}

@ -1,117 +0,0 @@
# Copyright (c) 2019, Google Inc.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
# This script exists to exercise breaking each of the FIPS tests on an Android
# device. Since, on Android, BoringCrypto exists in both 32- and 64-bit
# versions, the first argument must be either "32" or "64" to select which is
# being tested. The Android source tree must have been setup (with "lunch") for
# a matching build configuration before using this script to build the
# binaries. (Although it'll fail non-silently if there's a mismatch.)
#
# Since each test needs the FIPS module to be compiled differently, and that
# can take a long time, this script is run twice: once with "build" as the
# second argument to run the builds, and then with "run" as the second argument
# to run each test.
#
# Run it with /bin/bash, not /bin/sh, otherwise "read" may fail.
#
# In order to reconfigure the build for each test, it needs to set a define. It
# does so by rewriting a template in external/boringssl/Android.bp and you must
# add the template value before doing the builds. To do so, insert
# -DBORINGSSL_FIPS_BREAK_XXX=1 in the cflags list for the module, probably by
# putting it in the "boringssl_flags" stanza.
set -x
set -e
if [ ! -f external/boringssl/Android.bp ]; then
echo "Must be run from the top-level of an Android source tree."
exit 1
fi
. build/envsetup.sh
TESTS="NONE ECDSA_PWCT CRNG RSA_PWCT AES_CBC AES_GCM DES SHA_1 SHA_256 SHA_512 RSA_SIG DRBG ECDSA_SIG Z_COMPUTATION TLS_KDF FFC_DH"
if [ "x$1" = "x32" ]; then
lib="lib"
bits="32"
elif [ "x$1" = "x64" ] ; then
lib="lib64"
bits="64"
else
echo "First argument must be 32 or 64"
exit 1
fi
if [ "x$2" = "xbuild" ]; then
if ! grep -q DBORINGSSL_FIPS_BREAK_XXX=1 external/boringssl/Android.bp; then
echo "Missing DBORINGSSL_FIPS_BREAK_XXX in external/boringssl/Android.bp. Edit the file and insert -DBORINGSSL_FIPS_BREAK_XXX=1 in the cflags for the FIPS module"
exit 1
fi
printf "\\x1b[1mBuilding modules\\x1b[0m\n"
for test in $TESTS; do
printf "\\x1b[1mBuilding for ${test}\\x1b[0m\n"
cp external/boringssl/Android.bp external/boringssl/Android.bp.orig
sed -i -e "s/DBORINGSSL_FIPS_BREAK_XXX/DBORINGSSL_FIPS_BREAK_${test}/" external/boringssl/Android.bp
m test_fips
dir=test-${bits}-${test}
rm -Rf $dir
mkdir $dir
cp ${ANDROID_PRODUCT_OUT}/system/${lib}/libcrypto.so $dir
cp ${ANDROID_PRODUCT_OUT}/system/bin/test_fips $dir
if [ $bits = "32" ] ; then
if ! file ${dir}/test_fips | grep -q "32-bit" ; then
echo "32-bit build requested but binaries don't appear to be 32-bit:"
file ${dir}/test_fips
exit 1
fi
else
if ! file ${dir}/test_fips | grep -q "64-bit" ; then
echo "64-bit build requested but binaries don't appear to be 64-bit:"
file ${dir}/test_fips
exit 1
fi
fi
cp external/boringssl/Android.bp.orig external/boringssl/Android.bp
done
elif [ "x$2" = "xrun" ]; then
printf "\\x1b[1mTesting\\x1b[0m\n"
for test in $TESTS; do
dir=test-${bits}-${test}
if [ ! '(' -d ${dir} -a -f ${dir}/test_fips -a -f ${dir}/libcrypto.so ')' ] ; then
echo "Build directory ${dir} is missing or is missing files"
exit 1
fi
adb push ${dir}/* /data/local/tmp
printf "\\x1b[1mTesting ${test}\\x1b[0m\n"
adb shell -n -t -x LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/test_fips
read
done
printf "\\x1b[1mTesting integrity}\\x1b[0m\n"
src=test-${bits}-NONE
dir=test-${bits}-INT
rm -Rf $dir
mkdir $dir
go run external/boringssl/src/util/fipstools/break-hash.go ${src}/libcrypto.so ${dir}/libcrypto.so
cp ${src}/test_fips $dir
adb push ${dir}/* /data/local/tmp
adb shell -n -t -x LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/test_fips
read
else
echo "Second argument must be build or run"
exit 1
fi

@ -1,53 +0,0 @@
# Copyright (c) 2018, Google Inc.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
# This script exists to exercise breaking each of the FIPS tests. It builds
# BoringSSL differently for each test and that can take a long time. Thus it's
# run twice: once, from a BoringSSL source tree, with "build" as the sole
# argument to run the builds, and then (from the same location) with no
# arguments to run each script.
#
# Run it with /bin/bash, not /bin/sh, otherwise "read" may fail.
set -x
TESTS="NONE ECDSA_PWCT CRNG RSA_PWCT AES_CBC AES_GCM DES SHA_1 SHA_256 SHA_512 HMAC_SHA_256 RSA_SIG DRBG ECDSA_SIG Z_COMPUTATION TLS_KDF FFC_DH"
if [ "x$1" = "xbuild" ]; then
for test in $TESTS; do
rm -Rf build-$test
mkdir build-$test
pushd build-$test
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchain -DFIPS=1 -DFIPS_BREAK_TEST=${test} -DCMAKE_BUILD_TYPE=Release ..
ninja test_fips
popd
done
exit 0
fi
for test in $TESTS; do
pushd build-$test
printf "\n\n\\x1b[1m$test\\x1b[0m\n"
./util/fipstools/cavp/test_fips
echo "Waiting for keypress..."
read
popd
done
pushd build-NONE
printf "\\x1b[1mIntegrity\\x1b[0m\n"
go run ../util/fipstools/break-hash.go ./util/fipstools/cavp/test_fips ./util/fipstools/cavp/test_fips_broken
./util/fipstools/cavp/test_fips_broken
popd

@ -0,0 +1,40 @@
# Copyright (c) 2022, Google Inc.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# This script attempts to break each of the known KATs and checks that doing so
# seems to work and at least mentions the correct KAT in the output.
set -x
set -e
TEST_FIPS_BIN="build/util/fipstools/cavp/test_fips"
if [ ! -f $TEST_FIPS_BIN ]; then
echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a"
echo "BoringSSL checkout and ensure that ./build-fips-break-test-binaries.sh"
echo "has been run first."
exit 1
fi
KATS=$(go run util/fipstools/break-kat.go --list-tests)
for kat in $KATS; do
go run util/fipstools/break-kat.go $TEST_FIPS_BIN $kat > break-kat-bin
chmod u+x ./break-kat-bin
if ! (./break-kat-bin 2>&1 || true) | egrep -q "^$kat[^a-zA-Z0-9]"; then
echo "Failure for $kat did not mention that name in the output"
exit 1
fi
rm ./break-kat-bin
done
Loading…
Cancel
Save