Skip to content

Commit

Permalink
Add KDA OneStep (SSKDF_digest and SSKDF_hmac) to FIPS indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
skmcgrail committed Aug 23, 2024
1 parent 28e55ba commit 9ddb51c
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
18 changes: 18 additions & 0 deletions crypto/fipsmodule/kdf/sskdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,15 @@ static int SSKDF(const sskdf_variant *variant, sskdf_variant_ctx *ctx,
int SSKDF_digest(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) {
// We have to avoid the underlying |EVP_DigestFinal| services updating
// the indicator state, so we lock the state here.
FIPS_service_indicator_lock_state();

sskdf_variant_ctx ctx = {0};
int ret = 0;

if (!sskdf_variant_digest_ctx_init(&ctx, digest)) {
FIPS_service_indicator_unlock_state();
return 0;
}

Expand All @@ -305,16 +310,25 @@ int SSKDF_digest(uint8_t *out_key, size_t out_len, const EVP_MD *digest,

end:
sskdf_variant_digest_ctx_cleanup(&ctx);
FIPS_service_indicator_unlock_state();
if (ret) {
SSKDF_digest_verify_service_indicator(digest);
}
return ret;
}

int SSKDF_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, const uint8_t *salt, size_t salt_len) {
// We have to avoid the underlying |HMAC_Final| services updating
// the indicator state, so we lock the state here.
FIPS_service_indicator_lock_state();

sskdf_variant_ctx ctx = {0};
int ret = 0;

if (!sskdf_variant_hmac_ctx_init(&ctx, digest, salt, salt_len)) {
FIPS_service_indicator_unlock_state();
return 0;
}

Expand All @@ -327,5 +341,9 @@ int SSKDF_hmac(uint8_t *out_key, size_t out_len, const EVP_MD *digest,

end:
sskdf_variant_hmac_ctx_cleanup(&ctx);
FIPS_service_indicator_unlock_state();
if(ret) {
SSKDF_hmac_verify_service_indicator(digest);
}
return ret;
}
8 changes: 8 additions & 0 deletions crypto/fipsmodule/service_indicator/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ void PBKDF2_verify_service_indicator(const EVP_MD *evp_md, size_t password_len,
void SSHKDF_verify_service_indicator(const EVP_MD *evp_md);
void TLSKDF_verify_service_indicator(const EVP_MD *dgst, const char *label,
size_t label_len);
void SSKDF_digest_verify_service_indicator(const EVP_MD *dgst);
void SSKDF_hmac_verify_service_indicator(const EVP_MD *dgst);

#else

Expand Down Expand Up @@ -116,6 +118,12 @@ OPENSSL_INLINE void TLSKDF_verify_service_indicator(
OPENSSL_UNUSED const char *label,
OPENSSL_UNUSED size_t label_len) {}

OPENSSL_INLINE void SSKDF_digest_verify_service_indicator(
OPENSSL_UNUSED const EVP_MD *dgst) {}

OPENSSL_INLINE void SSKDF_hmac_verify_service_indicator(
OPENSSL_UNUSED const EVP_MD *dgst) {}

#endif // AWSLC_FIPS

// is_fips_build is similar to |FIPS_mode| but returns 1 including in the case
Expand Down
36 changes: 36 additions & 0 deletions crypto/fipsmodule/service_indicator/service_indicator.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,42 @@ void TLSKDF_verify_service_indicator(const EVP_MD *dgst, const char *label,
}
}

void SSKDF_digest_verify_service_indicator(const EVP_MD *dgst) {
switch (dgst->type) {
case NID_sha1:
case NID_sha224:
case NID_sha256:
case NID_sha384:
case NID_sha512:
case NID_sha512_224:
case NID_sha512_256:
case NID_sha3_224:
case NID_sha3_256:
case NID_sha3_384:
case NID_sha3_512:
FIPS_service_indicator_update_state();
break;
default:
break;
}
}

void SSKDF_hmac_verify_service_indicator(const EVP_MD *dgst) {
switch (dgst->type) {
case NID_sha1:
case NID_sha224:
case NID_sha256:
case NID_sha384:
case NID_sha512:
case NID_sha512_224:
case NID_sha512_256:
FIPS_service_indicator_update_state();
break;
default:
break;
}
}

#else

uint64_t FIPS_service_indicator_before_call(void) { return 0; }
Expand Down
141 changes: 141 additions & 0 deletions crypto/fipsmodule/service_indicator/service_indicator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4317,6 +4317,147 @@ TEST(ServiceIndicatorTest, DRBG) {
EXPECT_EQ(approved, AWSLC_APPROVED);
}

static const struct SSKDFDigestTestVector {
const EVP_MD *(*md)();
const FIPSStatus expectation;
} kSSKDFDigestTestVectors[] = {{
&EVP_sha1,
AWSLC_APPROVED,
},
{
&EVP_sha224,
AWSLC_APPROVED,
},
{
&EVP_sha256,
AWSLC_APPROVED,
},
{
&EVP_sha384,
AWSLC_APPROVED,
},
{
&EVP_sha512,
AWSLC_APPROVED,
},
{
&EVP_sha512_224,
AWSLC_APPROVED,
},
{
&EVP_sha512_256,
AWSLC_APPROVED,
},
{
&EVP_sha3_224,
AWSLC_APPROVED,
},
{
&EVP_sha3_256,
AWSLC_APPROVED,
},
{
&EVP_sha3_384,
AWSLC_APPROVED,
},
{
&EVP_sha3_512,
AWSLC_APPROVED,
},
{
&EVP_md5,
AWSLC_NOT_APPROVED,
}};

class SSKDFDigestIndicatorTest : public TestWithNoErrors<SSKDFDigestTestVector> {};

INSTANTIATE_TEST_SUITE_P(All, SSKDFDigestIndicatorTest,
testing::ValuesIn(kSSKDFDigestTestVectors));


TEST_P(SSKDFDigestIndicatorTest, SSKDF) {
const SSKDFDigestTestVector &vector = GetParam();

const uint8_t secret[23] = {'A', 'W', 'S', '-', 'L', 'C', ' ', 'S',
'S', 'K', 'D', 'F', '-', 'D', 'I', 'G',
'E', 'S', 'T', ' ', 'K', 'E', 'Y'};
const uint8_t info[19] = {'A', 'W', 'S', '-', 'L', 'C', ' ', 'S', 'S', 'K',
'D', 'F', '-', 'D', 'I', 'G', 'E', 'S', 'T'};
uint8_t output[16] = {0};

FIPSStatus approved = AWSLC_NOT_APPROVED;

CALL_SERVICE_AND_CHECK_APPROVED(
approved, ASSERT_TRUE(SSKDF_digest(
&output[0], sizeof(output), vector.md(), &secret[0],
sizeof(secret), &info[0], sizeof(info))));
ASSERT_EQ(vector.expectation, approved);
}

static const struct SSKDFHmacTestVector {
const EVP_MD *(*md)();
const FIPSStatus expectation;
} kSSKDFHmacTestVectors[] = {{
&EVP_sha1,
AWSLC_APPROVED,
},
{
&EVP_sha224,
AWSLC_APPROVED,
},
{
&EVP_sha256,
AWSLC_APPROVED,
},
{
&EVP_sha384,
AWSLC_APPROVED,
},
{
&EVP_sha512,
AWSLC_APPROVED,
},
{
&EVP_sha512_224,
AWSLC_APPROVED,
},
{
&EVP_sha512_256,
AWSLC_APPROVED,
},
{
&EVP_md5,
AWSLC_NOT_APPROVED,
}};

class SSKDFHmacIndicatorTest : public TestWithNoErrors<SSKDFHmacTestVector> {};

INSTANTIATE_TEST_SUITE_P(All, SSKDFHmacIndicatorTest,
testing::ValuesIn(kSSKDFHmacTestVectors));


TEST_P(SSKDFHmacIndicatorTest, SSKDF) {
const SSKDFHmacTestVector &vector = GetParam();

const uint8_t secret[21] = {'A', 'W', 'S', '-', 'L', 'C', ' ',
'S', 'S', 'K', 'D', 'F', '-', 'H',
'M', 'A', 'C', ' ', 'K', 'E', 'Y'};
const uint8_t info[17] = {'A', 'W', 'S', '-', 'L', 'C', ' ', 'S', 'S', 'K',
'D', 'F', '-', 'H', 'M', 'A', 'C'};
const uint8_t salt[22] = {'A', 'W', 'S', '-', 'L', 'C', ' ', 'S',
'S', 'K', 'D', 'F', '-', 'H', 'M', 'A',
'C', ' ', 'S', 'A', 'L', 'T'};
uint8_t output[16] = {0};

FIPSStatus approved = AWSLC_NOT_APPROVED;

CALL_SERVICE_AND_CHECK_APPROVED(
approved, ASSERT_TRUE(SSKDF_hmac(&output[0], sizeof(output), vector.md(),
&secret[0], sizeof(secret), &info[0],
sizeof(info), &salt[0], sizeof(salt))));
ASSERT_EQ(vector.expectation, approved);
}

// Verifies that the awslc_version_string is as expected.
// Since this is running in FIPS mode it should end in FIPS
// Update this when the AWS-LC version number is modified
Expand Down

0 comments on commit 9ddb51c

Please sign in to comment.