Skip to content

Commit

Permalink
One-step key derivation implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
skmcgrail committed Jun 3, 2024
1 parent 94e91d9 commit ed1806d
Show file tree
Hide file tree
Showing 9 changed files with 2,396 additions and 730 deletions.
1 change: 1 addition & 0 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ if(BUILD_TESTING)
fipsmodule/ec/ec_test.cc
fipsmodule/ec/p256-nistz_test.cc
fipsmodule/ecdsa/ecdsa_test.cc
fipsmodule/kdf/kdf_test.cc
fipsmodule/md5/md5_test.cc
fipsmodule/modes/gcm_test.cc
fipsmodule/modes/xts_test.cc
Expand Down
2 changes: 1 addition & 1 deletion crypto/fipsmodule/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
#include "evp/p_rsa.c"
#include "hkdf/hkdf.c"
#include "hmac/hmac.c"
#include "kdf/sskdf.c"
#include "md4/md4.c"
#include "md5/md5.c"
#include "modes/cbc.c"
Expand Down Expand Up @@ -145,7 +146,6 @@
#include "sshkdf/sshkdf.c"
#include "tls/kdf.c"


#if defined(BORINGSSL_FIPS)

#if !defined(OPENSSL_ASAN)
Expand Down
29 changes: 29 additions & 0 deletions crypto/fipsmodule/kdf/internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

#include <openssl/digest.h>
#include <openssl/hmac.h>

typedef struct {
void *data;
} SSKDF_VARIANT_CTX;

typedef struct {
const EVP_MD *digest;
EVP_MD_CTX *ctx;
} SSKDF_VARIANT_DIGEST_CTX;

typedef struct {
HMAC_CTX *ctx;
} SSKDF_VARIANT_HMAC_CTX;

typedef struct {
size_t (*size)(SSKDF_VARIANT_CTX *ctx);
int (*compute)(SSKDF_VARIANT_CTX *ctx, uint8_t *out, size_t out_len,
const uint8_t counter[4], const uint8_t *secret,
size_t secret_len, const uint8_t *info, size_t info_len);
} SSKDF_VARIANT;

const SSKDF_VARIANT *SSKDF_VARIANT_DIGEST(void);

const SSKDF_VARIANT *SSKDF_VARIANT_HMAC(void);
89 changes: 89 additions & 0 deletions crypto/fipsmodule/kdf/kdf_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

#include <openssl/digest.h>
#include <openssl/kdf.h>
#include <vector>
#include "../../test/file_test.h"
#include "../../test/test_util.h"

#include <gtest/gtest.h>

TEST(SSKDFTest, TestVectors) {
FileTestGTest("crypto/fipsmodule/kdf/test/sskdf.txt", [](FileTest *t) {
const EVP_MD *md;
std::string hash;
ASSERT_TRUE(t->GetAttribute(&hash, "HASH"));
if (hash == "SHA1") {
md = EVP_sha1();
} else if (hash == "SHA-224") {
md = EVP_sha224();
} else if (hash == "SHA-256") {
md = EVP_sha256();
} else if (hash == "SHA-384") {
md = EVP_sha384();
} else if (hash == "SHA-512") {
md = EVP_sha512();
} else {
FAIL() << "Unknown HASH=" + hash;
}

std::vector<uint8_t> secret, info, expect;

ASSERT_TRUE(t->GetBytes(&secret, "SECRET"));
if (t->HasAttribute("INFO")) {
ASSERT_TRUE(t->GetBytes(&info, "INFO"));
} else {
info = std::vector<uint8_t>(0);
}
ASSERT_TRUE(t->GetBytes(&expect, "EXPECT"));

std::vector<uint8_t> out(expect.size());

std::string variant;
ASSERT_TRUE(t->GetAttribute(&variant, "VARIANT"));
if (variant == "DIGEST") {
ASSERT_TRUE(SSKDF_DIGEST(out.data(), out.size(), md, secret.data(),
secret.size(), info.data(), info.size()));
} else if (variant == "HMAC") {
if (t->HasAttribute("SALT")) {
std::vector<uint8_t> salt;
ASSERT_TRUE(t->GetBytes(&salt, "SALT"));
ASSERT_TRUE(SSKDF_HMAC(out.data(), out.size(), md, secret.data(),
secret.size(), info.data(), info.size(),
salt.data(), salt.size()));
} else {
ASSERT_TRUE(SSKDF_HMAC(out.data(), out.size(), md, secret.data(),
secret.size(), info.data(), info.size(), NULL,
0));
}
}
ASSERT_EQ(Bytes(expect.data(), expect.size()),
Bytes(out.data(), out.size()));
});
}

TEST(SSKDFTest, DigestNegativeTests) {
const uint8_t secret[16] = {0};
std::vector<uint8_t> out(16);

// NULL output
ASSERT_FALSE(SSKDF_DIGEST(NULL, out.size(), EVP_sha256(), &secret[0],
sizeof(secret), NULL, 0));

// zero-length output
ASSERT_FALSE(SSKDF_DIGEST(out.data(), 0, EVP_sha256(), &secret[0],
sizeof(secret), NULL, 0));

// NULL digest
ASSERT_FALSE(SSKDF_DIGEST(out.data(), out.size(), NULL, &secret[0],
sizeof(secret), NULL, 0));

// NULL secret
ASSERT_FALSE(
SSKDF_DIGEST(out.data(), out.size(), EVP_sha256(), NULL, 0, NULL, 0));

// zero-length secret
ASSERT_FALSE(SSKDF_DIGEST(out.data(), out.size(), EVP_sha256(), &secret[0], 0,
NULL, 0));
}
Loading

0 comments on commit ed1806d

Please sign in to comment.