Move HKDF into the FIPS module. Change-Id: I7c5b0a24c26b83779cf889d890e2c18ae13187c3 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58725 Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index b45256c..cdb5ddc 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt
@@ -168,7 +168,6 @@ evp/scrypt.c evp/sign.c ex_data.c - hkdf/hkdf.c hpke/hpke.c hrss/hrss.c kyber/keccak.c @@ -390,13 +389,13 @@ fipsmodule/ec/ec_test.cc fipsmodule/ec/p256-nistz_test.cc fipsmodule/ecdsa/ecdsa_test.cc + fipsmodule/hkdf/hkdf_test.cc fipsmodule/md5/md5_test.cc fipsmodule/modes/gcm_test.cc fipsmodule/rand/ctrdrbg_test.cc fipsmodule/rand/fork_detect_test.cc fipsmodule/service_indicator/service_indicator_test.cc fipsmodule/sha/sha_test.cc - hkdf/hkdf_test.cc hpke/hpke_test.cc hmac_extra/hmac_test.cc hrss/hrss_test.cc
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c index e2e4d90..8231eee 100644 --- a/crypto/fipsmodule/bcm.c +++ b/crypto/fipsmodule/bcm.c
@@ -80,6 +80,7 @@ #include "ec/simple_mul.c" #include "ec/util.c" #include "ec/wnaf.c" +#include "hkdf/hkdf.c" #include "hmac/hmac.c" #include "md4/md4.c" #include "md5/md5.c"
diff --git a/crypto/hkdf/hkdf.c b/crypto/fipsmodule/hkdf/hkdf.c similarity index 98% rename from crypto/hkdf/hkdf.c rename to crypto/fipsmodule/hkdf/hkdf.c index 23b60af..fa1cc72 100644 --- a/crypto/hkdf/hkdf.c +++ b/crypto/fipsmodule/hkdf/hkdf.c
@@ -20,7 +20,7 @@ #include <openssl/err.h> #include <openssl/hmac.h> -#include "../internal.h" +#include "../../internal.h" int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
diff --git a/crypto/hkdf/hkdf_test.cc b/crypto/fipsmodule/hkdf/hkdf_test.cc similarity index 98% rename from crypto/hkdf/hkdf_test.cc rename to crypto/fipsmodule/hkdf/hkdf_test.cc index 8aad6c8..dd7dd58 100644 --- a/crypto/hkdf/hkdf_test.cc +++ b/crypto/fipsmodule/hkdf/hkdf_test.cc
@@ -20,9 +20,9 @@ #include <gtest/gtest.h> -#include "../test/file_test.h" -#include "../test/test_util.h" -#include "../test/wycheproof_util.h" +#include "../../test/file_test.h" +#include "../../test/test_util.h" +#include "../../test/wycheproof_util.h" struct HKDFTestVector {
diff --git a/crypto/fipsmodule/self_check/self_check.c b/crypto/fipsmodule/self_check/self_check.c index 08500e5..8dcc415 100644 --- a/crypto/fipsmodule/self_check/self_check.c +++ b/crypto/fipsmodule/self_check/self_check.c
@@ -946,6 +946,36 @@ goto err; } + // HKDF + static const uint8_t kHKDFSecret[32] = { + 0x68, 0x67, 0x85, 0x04, 0xb9, 0xb3, 0xad, 0xd1, 0x7d, 0x59, 0x67, + 0xa1, 0xa7, 0xbd, 0x37, 0x99, 0x3f, 0xd8, 0xa3, 0x3c, 0xe7, 0x30, + 0x30, 0x71, 0xf3, 0x9c, 0x09, 0x6d, 0x16, 0x35, 0xb3, 0xc9, + }; + static const uint8_t kHKDFSalt[32] = { + 0x8a, 0xab, 0x18, 0xb4, 0x9b, 0x0a, 0x17, 0xf9, 0xe8, 0xe6, 0x97, + 0x1a, 0x3d, 0xff, 0xda, 0x9b, 0x26, 0x8b, 0x3d, 0x17, 0x78, 0x0a, + 0xb3, 0xea, 0x65, 0xdb, 0x2a, 0xc0, 0x29, 0x9c, 0xfa, 0x72, + }; + static const uint8_t kHKDFInfo[32] = { + 0xe5, 0x6f, 0xf9, 0xe1, 0x18, 0x5e, 0x64, 0x8c, 0x6c, 0x8f, 0xee, + 0xc6, 0x93, 0x5a, 0xc5, 0x14, 0x8c, 0xf3, 0xd9, 0x78, 0xd2, 0x3a, + 0x86, 0xdd, 0x01, 0xdf, 0xb9, 0xe9, 0x5e, 0xe5, 0x1a, 0x56, + }; + static const uint8_t kHKDFOutput[32] = { + 0xa6, 0x29, 0xb4, 0xd7, 0xf4, 0xc1, 0x16, 0x64, 0x71, 0x5e, 0xa4, + 0xa8, 0xe6, 0x60, 0x8c, 0xf3, 0xc1, 0xa5, 0x03, 0xe2, 0x22, 0xf9, + 0x89, 0xe2, 0x12, 0x18, 0xbe, 0xef, 0x16, 0x86, 0xe0, 0xec, + }; + uint8_t hkdf_output[sizeof(kHKDFOutput)]; + if (!HKDF(hkdf_output, sizeof(hkdf_output), EVP_sha256(), kHKDFSecret, + sizeof(kHKDFSecret), kHKDFSalt, sizeof(kHKDFSalt), kHKDFInfo, + sizeof(kHKDFInfo)) || + !check_test(kHKDFOutput, hkdf_output, sizeof(kHKDFOutput), "HKDF")) { + fprintf(stderr, "HKDF failed.\n"); + goto err; + } + ret = 1; err:
diff --git a/util/fipstools/acvp/acvptool/subprocess/hkdf.go b/util/fipstools/acvp/acvptool/subprocess/hkdf.go index 3cd4c32..b124d79 100644 --- a/util/fipstools/acvp/acvptool/subprocess/hkdf.go +++ b/util/fipstools/acvp/acvptool/subprocess/hkdf.go
@@ -173,6 +173,9 @@ if err != nil { return nil, fmt.Errorf("HKDF operation failed: %s", err) } + if len(resp[0]) != int(outBytes) { + return nil, fmt.Errorf("HKDF operation resulted in %d bytes but wanted %d", len(resp[0]), outBytes) + } if isValidationTest { passed := bytes.Equal(expected, resp[0])
diff --git a/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 b/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 new file mode 100644 index 0000000..791fa7a --- /dev/null +++ b/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 Binary files differ
diff --git a/util/fipstools/acvp/acvptool/test/tests.json b/util/fipstools/acvp/acvptool/test/tests.json index d1e8eb5..36fdaad 100644 --- a/util/fipstools/acvp/acvptool/test/tests.json +++ b/util/fipstools/acvp/acvptool/test/tests.json
@@ -18,6 +18,7 @@ {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-384.bz2", "Out": "expected/HMAC-SHA2-384.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-512.bz2", "Out": "expected/HMAC-SHA2-512.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-512-256.bz2", "Out": "expected/HMAC-SHA2-512-256.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/HKDF.bz2", "Out": "expected/HKDF.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/hmacDRBG.bz2", "Out": "expected/hmacDRBG.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/KDA.bz2", "Out": "expected/KDA.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/KAS-ECC-SSC.bz2"},
diff --git a/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 b/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 new file mode 100644 index 0000000..f69a461 --- /dev/null +++ b/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 Binary files differ
diff --git a/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/util/fipstools/acvp/modulewrapper/modulewrapper.cc index 460a8e9..5c4f9b0 100644 --- a/util/fipstools/acvp/modulewrapper/modulewrapper.cc +++ b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
@@ -37,6 +37,7 @@ #include <openssl/ecdh.h> #include <openssl/ecdsa.h> #include <openssl/err.h> +#include <openssl/hkdf.h> #include <openssl/hmac.h> #include <openssl/obj.h> #include <openssl/rsa.h> @@ -885,6 +886,34 @@ "FB", "FC" ] + }, + { + "algorithm": "KDA", + "mode": "HKDF", + "revision": "Sp800-56Cr1", + "fixedInfoPattern": "uPartyInfo||vPartyInfo", + "encoding": [ + "concatenation" + ], + "hmacAlg": [ + "SHA2-224", + "SHA2-256", + "SHA2-384", + "SHA2-512", + "SHA2-512/256" + ], + "macSaltMethods": [ + "default", + "random" + ], + "l": 2048, + "z": [ + { + "min": 224, + "max": 65336, + "increment": 8 + } + ] } ])"; return write_reply({Span<const uint8_t>( @@ -1431,6 +1460,30 @@ return write_reply({Span<const uint8_t>(digest, digest_len)}); } +template <const EVP_MD *HashFunc()> +static bool HKDF(const Span<const uint8_t> args[], ReplyCallback write_reply) { + const EVP_MD *const md = HashFunc(); + const auto key = args[0]; + const auto salt = args[1]; + const auto info = args[2]; + const auto out_len_bytes = args[3]; + + if (out_len_bytes.size() != sizeof(uint32_t)) { + return false; + } + const uint32_t out_len = CRYPTO_load_u32_le(out_len_bytes.data()); + if (out_len > (1 << 24)) { + return false; + } + + std::vector<uint8_t> out(out_len); + if (!::HKDF(out.data(), out_len, md, key.data(), key.size(), salt.data(), + salt.size(), info.data(), info.size())) { + return false; + } + return write_reply({out}); +} + template <bool WithReseed> static bool DRBG(const Span<const uint8_t> args[], ReplyCallback write_reply) { const auto out_len_bytes = args[0]; @@ -1971,6 +2024,11 @@ {"3DES-ECB/decrypt", 3, TDES<false>}, {"3DES-CBC/encrypt", 4, TDES_CBC<true>}, {"3DES-CBC/decrypt", 4, TDES_CBC<false>}, + {"HKDF/SHA2-224", 4, HKDF<EVP_sha224>}, + {"HKDF/SHA2-256", 4, HKDF<EVP_sha256>}, + {"HKDF/SHA2-384", 4, HKDF<EVP_sha384>}, + {"HKDF/SHA2-512", 4, HKDF<EVP_sha512>}, + {"HKDF/SHA2-512/256", 4, HKDF<EVP_sha512_256>}, {"HMAC-SHA-1", 2, HMAC<EVP_sha1>}, {"HMAC-SHA2-224", 2, HMAC<EVP_sha224>}, {"HMAC-SHA2-256", 2, HMAC<EVP_sha256>},
diff --git a/util/fipstools/break-kat.go b/util/fipstools/break-kat.go index 6eace5b..ed29bb3 100644 --- a/util/fipstools/break-kat.go +++ b/util/fipstools/break-kat.go
@@ -21,6 +21,7 @@ "AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c", "DRBG": "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27", "DRBG-reseed": "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe", + "HKDF": "68678504b9b3add17d5967a1a7bd37993fd8a33ce7303071f39c096d1635b3c9", "SHA-1": "132fd9bad5c1826263bafbb699f707a5", "SHA-256": "ff3b857da7236a2baa0f396b51522217", "SHA-512": "212512f8d2ad8322781c6c4d69a9daa1",