Run ML-DSA Wycheproof verify tests through EVP too This is where the other verify tests run and covers a bit more code. They're not redundant with the low-level version, but when EVP catches up, perhaps. This required tweaking the driver slightly to support an off-by-default EVP_PKEY_ALG, and also to tolerate unparseable public key if the test was marked "invalid". Bug: 449751916 Change-Id: I5457e16222ec65e1f08cd356a9baa0236ee49857 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/83247 Reviewed-by: Lily Chen <chlily@google.com> Commit-Queue: David Benjamin <davidben@google.com> Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc index 3e01818..04a4dff 100644 --- a/crypto/evp/evp_test.cc +++ b/crypto/evp/evp_test.cc
@@ -849,18 +849,11 @@ RunEVPTests("crypto/evp/test/x25519_tests.txt"); } -void RunWycheproofVerifyTest(const char *path) { +void RunWycheproofVerifyTest(const char *path, const EVP_PKEY_ALG *alg) { SCOPED_TRACE(path); - FileTestGTest(path, [](FileTest *t) { + FileTestGTest(path, [&](FileTest *t) { t->IgnoreAllUnusedInstructions(); - std::vector<uint8_t> der; - ASSERT_TRUE(t->GetInstructionBytes(&der, "publicKeyDer")); - CBS cbs; - CBS_init(&cbs, der.data(), der.size()); - bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs)); - ASSERT_TRUE(key); - const EVP_MD *md = nullptr; if (t->HasInstruction("sha")) { md = GetWycheproofDigest(t, "sha", true); @@ -883,8 +876,31 @@ ASSERT_TRUE(t->GetBytes(&msg, "msg")); std::vector<uint8_t> sig; ASSERT_TRUE(t->GetBytes(&sig, "sig")); + std::vector<uint8_t> sig_ctx; + if (t->HasAttribute("ctx")) { + ASSERT_TRUE(t->GetBytes(&sig_ctx, "ctx")); + } WycheproofResult result; ASSERT_TRUE(GetWycheproofResult(t, &result)); + // BoringSSL does not enforce policies on weak keys and leaves it to the + // caller. + bool expect_valid = + result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"}); + + std::vector<uint8_t> der; + ASSERT_TRUE(t->GetInstructionBytes(&der, "publicKeyDer")); + bssl::UniquePtr<EVP_PKEY> key( + EVP_PKEY_from_subject_public_key_info(der.data(), der.size(), &alg, 1)); + if (!key) { + EXPECT_FALSE(expect_valid); + return; + } + + // We do not currently support signature contexts. + // TODO(crbug.com/449751916): Support this. + if (!sig_ctx.empty()) { + return; + } if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) { // DSA is deprecated and is not usable via EVP. @@ -910,81 +926,125 @@ } int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(), msg.size()); - // BoringSSL does not enforce policies on weak keys and leaves it to the - // caller. - EXPECT_EQ(ret, - result.IsValid({"SmallModulus", "SmallPublicKey", "WeakHash"}) - ? 1 - : 0); + EXPECT_EQ(ret, expect_valid ? 1 : 0); } }); } TEST(EVPTest, WycheproofDSA) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/dsa_2048_224_sha224_test.txt"); + "third_party/wycheproof_testvectors/dsa_2048_224_sha224_test.txt", + EVP_pkey_dsa()); } TEST(EVPTest, WycheproofECDSAP224) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt", + EVP_pkey_ec_p224()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt", + EVP_pkey_ec_p224()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt", + EVP_pkey_ec_p224()); } TEST(EVPTest, WycheproofECDSAP256) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt", + EVP_pkey_ec_p256()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt", + EVP_pkey_ec_p256()); } TEST(EVPTest, WycheproofECDSAP384) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt", + EVP_pkey_ec_p384()); + RunWycheproofVerifyTest( + "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt", + EVP_pkey_ec_p384()); } TEST(EVPTest, WycheproofECDSAP521) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt"); - RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt"); + "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt", + EVP_pkey_ec_p521()); } TEST(EVPTest, WycheproofEd25519) { + RunWycheproofVerifyTest("third_party/wycheproof_testvectors/ed25519_test.txt", + EVP_pkey_ed25519()); +} + +// TODO(crbug.com/449751916): We also test these in the low-level ML-DSA code. +// The EVP-level tests are not yet redundant: +// +// * We can't yet run the tests with a context argument. +// * We can't yet run the signing tests with external entropy. +// +// When/if we add |EVP_PKEY|-based APIs for those, we may be able to remove the +// low-level copy. + +TEST(EVPTest, WycheproofMLDSA44) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/ed25519_test.txt"); + "third_party/wycheproof_testvectors/mldsa_44_verify_test.txt", + EVP_pkey_ml_dsa_44()); +} + +TEST(EVPTest, WycheproofMLDSA65) { + RunWycheproofVerifyTest( + "third_party/wycheproof_testvectors/mldsa_65_verify_test.txt", + EVP_pkey_ml_dsa_65()); +} + +TEST(EVPTest, WycheproofMLDSA87) { + RunWycheproofVerifyTest( + "third_party/wycheproof_testvectors/mldsa_87_verify_test.txt", + EVP_pkey_ml_dsa_87()); } TEST(EVPTest, WycheproofRSAPKCS1) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_4096_sha256_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_4096_sha256_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_8192_sha256_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_8192_sha256_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_8192_sha384_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_8192_sha384_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_signature_8192_sha512_test.txt"); + "third_party/wycheproof_testvectors/rsa_signature_8192_sha512_test.txt", + EVP_pkey_rsa()); } void RunWycheproofSignTest(FileTest *t) { @@ -1043,23 +1103,26 @@ TEST(EVPTest, WycheproofRSAPSS) { RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/" - "rsa_pss_2048_sha256_mgf1_32_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_32_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/" - "rsa_pss_3072_sha256_mgf1_32_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_3072_sha256_mgf1_32_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/" - "rsa_pss_4096_sha256_mgf1_32_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_4096_sha256_mgf1_32_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/" - "rsa_pss_4096_sha512_mgf1_32_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_4096_sha512_mgf1_32_test.txt", + EVP_pkey_rsa()); RunWycheproofVerifyTest( - "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt"); + "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt", + EVP_pkey_rsa()); } void RunWycheproofDecryptTest(