Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/check-test-vectors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ jobs:
run: |
gh issue create \
--title "Update third-party test vectors" \
--template "update-vectors" \
--body "Automated check detected that some third-party test vectors need to be updated."
--template "update-vectors"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
Expand Down
12 changes: 9 additions & 3 deletions crypto/cipher_extra/aead_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1178,8 +1178,10 @@ static void RunWycheproofTestCase(FileTest *t, const EVP_AEAD *aead) {
}
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_gcm_siv_test.txt`.
TEST(AEADTest, WycheproofAESGCMSIV) {
FileTestGTest("third_party/wycheproof_testvectors/aes_gcm_siv_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_gcm_siv_test.txt",
[](FileTest *t) {
std::string key_size_str;
ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
Expand Down Expand Up @@ -1226,17 +1228,21 @@ TEST(AEADTest, WycheproofAESGCM) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/chacha20_poly1305_test.txt`.
TEST(AEADTest, WycheproofChaCha20Poly1305) {
FileTestGTest("third_party/wycheproof_testvectors/chacha20_poly1305_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/chacha20_poly1305_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("keySize");
RunWycheproofTestCase(t, EVP_aead_chacha20_poly1305());
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/xchacha20_poly1305_test.txt`.
TEST(AEADTest, WycheproofXChaCha20Poly1305) {
FileTestGTest(
"third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt",
"third_party/vectors/converted/wycheproof/testvectors_v1/xchacha20_poly1305_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("keySize");
RunWycheproofTestCase(t, EVP_aead_xchacha20_poly1305());
Expand Down
12 changes: 9 additions & 3 deletions crypto/cipher_extra/cipher_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -792,9 +792,11 @@ static bool ChaCha20Poly1305TagValidate(size_t tag_size) {
return tag_size <= 16;
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/chacha20_poly1305_test.txt`.
TEST(CipherTest, WycheproofChaCha20Poly1305) {
std::string test_vectors =
"third_party/wycheproof_testvectors/chacha20_poly1305_test.txt";
"third_party/vectors/converted/wycheproof/testvectors_v1/chacha20_poly1305_test.txt";
FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
t->IgnoreInstruction("type");
t->IgnoreInstruction("tagSize");
Expand Down Expand Up @@ -834,9 +836,11 @@ static bool AesCcmTagValidate(size_t tag_size) {
return true;
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_ccm_test.txt`.
TEST(CipherTest, WycheproofAesCcm) {
std::string test_vectors =
"third_party/wycheproof_testvectors/aes_ccm_test.txt";
"third_party/vectors/converted/wycheproof/testvectors_v1/aes_ccm_test.txt";
FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
t->IgnoreInstruction("type");
t->IgnoreInstruction("tagSize");
Expand Down Expand Up @@ -876,8 +880,10 @@ TEST(CipherTest, WycheproofAesCcm) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_cbc_pkcs5_test.txt`.
TEST(CipherTest, WycheproofAESCBC) {
FileTestGTest("third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_cbc_pkcs5_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("type");
t->IgnoreInstruction("ivSize");
Expand Down
86 changes: 63 additions & 23 deletions crypto/evp_extra/p_pqdsa_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2646,35 +2646,56 @@ static int VerifyMLDSAWithContext(EVP_PKEY *pkey,
// context |msg_ctx|. We need this wrapper because |EVP_DigestSign| does not
// support signing with contexts.
//
// If |has_msg| is true, computes mu from |msg| and |msg_ctx|, and verifies it
// matches |expected_mu| if provided. If |has_msg| is false, uses |expected_mu|
// directly (for internal signing tests with Sign_internal).
//
// Always signs using EVP_PKEY_sign with mu. If |msg_ctx| is empty, also
// performs standard signing with EVP_DigestSign to verify both paths work.
//
// It returns one on success and zero on error.
static int SignMLDSAWithContext(EVP_PKEY *pkey, std::vector<uint8_t> &sig,
const std::vector<uint8_t> &pk,
const std::vector<uint8_t> &msg,
const std::vector<uint8_t> &msg_ctx) {
// If there's a non-empty context string, do ExternalMu signing
if (!msg_ctx.empty()) {
std::vector<uint8_t> mu;
const std::vector<uint8_t> &msg_ctx,
const std::vector<uint8_t> &expected_mu,
bool has_msg) {
std::vector<uint8_t> mu;
if (has_msg) {
if (!ComputeMLDSAExternalMu(pk, msg_ctx, msg, mu)) {
return 0;
}
bssl::UniquePtr<EVP_PKEY_CTX> pkey_ctx(EVP_PKEY_CTX_new(pkey, nullptr));
if (!pkey_ctx || !EVP_PKEY_sign_init(pkey_ctx.get())) {
if (!expected_mu.empty() && mu != expected_mu) {
return 0;
}

size_t sig_len = sig.size();
return EVP_PKEY_sign(pkey_ctx.get(), sig.data(), &sig_len, mu.data(),
mu.size());
} else {
mu = expected_mu;
}

// Otherwise, do standard signing
bssl::ScopedEVP_MD_CTX md_ctx;
if (!EVP_DigestSignInit(md_ctx.get(), nullptr, nullptr, nullptr, pkey)) {
bssl::UniquePtr<EVP_PKEY_CTX> pkey_ctx(EVP_PKEY_CTX_new(pkey, nullptr));
if (!pkey_ctx || !EVP_PKEY_sign_init(pkey_ctx.get())) {
return 0;
}

size_t sig_len = sig.size();
return EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, msg.data(),
msg.size());
if (!EVP_PKEY_sign(pkey_ctx.get(), sig.data(), &sig_len, mu.data(),
mu.size())) {
return 0;
}

// If no context, also do standard signing
if (msg_ctx.empty()) {
bssl::ScopedEVP_MD_CTX md_ctx;
if (!EVP_DigestSignInit(md_ctx.get(), nullptr, nullptr, nullptr, pkey)) {
return 0;
}
size_t sig_len = sig.size();
if (!EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, msg.data(),
msg.size())) {
return 0;
}
}
return 1;
}

TEST_P(WycheproofMLDSATest, Verify) {
Expand Down Expand Up @@ -2739,7 +2760,7 @@ TEST_P(WycheproofMLDSATest, SignWithSeed) {
std::string test_path =
std::string(kWycheproofMLDSAPath) + GetParam().sign_seed_test;
FileTestGTest(test_path.c_str(), [&](FileTest *t) {
std::vector<uint8_t> msg, pk, sk_pkcs8, sk_seed, expected_sig;
std::vector<uint8_t> msg, pk, sk_pkcs8, sk_seed, expected_sig, expected_mu;
std::vector<uint8_t> msg_ctx;

ASSERT_TRUE(t->GetInstructionBytes(&pk, "publicKey"));
Expand All @@ -2749,7 +2770,12 @@ TEST_P(WycheproofMLDSATest, SignWithSeed) {
ASSERT_TRUE(t->GetInstructionBytes(&sk_pkcs8, "privateKeyPkcs8"));
}
ASSERT_TRUE(t->GetInstructionBytes(&sk_seed, "privateSeed"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));

// msg is optional for internal signing tests (Sign_internal with mu)
bool has_msg = t->HasAttribute("msg");
if (has_msg) {
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
}
ASSERT_TRUE(t->GetBytes(&expected_sig, "sig"));

WycheproofResult result;
Expand All @@ -2758,6 +2784,10 @@ TEST_P(WycheproofMLDSATest, SignWithSeed) {
if (t->HasAttribute("ctx")) {
ASSERT_TRUE(t->GetBytes(&msg_ctx, "ctx"));
}
// mu is an intermediate value in the signing process
if (t->HasAttribute("mu")) {
ASSERT_TRUE(t->GetBytes(&expected_mu, "mu"));
}

bssl::UniquePtr<EVP_PKEY> sec_pkey_from_raw(
EVP_PKEY_pqdsa_new_raw_private_key(GetParam().nid, sk_seed.data(),
Expand Down Expand Up @@ -2788,8 +2818,8 @@ TEST_P(WycheproofMLDSATest, SignWithSeed) {

std::vector<uint8_t> sig(expected_sig.size());
EVP_PKEY *signing_key = has_pkcs8 ? sec_pkey_from_der.get() : sec_pkey_from_raw.get();
int sign_result =
SignMLDSAWithContext(signing_key, sig, pk, msg, msg_ctx);
int sign_result = SignMLDSAWithContext(signing_key, sig, pk, msg, msg_ctx,
expected_mu, has_msg);
if (result.IsValid()) {
EXPECT_TRUE(sign_result) << "Signing failed for valid test case";
} else {
Expand All @@ -2802,7 +2832,7 @@ TEST_P(WycheproofMLDSATest, SignWithoutSeed) {
std::string test_path =
std::string(kWycheproofMLDSAPath) + GetParam().sign_noseed_test;
FileTestGTest(test_path.c_str(), [&](FileTest *t) {
std::vector<uint8_t> msg, pk, sk_expanded, expected_sig;
std::vector<uint8_t> msg, pk, sk_expanded, expected_sig, expected_mu;
std::vector<uint8_t> msg_ctx;

// publicKey is optional - it's omitted for some invalid test cases
Expand All @@ -2811,7 +2841,12 @@ TEST_P(WycheproofMLDSATest, SignWithoutSeed) {
ASSERT_TRUE(t->GetInstructionBytes(&pk, "publicKey"));
}
ASSERT_TRUE(t->GetInstructionBytes(&sk_expanded, "privateKey"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));

// msg is optional for internal signing tests (Sign_internal with mu)
bool has_msg = t->HasAttribute("msg");
if (has_msg) {
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
}
ASSERT_TRUE(t->GetBytes(&expected_sig, "sig"));

WycheproofResult result;
Expand All @@ -2820,6 +2855,10 @@ TEST_P(WycheproofMLDSATest, SignWithoutSeed) {
if (t->HasAttribute("ctx")) {
ASSERT_TRUE(t->GetBytes(&msg_ctx, "ctx"));
}
// mu is an intermediate value in the signing process
if (t->HasAttribute("mu")) {
ASSERT_TRUE(t->GetBytes(&expected_mu, "mu"));
}

bssl::UniquePtr<EVP_PKEY> sec_pkey_from_expanded(
EVP_PKEY_pqdsa_new_raw_private_key(GetParam().nid, sk_expanded.data(),
Expand All @@ -2835,8 +2874,9 @@ TEST_P(WycheproofMLDSATest, SignWithoutSeed) {
ASSERT_TRUE(sec_pkey_from_expanded.get());

std::vector<uint8_t> sig(expected_sig.size());
int sign_result = SignMLDSAWithContext(sec_pkey_from_expanded.get(), sig,
pk, msg, msg_ctx);
int sign_result =
SignMLDSAWithContext(sec_pkey_from_expanded.get(), sig, pk, msg,
msg_ctx, expected_mu, has_msg);
if (result.IsValid()) {
EXPECT_TRUE(sign_result) << "Signing failed for valid test case";
} else {
Expand Down
12 changes: 9 additions & 3 deletions crypto/fipsmodule/aes/aes_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,10 @@ TEST(AESTest, TestVectors) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_wrap_test.txt`.
TEST(AESTest, WycheproofKeyWrap) {
FileTestGTest("third_party/wycheproof_testvectors/kw_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_wrap_test.txt",
[](FileTest *t) {
std::string key_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
Expand Down Expand Up @@ -275,8 +277,10 @@ TEST(AESTest, WycheproofKeyWrap) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_wrap_test.txt`.
TEST(AESTest, WycheproofEVPKeyWrap) {
FileTestGTest("third_party/wycheproof_testvectors/kw_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_wrap_test.txt",
[](FileTest *t) {
std::string key_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
Expand Down Expand Up @@ -342,8 +346,10 @@ TEST(AESTest, WycheproofEVPKeyWrap) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_kwp_test.txt`.
TEST(AESTest, WycheproofKeyWrapWithPadding) {
FileTestGTest("third_party/wycheproof_testvectors/kwp_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_kwp_test.txt",
[](FileTest *t) {
std::string key_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
Expand Down
4 changes: 3 additions & 1 deletion crypto/fipsmodule/cmac/cmac_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,10 @@ TEST(CMACTest, RFC4493TestVectors) {
test("RFC 4493 #4", kKey, sizeof(kKey), kMsg4, sizeof(kMsg4), kOut4);
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/aes_cmac_test.txt`.
TEST(CMACTest, Wycheproof) {
FileTestGTest("third_party/wycheproof_testvectors/aes_cmac_test.txt",
FileTestGTest("third_party/vectors/converted/wycheproof/testvectors_v1/aes_cmac_test.txt",
[](FileTest *t) {
std::string key_size, tag_size;
ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
Expand Down
16 changes: 12 additions & 4 deletions crypto/fipsmodule/hkdf/hkdf_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,23 +397,31 @@ static void RunWycheproofTest(const char *path, const EVP_MD *md) {
});
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/hkdf_sha1_test.txt`.
TEST(HKDFTest, WycheproofSHA1) {
RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha1_test.txt",
RunWycheproofTest("third_party/vectors/converted/wycheproof/testvectors_v1/hkdf_sha1_test.txt",
EVP_sha1());
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/hkdf_sha256_test.txt`.
TEST(HKDFTest, WycheproofSHA256) {
RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha256_test.txt",
RunWycheproofTest("third_party/vectors/converted/wycheproof/testvectors_v1/hkdf_sha256_test.txt",
EVP_sha256());
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/hkdf_sha384_test.txt`.
TEST(HKDFTest, WycheproofSHA384) {
RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha384_test.txt",
RunWycheproofTest("third_party/vectors/converted/wycheproof/testvectors_v1/hkdf_sha384_test.txt",
EVP_sha384());
}

//= third_party/vectors/vectors_spec.md#wycheproof
//# AWS-LC MUST test against `testvectors_v1/hkdf_sha512_test.txt`.
TEST(HKDFTest, WycheproofSHA512) {
RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha512_test.txt",
RunWycheproofTest("third_party/vectors/converted/wycheproof/testvectors_v1/hkdf_sha512_test.txt",
EVP_sha512());
}

Expand Down
Loading
Loading