Handle nullptr arguments to FIPS key generation functions FIPS needs these functions to handle nullptr arguments without crashing. Change-Id: Ic3f2f4d988b80e621a990c28423e3323ea526241 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/77308 Reviewed-by: Bob Beck <bbe@google.com> Auto-Submit: Adam Langley <agl@google.com> Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/fipsmodule/bcm_interface.h b/crypto/fipsmodule/bcm_interface.h index c22ef77..2f53777 100644 --- a/crypto/fipsmodule/bcm_interface.h +++ b/crypto/fipsmodule/bcm_interface.h
@@ -713,14 +713,22 @@ // SLH-DSA-SHA2-128s signature. #define BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856 -// SLHDSA_SHA2_128S_generate_key_from_seed generates an SLH-DSA-SHA2-128s key -// pair from a 48-byte seed and writes the result to |out_public_key| and +// BCM_slhdsa_sha2_128s_generate_key_from_seed generates an SLH-DSA-SHA2-128s +// key pair from a 48-byte seed and writes the result to |out_public_key| and // |out_secret_key|. OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed( uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]); +// BCM_slhdsa_sha2_128s_generate_key_from_seed_fips does the same thing as +// `BCM_slhdsa_sha2_128s_generate_key_from_seed` but implements the required +// second check before generating a key by testing for nullptr arguments. +OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_generate_key_from_seed_fips( + uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]); + // BCM_slhdsa_sha2_128s_sign_internal acts like |SLHDSA_SHA2_128S_sign| but // accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of // the private key) to generate deterministic signatures. It also takes the @@ -748,6 +756,10 @@ uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); +OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_generate_key_fips( + uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); + OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_public_from_private( uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
diff --git a/crypto/fipsmodule/mldsa/mldsa.cc.inc b/crypto/fipsmodule/mldsa/mldsa.cc.inc index 52f5836..e89d87c 100644 --- a/crypto/fipsmodule/mldsa/mldsa.cc.inc +++ b/crypto/fipsmodule/mldsa/mldsa.cc.inc
@@ -2032,6 +2032,9 @@ uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES], uint8_t out_seed[BCM_MLDSA_SEED_BYTES], struct BCM_mldsa65_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } if (BCM_mldsa65_generate_key(out_encoded_public_key, out_seed, out_private_key) == bcm_status::failure) { return bcm_status::failure; @@ -2043,6 +2046,9 @@ uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES], struct BCM_mldsa65_private_key *out_private_key, const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } if (BCM_mldsa65_generate_key_external_entropy(out_encoded_public_key, out_private_key, entropy) == bcm_status::failure) { @@ -2188,6 +2194,9 @@ uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES], uint8_t out_seed[BCM_MLDSA_SEED_BYTES], struct BCM_mldsa87_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } if (BCM_mldsa87_generate_key(out_encoded_public_key, out_seed, out_private_key) == bcm_status::failure) { return bcm_status::failure; @@ -2199,6 +2208,9 @@ uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES], struct BCM_mldsa87_private_key *out_private_key, const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } if (BCM_mldsa87_generate_key_external_entropy(out_encoded_public_key, out_private_key, entropy) == bcm_status::failure) {
diff --git a/crypto/fipsmodule/mlkem/mlkem.cc.inc b/crypto/fipsmodule/mlkem/mlkem.cc.inc index 265b0ca..c3773cc 100644 --- a/crypto/fipsmodule/mlkem/mlkem.cc.inc +++ b/crypto/fipsmodule/mlkem/mlkem.cc.inc
@@ -1102,6 +1102,9 @@ uint8_t out_encoded_public_key[BCM_MLKEM768_PUBLIC_KEY_BYTES], uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES], struct BCM_mlkem768_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } BCM_mlkem768_generate_key(out_encoded_public_key, optional_out_seed, out_private_key); return BCM_mlkem768_check_fips(out_private_key); @@ -1163,6 +1166,9 @@ uint8_t out_encoded_public_key[BCM_MLKEM1024_PUBLIC_KEY_BYTES], uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES], struct BCM_mlkem1024_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } BCM_mlkem1024_generate_key(out_encoded_public_key, optional_out_seed, out_private_key); return BCM_mlkem1024_check_fips(out_private_key);
diff --git a/crypto/fipsmodule/slhdsa/slhdsa.cc.inc b/crypto/fipsmodule/slhdsa/slhdsa.cc.inc index e8f09b9..b3e5644 100644 --- a/crypto/fipsmodule/slhdsa/slhdsa.cc.inc +++ b/crypto/fipsmodule/slhdsa/slhdsa.cc.inc
@@ -86,7 +86,7 @@ abort(); } - return bcm_infallible::approved; + return bcm_infallible::not_approved; } // Note that this overreads by a byte. This is fine in the context that it's @@ -294,6 +294,18 @@ seed); } +bcm_status BCM_slhdsa_sha2_128s_generate_key_from_seed_fips( + uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], + const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]) { + if (out_public_key == nullptr || out_secret_key == nullptr) { + return bcm_status::failure; + } + BCM_slhdsa_sha2_128s_generate_key_from_seed(out_public_key, out_secret_key, + seed); + return bcm_status::approved; +} + bcm_infallible BCM_slhdsa_sha2_128s_generate_key( uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) { @@ -303,6 +315,16 @@ out_private_key, seed); } +bcm_status BCM_slhdsa_sha2_128s_generate_key_fips( + uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], + uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) { + if (out_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } + BCM_slhdsa_sha2_128s_generate_key(out_public_key, out_private_key); + return bcm_status::approved; +} + bcm_infallible BCM_slhdsa_sha2_128s_public_from_private( uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
diff --git a/crypto/mldsa/mldsa_test.cc b/crypto/mldsa/mldsa_test.cc index cc1d75c..112b444 100644 --- a/crypto/mldsa/mldsa_test.cc +++ b/crypto/mldsa/mldsa_test.cc
@@ -547,4 +547,18 @@ bcm_status::approved); } +TEST(MLDSATest, NullptrArgumentsToCreate) { + // For FIPS reasons, this should fail rather than crash. + ASSERT_EQ(BCM_mldsa65_generate_key_fips(nullptr, nullptr, nullptr), + bcm_status::failure); + ASSERT_EQ(BCM_mldsa87_generate_key_fips(nullptr, nullptr, nullptr), + bcm_status::failure); + ASSERT_EQ( + BCM_mldsa65_generate_key_external_entropy_fips(nullptr, nullptr, nullptr), + bcm_status::failure); + ASSERT_EQ( + BCM_mldsa87_generate_key_external_entropy_fips(nullptr, nullptr, nullptr), + bcm_status::failure); +} + } // namespace
diff --git a/crypto/mlkem/mlkem_test.cc b/crypto/mlkem/mlkem_test.cc index 213991a..5b4d686 100644 --- a/crypto/mlkem/mlkem_test.cc +++ b/crypto/mlkem/mlkem_test.cc
@@ -544,4 +544,12 @@ bcm_status::approved); } +TEST(MLKEMTest, NullptrArgumentsToCreate) { + // For FIPS reasons, this should fail rather than crash. + ASSERT_EQ(BCM_mlkem768_generate_key_fips(nullptr, nullptr, nullptr), + bcm_status::failure); + ASSERT_EQ(BCM_mlkem1024_generate_key_fips(nullptr, nullptr, nullptr), + bcm_status::failure); +} + } // namespace
diff --git a/crypto/slhdsa/slhdsa_test.cc b/crypto/slhdsa/slhdsa_test.cc index d6a7011..c00a2f9 100644 --- a/crypto/slhdsa/slhdsa_test.cc +++ b/crypto/slhdsa/slhdsa_test.cc
@@ -222,4 +222,13 @@ TEST(SLHDSATest, Self) { boringssl_self_test_slhdsa(); } +TEST(SLHDSATest, NullptrArgumentsToCreate) { + // For FIPS reasons, this should fail rather than crash. + ASSERT_EQ(BCM_slhdsa_sha2_128s_generate_key_fips(nullptr, nullptr), + bcm_status::failure); + ASSERT_EQ(BCM_slhdsa_sha2_128s_generate_key_from_seed_fips(nullptr, nullptr, + nullptr), + bcm_status::failure); +} + } // namespace