diff --git a/crypto/fipsmodule/kdf/kbkdf.c b/crypto/fipsmodule/kdf/kbkdf.c index ec1c68d4f54..e6bc1e24a92 100644 --- a/crypto/fipsmodule/kdf/kbkdf.c +++ b/crypto/fipsmodule/kdf/kbkdf.c @@ -4,9 +4,9 @@ #include #include "internal.h" -int KBKDF_ctr(uint8_t *out_key, size_t out_len, const EVP_MD *digest, - const uint8_t *secret, size_t secret_len, const uint8_t *info, - size_t info_len) { +int KBKDF_ctr_hmac(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const uint8_t *info, size_t info_len) { int ret = 0; HMAC_CTX *hmac_ctx = NULL; @@ -87,6 +87,9 @@ int KBKDF_ctr(uint8_t *out_key, size_t out_len, const EVP_MD *digest, ret = 1; err: + if(ret <= 0) { + OPENSSL_cleanse(out_key, out_len); + } HMAC_CTX_free(hmac_ctx); return ret; } diff --git a/crypto/fipsmodule/kdf/kdf_test.cc b/crypto/fipsmodule/kdf/kdf_test.cc index f99163e09b4..939069c2716 100644 --- a/crypto/fipsmodule/kdf/kdf_test.cc +++ b/crypto/fipsmodule/kdf/kdf_test.cc @@ -145,7 +145,7 @@ TEST(KBKDFCounterTest, TestVectors) { std::vector out(expect.size()); - ASSERT_TRUE(KBKDF_ctr(out.data(), out.size(), md, secret.data(), + ASSERT_TRUE(KBKDF_ctr_hmac(out.data(), out.size(), md, secret.data(), secret.size(), info.data(), info.size())); ASSERT_EQ(Bytes(expect.data(), expect.size()), Bytes(out.data(), out.size())); @@ -157,22 +157,22 @@ TEST(KBKDFCounterTest, NegativeTests) { std::vector out(16); // NULL output - ASSERT_FALSE(KBKDF_ctr(NULL, out.size(), EVP_sha256(), &secret[0], + ASSERT_FALSE(KBKDF_ctr_hmac(NULL, out.size(), EVP_sha256(), &secret[0], sizeof(secret), NULL, 0)); // zero-length output - ASSERT_FALSE(KBKDF_ctr(out.data(), 0, EVP_sha256(), &secret[0], + ASSERT_FALSE(KBKDF_ctr_hmac(out.data(), 0, EVP_sha256(), &secret[0], sizeof(secret), NULL, 0)); // NULL Digest - ASSERT_FALSE(KBKDF_ctr(out.data(), out.size(), NULL, &secret[0], + ASSERT_FALSE(KBKDF_ctr_hmac(out.data(), out.size(), NULL, &secret[0], sizeof(secret), NULL, 0)); // NULL secret - ASSERT_FALSE(KBKDF_ctr(out.data(), out.size(), EVP_sha256(), NULL, + ASSERT_FALSE(KBKDF_ctr_hmac(out.data(), out.size(), EVP_sha256(), NULL, sizeof(secret), NULL, 0)); // zero-length secret - ASSERT_FALSE(KBKDF_ctr(out.data(), out.size(), EVP_sha256(), &secret[0], + ASSERT_FALSE(KBKDF_ctr_hmac(out.data(), out.size(), EVP_sha256(), &secret[0], 0, NULL, 0)); } diff --git a/crypto/fipsmodule/kdf/sskdf.c b/crypto/fipsmodule/kdf/sskdf.c index f1bcad07743..16e25db5a3c 100644 --- a/crypto/fipsmodule/kdf/sskdf.c +++ b/crypto/fipsmodule/kdf/sskdf.c @@ -278,6 +278,9 @@ static int SSKDF(const sskdf_variant *variant, sskdf_variant_ctx *ctx, ret = 1; err: + if(ret <= 0) { + OPENSSL_cleanse(out_key, out_len); + } return ret; } diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index e3faab2193e..41cbb537cc3 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -85,9 +85,10 @@ OPENSSL_EXPORT int SSKDF_hmac(uint8_t *out_key, size_t out_len, const uint8_t *info, size_t info_len, const uint8_t *salt, size_t salt_len); -// KBKDF_ctr derives keying material using the KDF counter mode algorithm, +// KBKDF_ctr_hmac derives keying material using the KDF counter mode algorithm, // using the provided key derivation key |secret| and fixed info |info|. -// |info| or |info_len| may be zero-length. +// |info| or |info_len| may be zero-length. This algorithm +// may be referred to as a "Key-Based Key Derivation Function in Counter Mode". // // This implementation adheres to the algorithm specified in Section 4.1 of the // NIST Special Publication 800-108 Revision 1 Update 1 published on August @@ -95,16 +96,16 @@ OPENSSL_EXPORT int SSKDF_hmac(uint8_t *out_key, size_t out_len, // * |out_len|, |secret_len|, and |info_len| are specified in bytes // * |out_len| is analogous to |L| in the specification. // * |r| the length of the binary representation of the counter |i| -// . referred to by the specification is 32-bit in this implementation. +// referred to by the specification. |r| is 32 bits in this implementation. // * The 32-bit counter is big-endian in this implementation. // * |K_IN| is analogous to |secret| and |secret_len|. // * |PRF| refers to HMAC in this implementation. // // Specification is available at https://doi.org/10.6028/NIST.SP.800-108r1-upd1 -OPENSSL_EXPORT int KBKDF_ctr(uint8_t *out_key, size_t out_len, - const EVP_MD *digest, const uint8_t *secret, - size_t secret_len, const uint8_t *info, - size_t info_len); +OPENSSL_EXPORT int KBKDF_ctr_hmac(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *secret, + size_t secret_len, const uint8_t *info, + size_t info_len); // KDF support for EVP.