Add various function calls to test_fips.
test_fips probably needs to exercise everything that we have self-tests
for.
(The following change will eliminate the duplication of the code to
create the FFDH group. For reasons, that can't be done in this change.)
Change-Id: Ia72064db77381e7cf396a34b4723b2607f26f00b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/45404
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/dh/dh.c b/crypto/fipsmodule/dh/dh.c
index 0d437ee..2d0af21 100644
--- a/crypto/fipsmodule/dh/dh.c
+++ b/crypto/fipsmodule/dh/dh.c
@@ -403,3 +403,53 @@
CRYPTO_refcount_inc(&dh->references);
return 1;
}
+
+DH *DH_get_rfc7919_2048(void) {
+ // This is the prime from https://tools.ietf.org/html/rfc7919#appendix-A.1,
+ // which is specifically approved for FIPS in appendix D of SP 800-56Ar3.
+ static const BN_ULONG kFFDHE2048Data[] = {
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x886b4238, 0x61285c97),
+ TOBN(0xc6f34a26, 0xc1b2effa), TOBN(0xc58ef183, 0x7d1683b2),
+ TOBN(0x3bb5fcbc, 0x2ec22005), TOBN(0xc3fe3b1b, 0x4c6fad73),
+ TOBN(0x8e4f1232, 0xeef28183), TOBN(0x9172fe9c, 0xe98583ff),
+ TOBN(0xc03404cd, 0x28342f61), TOBN(0x9e02fce1, 0xcdf7e2ec),
+ TOBN(0x0b07a7c8, 0xee0a6d70), TOBN(0xae56ede7, 0x6372bb19),
+ TOBN(0x1d4f42a3, 0xde394df4), TOBN(0xb96adab7, 0x60d7f468),
+ TOBN(0xd108a94b, 0xb2c8e3fb), TOBN(0xbc0ab182, 0xb324fb61),
+ TOBN(0x30acca4f, 0x483a797a), TOBN(0x1df158a1, 0x36ade735),
+ TOBN(0xe2a689da, 0xf3efe872), TOBN(0x984f0c70, 0xe0e68b77),
+ TOBN(0xb557135e, 0x7f57c935), TOBN(0x85636555, 0x3ded1af3),
+ TOBN(0x2433f51f, 0x5f066ed0), TOBN(0xd3df1ed5, 0xd5fd6561),
+ TOBN(0xf681b202, 0xaec4617a), TOBN(0x7d2fe363, 0x630c75d8),
+ TOBN(0xcc939dce, 0x249b3ef9), TOBN(0xa9e13641, 0x146433fb),
+ TOBN(0xd8b9c583, 0xce2d3695), TOBN(0xafdc5620, 0x273d3cf1),
+ TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff),
+ };
+
+ BIGNUM *const ffdhe2048_p = BN_new();
+ BIGNUM *const ffdhe2048_q = BN_new();
+ BIGNUM *const ffdhe2048_g = BN_new();
+ DH *const dh = DH_new();
+
+ if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !dh) {
+ goto err;
+ }
+
+ bn_set_static_words(ffdhe2048_p, kFFDHE2048Data,
+ OPENSSL_ARRAY_SIZE(kFFDHE2048Data));
+
+ if (!BN_rshift1(ffdhe2048_q, ffdhe2048_p) ||
+ !BN_set_word(ffdhe2048_g, 2) ||
+ !DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) {
+ goto err;
+ }
+
+ return dh;
+
+ err:
+ BN_free(ffdhe2048_p);
+ BN_free(ffdhe2048_q);
+ BN_free(ffdhe2048_g);
+ DH_free(dh);
+ return NULL;
+}
diff --git a/crypto/fipsmodule/self_check/self_check.c b/crypto/fipsmodule/self_check/self_check.c
index b5ccba9..638500b 100644
--- a/crypto/fipsmodule/self_check/self_check.c
+++ b/crypto/fipsmodule/self_check/self_check.c
@@ -248,26 +248,15 @@
}
static DH *self_test_dh(void) {
- // This is the prime from https://tools.ietf.org/html/rfc7919#appendix-A.1,
- // which is specifically approved for FIPS in appendix D of SP 800-56Ar3.
- static const BN_ULONG kFFDHE2048Data[] = {
- TOBN(0xffffffff, 0xffffffff), TOBN(0x886b4238, 0x61285c97),
- TOBN(0xc6f34a26, 0xc1b2effa), TOBN(0xc58ef183, 0x7d1683b2),
- TOBN(0x3bb5fcbc, 0x2ec22005), TOBN(0xc3fe3b1b, 0x4c6fad73),
- TOBN(0x8e4f1232, 0xeef28183), TOBN(0x9172fe9c, 0xe98583ff),
- TOBN(0xc03404cd, 0x28342f61), TOBN(0x9e02fce1, 0xcdf7e2ec),
- TOBN(0x0b07a7c8, 0xee0a6d70), TOBN(0xae56ede7, 0x6372bb19),
- TOBN(0x1d4f42a3, 0xde394df4), TOBN(0xb96adab7, 0x60d7f468),
- TOBN(0xd108a94b, 0xb2c8e3fb), TOBN(0xbc0ab182, 0xb324fb61),
- TOBN(0x30acca4f, 0x483a797a), TOBN(0x1df158a1, 0x36ade735),
- TOBN(0xe2a689da, 0xf3efe872), TOBN(0x984f0c70, 0xe0e68b77),
- TOBN(0xb557135e, 0x7f57c935), TOBN(0x85636555, 0x3ded1af3),
- TOBN(0x2433f51f, 0x5f066ed0), TOBN(0xd3df1ed5, 0xd5fd6561),
- TOBN(0xf681b202, 0xaec4617a), TOBN(0x7d2fe363, 0x630c75d8),
- TOBN(0xcc939dce, 0x249b3ef9), TOBN(0xa9e13641, 0x146433fb),
- TOBN(0xd8b9c583, 0xce2d3695), TOBN(0xafdc5620, 0x273d3cf1),
- TOBN(0xadf85458, 0xa2bb4a9a), TOBN(0xffffffff, 0xffffffff),
- };
+ DH *dh = DH_get_rfc7919_2048();
+ if (!dh) {
+ return NULL;
+ }
+
+ BIGNUM *priv = BN_new();
+ if (!priv) {
+ goto err;
+ }
// kFFDHE2048PrivateKeyData is a 225-bit value. (225 because that's the
// minimum private key size in
@@ -279,41 +268,16 @@
TOBN(0x00000001, 0x91173f2a),
};
- BIGNUM *const ffdhe2048_p = BN_new();
- BIGNUM *const ffdhe2048_q = BN_new();
- BIGNUM *const ffdhe2048_g = BN_new();
- BIGNUM *ffdhe2048_priv = BN_new();
- DH *const dh = DH_new();
-
- if (!ffdhe2048_p || !ffdhe2048_q || !ffdhe2048_g || !ffdhe2048_priv || !dh) {
- goto err;
- }
-
- bn_set_static_words(ffdhe2048_p, kFFDHE2048Data,
- OPENSSL_ARRAY_SIZE(kFFDHE2048Data));
- bn_set_static_words(ffdhe2048_priv, kFFDHE2048PrivateKeyData,
+ bn_set_static_words(priv, kFFDHE2048PrivateKeyData,
OPENSSL_ARRAY_SIZE(kFFDHE2048PrivateKeyData));
- if (!BN_copy(ffdhe2048_q, ffdhe2048_p) ||
- !BN_sub_word(ffdhe2048_q, 1) ||
- BN_div_word(ffdhe2048_q, 2) != 0 ||
- !BN_set_word(ffdhe2048_g, 2) ||
- !DH_set0_key(dh, NULL, ffdhe2048_priv)) {
+ if (!DH_set0_key(dh, NULL, priv)) {
goto err;
}
-
- ffdhe2048_priv = NULL;
- if (!DH_set0_pqg(dh, ffdhe2048_p, ffdhe2048_q, ffdhe2048_g)) {
- goto err;
- }
-
return dh;
err:
- BN_free(ffdhe2048_p);
- BN_free(ffdhe2048_q);
- BN_free(ffdhe2048_g);
- BN_free(ffdhe2048_priv);
+ BN_free(priv);
DH_free(dh);
return NULL;
}
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index a4e2e71..9a86e9e 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -139,6 +139,11 @@
// and returned. It returns NULL on allocation failure.
OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret);
+// DH_get_rfc7919_2048 returns the group `ffdhe2048` from
+// https://tools.ietf.org/html/rfc7919#appendix-A.1. It returns NULL if out
+// of memory.
+OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void);
+
// Parameter generation.
diff --git a/util/fipstools/cavp/test_fips.c b/util/fipstools/cavp/test_fips.c
index 66359c5..dd82d65 100644
--- a/util/fipstools/cavp/test_fips.c
+++ b/util/fipstools/cavp/test_fips.c
@@ -22,6 +22,7 @@
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/des.h>
+#include <openssl/dh.h>
#include <openssl/ecdsa.h>
#include <openssl/ec_key.h>
#include <openssl/hmac.h>
@@ -30,6 +31,7 @@
#include <openssl/sha.h>
#include "../crypto/fipsmodule/rand/internal.h"
+#include "../crypto/fipsmodule/tls/internal.h"
#include "../crypto/internal.h"
@@ -217,6 +219,24 @@
goto err;
}
+ /* Primitive Z Computation */
+ const EC_GROUP *const ec_group = EC_KEY_get0_group(ec_key);
+ EC_POINT *z_point = EC_POINT_new(ec_group);
+ uint8_t z_result[65];
+ printf("About to compute key-agreement Z with P-256:\n");
+ if (!EC_POINT_mul(ec_group, z_point, NULL, EC_KEY_get0_public_key(ec_key),
+ EC_KEY_get0_private_key(ec_key), NULL) ||
+ EC_POINT_point2oct(ec_group, z_point, POINT_CONVERSION_UNCOMPRESSED,
+ z_result, sizeof(z_result),
+ NULL) != sizeof(z_result)) {
+ fprintf(stderr, "EC_POINT_mul failed.\n");
+ goto err;
+ }
+ EC_POINT_free(z_point);
+
+ printf(" got ");
+ hexdump(z_result, sizeof(z_result));
+
/* ECDSA Sign/Verify PWCT */
printf("About to ECDSA sign ");
hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256));
@@ -250,6 +270,36 @@
hexdump(output, sizeof(output));
CTR_DRBG_clear(&drbg);
+ /* TLS KDF */
+ printf("About to run TLS KDF\n");
+ uint8_t tls_output[32];
+ if (!CRYPTO_tls1_prf(EVP_sha256(), tls_output, sizeof(tls_output), kAESKey,
+ sizeof(kAESKey), "foo", 3, kPlaintextSHA256,
+ sizeof(kPlaintextSHA256), kPlaintextSHA256,
+ sizeof(kPlaintextSHA256))) {
+ fprintf(stderr, "TLS KDF failed.\n");
+ goto err;
+ }
+ printf(" got ");
+ hexdump(tls_output, sizeof(tls_output));
+
+ /* FFDH */
+ printf("About to compute FFDH key-agreement:\n");
+ DH *dh = DH_get_rfc7919_2048();
+ uint8_t dh_result[2048/8];
+ if (!dh ||
+ !DH_generate_key(dh) ||
+ sizeof(dh_result) != DH_size(dh) ||
+ DH_compute_key_padded(dh_result, DH_get0_pub_key(dh), dh) !=
+ sizeof(dh_result)) {
+ fprintf(stderr, "FFDH failed.\n");
+ goto err;
+ }
+ DH_free(dh);
+
+ printf(" got ");
+ hexdump(dh_result, sizeof(dh_result));
+
printf("PASS\n");
return 0;