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)) {