Don't draw entropy during FIPS power-on tests.
Change-Id: I8512c6bfb62f1a83afc8f763d681bf5db3b4ceae
Reviewed-on: https://boringssl-review.googlesource.com/17144
Commit-Queue: Adam Langley <alangley@gmail.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index 76fbae3..c6ea796 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -245,8 +245,7 @@
!set_bignum(&rsa->q, kQ, sizeof(kQ)) ||
!set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) ||
!set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) ||
- !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP)) ||
- !RSA_check_fips(rsa)) {
+ !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) {
RSA_free(rsa);
return NULL;
}
@@ -277,8 +276,7 @@
BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL);
if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL ||
!EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) ||
- !EC_KEY_set_private_key(ec_key, d) ||
- !EC_KEY_check_fips(ec_key)) {
+ !EC_KEY_set_private_key(ec_key, d)) {
EC_KEY_free(ec_key);
ec_key = NULL;
}
@@ -460,6 +458,21 @@
0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b,
0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4,
};
+ 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
+ };
+ 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,
+ };
AES_KEY aes_key;
uint8_t aes_iv[16];
@@ -572,6 +585,11 @@
/* 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, kPlaintextSHA256, sizeof(kPlaintextSHA256), output,
&sig_len, rsa_key) ||
!check_test(kRSASignature, output, sizeof(kRSASignature),
@@ -595,15 +613,28 @@
}
/* ECDSA Sign/Verify PWCT */
+
+ /* The 'k' value for ECDSA is fixed to avoid an entropy draw. */
+ ec_key->fixed_k = BN_new();
+ if (ec_key->fixed_k == NULL ||
+ !BN_set_word(ec_key->fixed_k, 42)) {
+ printf("Out of memory\n");
+ goto err;
+ }
+
ECDSA_SIG *sig =
ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key);
-#if defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG)
- sig->r->d[0] = ~sig->r->d[0];
-#endif
+
+ uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)];
+ uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)];
if (sig == NULL ||
- !ECDSA_do_verify(kPlaintextSHA256, sizeof(kPlaintextSHA256), sig,
- ec_key)) {
- printf("ECDSA Sign/Verify power-on PWCT failed.\n");
+ 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")) {
+ printf("ECDSA KAT failed.\n");
goto err;
}
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
index 67b92a7..acabb06 100644
--- a/crypto/fipsmodule/ec/ec_key.c
+++ b/crypto/fipsmodule/ec/ec_key.c
@@ -152,6 +152,7 @@
EC_GROUP_free(r->group);
EC_POINT_free(r->pub_key);
BN_clear_free(r->priv_key);
+ BN_free(r->fixed_k);
CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data);
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h
index b86a0f9..d14fec6 100644
--- a/crypto/fipsmodule/ec/internal.h
+++ b/crypto/fipsmodule/ec/internal.h
@@ -235,6 +235,10 @@
EC_POINT *pub_key;
BIGNUM *priv_key;
+ /* fixed_k may contain a specific value of 'k', to be used in ECDSA signing.
+ * This is only for the FIPS power-on tests. */
+ BIGNUM *fixed_k;
+
unsigned int enc_flag;
point_conversion_form_t conv_form;
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c
index 37f8223..9e719f2 100644
--- a/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -262,7 +262,11 @@
/* If possible, we'll include the private key and message digest in the k
* generation. The |digest| argument is only empty if |ECDSA_sign_setup| is
* being used. */
- if (digest_len > 0) {
+ if (eckey->fixed_k != NULL) {
+ if (!BN_copy(k, eckey->fixed_k)) {
+ goto err;
+ }
+ } else if (digest_len > 0) {
do {
if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
digest, digest_len, ctx)) {