diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 2ef8051e1a..d76c077130 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -418,6 +418,7 @@ add_library( evp_extra/p_dsa.c evp_extra/p_dsa_asn1.c evp_extra/p_ec_asn1.c + evp_extra/p_ed25519ph.c evp_extra/p_ed25519_asn1.c evp_extra/p_hmac_asn1.c evp_extra/p_kem_asn1.c diff --git a/crypto/evp_extra/evp_test.cc b/crypto/evp_extra/evp_test.cc index dc278256bb..ef8f8bb492 100644 --- a/crypto/evp_extra/evp_test.cc +++ b/crypto/evp_extra/evp_test.cc @@ -1529,3 +1529,280 @@ TEST(EVPTest, PKEY_asn1_find_str) { ASSERT_FALSE(ameth); ASSERT_FALSE(EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, &pinfo, &pem_str, ameth)); } + +TEST(EVPTest, ED25519PH) { + const uint8_t message[] = {0x72, 0x61, 0x63, 0x63, 0x6f, 0x6f, 0x6e}; + const uint8_t context[] = {0x73, 0x6e, 0x65, 0x61, 0x6b, 0x79}; + const uint8_t message_sha512[] = { + 0x50, 0xcf, 0x03, 0x79, 0x8c, 0xb2, 0xfb, 0x0f, 0xf1, 0x3d, 0xc6, + 0x4c, 0x7c, 0xf0, 0x89, 0x8f, 0xfe, 0x90, 0x9d, 0xfd, 0xa5, 0x22, + 0xdd, 0x22, 0xf4, 0x10, 0x8f, 0xa0, 0x1b, 0x8f, 0x29, 0x15, 0x98, + 0x60, 0xf2, 0x80, 0x0e, 0x7c, 0x93, 0x3c, 0x7c, 0x6e, 0x4c, 0xb1, + 0xf9, 0x3f, 0x33, 0xbe, 0x43, 0xa3, 0xd4, 0x1c, 0x86, 0x92, 0x2b, + 0x32, 0xaf, 0x89, 0xa2, 0xa4, 0xa3, 0xe2, 0xf1, 0x92}; + + bssl::UniquePtr pkey(nullptr); + bssl::UniquePtr pubkey(nullptr); + bssl::ScopedCBB marshalled_private_key; + bssl::ScopedCBB marshalled_public_key; + uint8_t signature[ED25519_SIGNATURE_LEN] = {0}; + size_t signature_len = ED25519_SIGNATURE_LEN; + uint8_t working_signature[ED25519_SIGNATURE_LEN] = {0}; + size_t working_signature_len = ED25519_SIGNATURE_LEN; + + { + bssl::UniquePtr ctx( + EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519PH, nullptr)); + ASSERT_FALSE(EVP_PKEY_keygen_init(ctx.get())); + } + + { + bssl::UniquePtr ctx( + EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr)); + ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get())); + EVP_PKEY *pkey_ptr = nullptr; + ASSERT_TRUE(EVP_PKEY_keygen(ctx.get(), &pkey_ptr)); + ASSERT_NE(pkey_ptr, nullptr); + pkey.reset(pkey_ptr); // now owns pkey_ptr + // marshal the keys + ASSERT_TRUE(CBB_init(marshalled_private_key.get(), 0)); + ASSERT_TRUE(CBB_init(marshalled_public_key.get(), 0)); + ASSERT_TRUE( + EVP_marshal_private_key(marshalled_private_key.get(), pkey.get())); + ASSERT_TRUE( + EVP_marshal_public_key(marshalled_public_key.get(), pkey.get())); + } + + { + uint8_t raw_key[ED25519_PRIVATE_KEY_SEED_LEN]; + size_t raw_key_len = sizeof(raw_key); + ASSERT_TRUE(EVP_PKEY_get_raw_private_key(pkey.get(), raw_key, &raw_key_len)); + + EVP_PKEY *rk = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519PH, nullptr, raw_key, raw_key_len); + ASSERT_TRUE(rk); + pkey.reset(rk); + ASSERT_EQ(EVP_PKEY_ED25519PH, EVP_PKEY_id(pkey.get())); + + bssl::ScopedCBB temp; + ASSERT_TRUE(CBB_init(temp.get(), 0)); + ASSERT_FALSE(EVP_marshal_private_key(temp.get(), pkey.get())); + } + + { + uint8_t raw_key[ED25519_PUBLIC_KEY_LEN]; + size_t raw_key_len = sizeof(raw_key); + ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pkey.get(), raw_key, &raw_key_len)); + + EVP_PKEY *rk = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519PH, nullptr, raw_key, raw_key_len); + ASSERT_TRUE(rk); + pubkey.reset(rk); + ASSERT_EQ(EVP_PKEY_ED25519PH, EVP_PKEY_id(pubkey.get())); + + bssl::ScopedCBB temp; + ASSERT_TRUE(CBB_init(temp.get(), 0)); + ASSERT_FALSE(EVP_marshal_public_key(temp.get(), pubkey.get())); + } + + // prehash signature w/ context gen and verify + { + bssl::UniquePtr md_ctx(EVP_MD_CTX_new()); + EVP_PKEY_CTX *pctx = nullptr; + + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pctx, EVP_sha512(), nullptr, + pkey.get())); + + ASSERT_TRUE( + EVP_PKEY_CTX_set_signature_context(pctx, context, sizeof(context))); + const uint8_t *sctx = NULL; + size_t sctx_len = 0; + ASSERT_TRUE(EVP_PKEY_CTX_get0_signature_context(pctx, &sctx, &sctx_len)); + ASSERT_TRUE(sctx); + ASSERT_NE(sctx, context); + ASSERT_EQ(Bytes(context, sizeof(context)), Bytes(sctx, sctx_len)); + + ASSERT_TRUE(EVP_DigestSignUpdate(md_ctx.get(), &message[0], 3)); + ASSERT_TRUE( + EVP_DigestSignUpdate(md_ctx.get(), &message[3], sizeof(message) - 3)); + ASSERT_TRUE(EVP_DigestSignFinal(md_ctx.get(), signature, + &signature_len)); + ASSERT_EQ(signature_len, (size_t)ED25519_SIGNATURE_LEN); + + ASSERT_TRUE(EVP_DigestVerifyInit(md_ctx.get(), &pctx, EVP_sha512(), nullptr, + pubkey.get())); + ASSERT_TRUE( + EVP_PKEY_CTX_set_signature_context(pctx, context, sizeof(context))); + ASSERT_TRUE(EVP_DigestVerifyUpdate(md_ctx.get(), &message[0], 3)); + ASSERT_TRUE( + EVP_DigestVerifyUpdate(md_ctx.get(), &message[3], sizeof(message) - 3)); + ASSERT_TRUE(EVP_DigestVerifyFinal(md_ctx.get(), + signature, signature_len)); + } + + // prehash signature gen and verify w/ context using EVP_PKEY_sign and + // EVP_PKEY_verify directly + { + bssl::UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + ASSERT_TRUE(ctx.get()); + ASSERT_TRUE(EVP_PKEY_sign_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_signature_context(ctx.get(), context, + sizeof(context))); + ASSERT_TRUE(EVP_PKEY_sign(ctx.get(), working_signature, &working_signature_len, message_sha512, sizeof(message_sha512))); + ASSERT_EQ(working_signature_len, (size_t)ED25519_SIGNATURE_LEN); + + ctx.reset(EVP_PKEY_CTX_new(pubkey.get(), nullptr)); + ASSERT_TRUE(ctx.get()); + ASSERT_TRUE(EVP_PKEY_verify_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_signature_context(ctx.get(), context, + sizeof(context))); + ASSERT_TRUE(EVP_PKEY_verify(ctx.get(), working_signature, + working_signature_len, message_sha512, + sizeof(message_sha512))); + + ASSERT_EQ(Bytes(signature, signature_len), + Bytes(working_signature, working_signature_len)); + } + + // prehash signature gen and verify + { + bssl::UniquePtr md_ctx(EVP_MD_CTX_new()); + EVP_PKEY_CTX *pctx; + + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pctx, EVP_sha512(), nullptr, + pkey.get())); + + const uint8_t *sctx = NULL; + size_t sctx_len = 0; + ASSERT_TRUE(EVP_PKEY_CTX_get0_signature_context(pctx, &sctx, &sctx_len)); + ASSERT_EQ(sctx, nullptr); + ASSERT_EQ(sctx_len, (size_t)0); + + ASSERT_TRUE(EVP_DigestSignUpdate(md_ctx.get(), &message[0], 3)); + ASSERT_TRUE( + EVP_DigestSignUpdate(md_ctx.get(), &message[3], sizeof(message) - 3)); + ASSERT_TRUE(EVP_DigestSignFinal(md_ctx.get(), working_signature, + &working_signature_len)); + ASSERT_EQ(working_signature_len, (size_t)ED25519_SIGNATURE_LEN); + + ASSERT_TRUE(EVP_DigestVerifyInit(md_ctx.get(), nullptr, EVP_sha512(), + nullptr, pubkey.get())); + ASSERT_TRUE(EVP_DigestVerifyUpdate(md_ctx.get(), message, 3)); + ASSERT_TRUE( + EVP_DigestVerifyUpdate(md_ctx.get(), &message[3], sizeof(message) - 3)); + ASSERT_TRUE(EVP_DigestVerifyFinal(md_ctx.get(), working_signature, + working_signature_len)); + } + + // Pre-hash signature w/ context should not match Pre-hash signature w/o context + ASSERT_NE(Bytes(signature, signature_len), + Bytes(working_signature, working_signature_len)); + + + // prehash signature gen and verify with EVP_PKEY_sign and EVP_PKEY_verify directly + { + OPENSSL_memcpy(signature, working_signature, working_signature_len); + signature_len = working_signature_len; + + bssl::UniquePtr ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + ASSERT_TRUE(ctx.get()); + ASSERT_TRUE(EVP_PKEY_sign_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_sign(ctx.get(), working_signature, &working_signature_len, message_sha512, sizeof(message_sha512))); + ASSERT_EQ(working_signature_len, (size_t)ED25519_SIGNATURE_LEN); + + ctx.reset(EVP_PKEY_CTX_new(pubkey.get(), nullptr)); + ASSERT_TRUE(ctx.get()); + ASSERT_TRUE(EVP_PKEY_verify_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_verify(ctx.get(), working_signature, working_signature_len, message_sha512, sizeof(message_sha512))); + + ASSERT_EQ(Bytes(signature, signature_len), + Bytes(working_signature, working_signature_len)); + } + + + { + CBS cbs; + CBS_init(&cbs, CBB_data(marshalled_private_key.get()), + CBB_len(marshalled_private_key.get())); + EVP_PKEY *parsed = EVP_parse_private_key(&cbs); + ASSERT_TRUE(parsed); + pkey.reset(parsed); + ASSERT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(pkey.get())); + } + + { + CBS cbs; + CBS_init(&cbs, CBB_data(marshalled_public_key.get()), + CBB_len(marshalled_public_key.get())); + EVP_PKEY *parsed = EVP_parse_public_key(&cbs); + ASSERT_TRUE(parsed); + pubkey.reset(parsed); + ASSERT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(pubkey.get())); + } + + // pure signature gen and verify + { + bssl::UniquePtr md_ctx(EVP_MD_CTX_new()); + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, nullptr, nullptr, + pkey.get())); + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), working_signature, + &working_signature_len, message, sizeof(message))); + ASSERT_EQ(working_signature_len, (size_t)ED25519_SIGNATURE_LEN); + + ASSERT_TRUE(EVP_DigestVerifyInit(md_ctx.get(), nullptr, nullptr, nullptr, + pubkey.get())); + ASSERT_TRUE(EVP_DigestVerify(md_ctx.get(), working_signature, + working_signature_len, message, sizeof(message))); + } + + // pure signature shouldn't match a pre-hash signature w/o context + ASSERT_NE(Bytes(signature, signature_len), + Bytes(working_signature, working_signature_len)); +} + +TEST(EVPTest, Ed25519phTestVectors) { + FileTestGTest("crypto/fipsmodule/curve25519/ed25519ph_tests.txt", [](FileTest *t) { + std::vector seed, q, message, context, expected_signature; + ASSERT_TRUE(t->GetBytes(&seed, "SEED")); + ASSERT_EQ(32u, seed.size()); + ASSERT_TRUE(t->GetBytes(&q, "Q")); + ASSERT_EQ(32u, q.size()); + ASSERT_TRUE(t->GetBytes(&message, "MESSAGE")); + ASSERT_TRUE(t->GetBytes(&expected_signature, "SIGNATURE")); + ASSERT_EQ(64u, expected_signature.size()); + + if (t->HasAttribute("CONTEXT")) { + t->GetBytes(&context, "CONTEXT"); + } else { + context = std::vector(); + } + + bssl::UniquePtr pkey(EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519PH, nullptr, seed.data(), seed.size())); + bssl::UniquePtr pubkey(EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519PH, nullptr, q.data(), q.size())); + ASSERT_TRUE(pkey.get()); + ASSERT_TRUE(pubkey.get()); + ASSERT_EQ(EVP_PKEY_ED25519PH, EVP_PKEY_id(pkey.get())); + ASSERT_EQ(EVP_PKEY_ED25519PH, EVP_PKEY_id(pubkey.get())); + + bssl::UniquePtr md_ctx(EVP_MD_CTX_new()); + EVP_PKEY_CTX *pctx = nullptr; + uint8_t signature[ED25519_SIGNATURE_LEN] = {}; + size_t signature_len = ED25519_SIGNATURE_LEN; + + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pctx, EVP_sha512(), nullptr, + pkey.get())); + ASSERT_TRUE( + EVP_PKEY_CTX_set_signature_context(pctx, context.data(), context.size())); + ASSERT_TRUE(EVP_DigestSignUpdate(md_ctx.get(), message.data(), message.size())); + ASSERT_TRUE(EVP_DigestSignFinal(md_ctx.get(), signature, + &signature_len)); + ASSERT_EQ(signature_len, (size_t)ED25519_SIGNATURE_LEN); + ASSERT_EQ(Bytes(expected_signature), Bytes(signature, signature_len)); + + ASSERT_TRUE(EVP_DigestVerifyInit(md_ctx.get(), &pctx, EVP_sha512(), nullptr, + pubkey.get())); + ASSERT_TRUE( + EVP_PKEY_CTX_set_signature_context(pctx, context.data(), context.size())); + ASSERT_TRUE(EVP_DigestVerifyUpdate(md_ctx.get(), message.data(), message.size())); + ASSERT_TRUE(EVP_DigestVerifyFinal(md_ctx.get(), signature, + signature_len)); + }); +} diff --git a/crypto/evp_extra/internal.h b/crypto/evp_extra/internal.h index f8cbff80a5..18e9671924 100644 --- a/crypto/evp_extra/internal.h +++ b/crypto/evp_extra/internal.h @@ -11,7 +11,6 @@ #define PKCS8_VERSION_ONE 0 #define PKCS8_VERSION_TWO 1 -#define ED25519_PUBLIC_KEY_OFFSET 32 typedef struct { uint8_t pub[32]; @@ -31,6 +30,7 @@ extern const EVP_PKEY_ASN1_METHOD pqdsa_asn1_meth; extern const EVP_PKEY_ASN1_METHOD kem_asn1_meth; extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519ph_asn1_meth; extern const EVP_PKEY_METHOD x25519_pkey_meth; extern const EVP_PKEY_METHOD hkdf_pkey_meth; @@ -38,6 +38,7 @@ extern const EVP_PKEY_METHOD hmac_pkey_meth; extern const EVP_PKEY_METHOD dh_pkey_meth; extern const EVP_PKEY_METHOD dsa_pkey_meth; extern const EVP_PKEY_METHOD pqdsa_pkey_meth; +extern const EVP_PKEY_METHOD ed25519ph_pkey_meth; // evp_pkey_set_method behaves like |EVP_PKEY_set_type|, but takes a pointer to // a method table. This avoids depending on every |EVP_PKEY_ASN1_METHOD|. diff --git a/crypto/evp_extra/p_ed25519_asn1.c b/crypto/evp_extra/p_ed25519_asn1.c index 14c4cfdf8e..488c64452b 100644 --- a/crypto/evp_extra/p_ed25519_asn1.c +++ b/crypto/evp_extra/p_ed25519_asn1.c @@ -66,7 +66,7 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *privkey, } static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { - if (len != 32) { + if (len != ED25519_PUBLIC_KEY_LEN) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return 0; } @@ -76,7 +76,7 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { return 0; } - OPENSSL_memcpy(key->key + ED25519_PUBLIC_KEY_OFFSET, in, 32); + OPENSSL_memcpy(key->key + ED25519_PUBLIC_KEY_OFFSET, in, ED25519_PUBLIC_KEY_LEN); key->has_private = 0; ed25519_free(pkey); @@ -93,7 +93,7 @@ static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, } if (out == NULL) { - *out_len = 32; + *out_len = ED25519_PRIVATE_KEY_SEED_LEN; return 1; } @@ -103,7 +103,7 @@ static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, } // The raw private key format is the first 32 bytes of the private key. - OPENSSL_memcpy(out, key->key, 32); + OPENSSL_memcpy(out, key->key, ED25519_PRIVATE_KEY_SEED_LEN); *out_len = 32; return 1; } @@ -112,16 +112,16 @@ static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { const ED25519_KEY *key = pkey->pkey.ptr; if (out == NULL) { - *out_len = 32; + *out_len = ED25519_PUBLIC_KEY_LEN; return 1; } - if (*out_len < 32) { + if (*out_len < ED25519_PUBLIC_KEY_LEN) { OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); return 0; } - OPENSSL_memcpy(out, key->key + ED25519_PUBLIC_KEY_OFFSET, 32); + OPENSSL_memcpy(out, key->key + ED25519_PUBLIC_KEY_OFFSET, ED25519_PUBLIC_KEY_LEN); *out_len = 32; return 1; } @@ -163,7 +163,7 @@ static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { const ED25519_KEY *a_key = a->pkey.ptr; const ED25519_KEY *b_key = b->pkey.ptr; return OPENSSL_memcmp(a_key->key + ED25519_PUBLIC_KEY_OFFSET, - b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0; + b_key->key + ED25519_PUBLIC_KEY_OFFSET, ED25519_PUBLIC_KEY_LEN) == 0; } static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key, CBS *pubkey) { @@ -281,3 +281,28 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { NULL /* param_cmp */, ed25519_free, }; + +const EVP_PKEY_ASN1_METHOD ed25519ph_asn1_meth = { + EVP_PKEY_ED25519PH, + {0xFF}, /* oid */ + 0, /* oid_len */ + "ED25519ph", /* pem_str */ + "OpenSSL ED25519ph algorithm", /* info */ + NULL, /* pub_decode */ + NULL, /* pub_encode */ + NULL, /* pub_cmp */ + NULL, /* priv_decode */ + NULL, /* priv_encode */ + NULL, /* priv_encode_v2 */ + ed25519_set_priv_raw, + ed25519_set_pub_raw, + ed25519_get_priv_raw, + ed25519_get_pub_raw, + NULL /* pkey_opaque */, + ed25519_size, + ed25519_bits, + NULL /* param_missing */, + NULL /* param_copy */, + NULL /* param_cmp */, + ed25519_free, +}; diff --git a/crypto/evp_extra/p_ed25519ph.c b/crypto/evp_extra/p_ed25519ph.c new file mode 100644 index 0000000000..eda1306206 --- /dev/null +++ b/crypto/evp_extra/p_ed25519ph.c @@ -0,0 +1,166 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + +typedef struct { + uint8_t context[255]; + size_t context_len; +} ED25519PH_PKEY_CTX; + +static int pkey_ed25519ph_init(EVP_PKEY_CTX *ctx) { + ED25519PH_PKEY_CTX *dctx = OPENSSL_zalloc(sizeof(ED25519PH_PKEY_CTX)); + if (dctx == NULL) { + return 0; + } + ctx->data = dctx; + return 1; +} + +static void pkey_ed25519ph_cleanup(EVP_PKEY_CTX *ctx) { + ED25519PH_PKEY_CTX *dctx = ctx->data; + if (!dctx) { + return; + } + + OPENSSL_free(dctx); +} + +static int pkey_ed25519ph_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { + if (!pkey_ed25519ph_init(dst)) { + return 0; + } + + ED25519PH_PKEY_CTX *dctx = dst->data; + ED25519PH_PKEY_CTX *sctx = src->data; + GUARD_PTR(dctx); + GUARD_PTR(sctx); + + OPENSSL_memcpy(dctx->context, sctx->context, sizeof(sctx->context)); + dctx->context_len = sctx->context_len; + + return 1; +} + +static int pkey_ed25519ph_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (sig == NULL) { + *siglen = ED25519_SIGNATURE_LEN; + return 1; + } + + if (*siglen < ED25519_SIGNATURE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if(tbslen < SHA512_DIGEST_LENGTH) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + ED25519PH_PKEY_CTX *dctx = ctx->data; + GUARD_PTR(dctx); + + if (!ED25519ph_sign_digest(sig, tbs, key->key, dctx->context, dctx->context_len)) { + return 0; + } + + *siglen = ED25519_SIGNATURE_LEN; + return 1; +} + +static int pkey_ed25519ph_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + ED25519PH_PKEY_CTX *dctx = ctx->data; + GUARD_PTR(dctx); + + if (siglen != ED25519_SIGNATURE_LEN || tbslen < SHA512_DIGEST_LENGTH || + !ED25519ph_verify_digest(tbs, sig, + key->key + ED25519_PUBLIC_KEY_OFFSET, dctx->context, dctx->context_len)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); + return 0; + } + + return 1; +} + +static int pkey_ed25519ph_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + GUARD_PTR(ctx); + ED25519PH_PKEY_CTX *dctx = (ED25519PH_PKEY_CTX *)ctx->data; + switch (type) { + case EVP_PKEY_CTRL_MD: { + const EVP_MD *md = p2; + int md_type = EVP_MD_type(md); + // MUST be SHA-512 + if (md_type != NID_sha512) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + break; + } + case EVP_PKEY_CTRL_SIGNING_CONTEXT: { + EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS *params = p2; + if (!params || !dctx || params->context_len > sizeof(dctx->context)) { + return 0; + } + OPENSSL_memcpy(dctx->context, params->context, params->context_len); + dctx->context_len = params->context_len; + break; + } + case EVP_PKEY_CTRL_GET_SIGNING_CONTEXT: { + EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS *params = p2; + if (!params || !dctx) { + return 0; + } + if(dctx->context_len == 0) { + params->context = NULL; + params->context_len = 0; + } else { + params->context = dctx->context; + params->context_len = dctx->context_len; + } + return 1; + } + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + return 1; +} + +const EVP_PKEY_METHOD ed25519ph_pkey_meth = { + .pkey_id = EVP_PKEY_ED25519PH, + .init = pkey_ed25519ph_init, + .cleanup = pkey_ed25519ph_cleanup, + .copy = pkey_ed25519ph_copy, + .sign = pkey_ed25519ph_sign, + .verify = pkey_ed25519ph_verify, + .ctrl = pkey_ed25519ph_ctrl +}; diff --git a/crypto/evp_extra/p_methods.c b/crypto/evp_extra/p_methods.c index 6e8f591f03..19fc43d4ce 100644 --- a/crypto/evp_extra/p_methods.c +++ b/crypto/evp_extra/p_methods.c @@ -11,6 +11,7 @@ static const EVP_PKEY_METHOD *const non_fips_pkey_evp_methods[] = { &x25519_pkey_meth, &dh_pkey_meth, &dsa_pkey_meth, + &ed25519ph_pkey_meth }; const EVP_PKEY_ASN1_METHOD *const asn1_evp_pkey_methods[] = { @@ -23,7 +24,8 @@ const EVP_PKEY_ASN1_METHOD *const asn1_evp_pkey_methods[] = { &pqdsa_asn1_meth, &kem_asn1_meth, &hmac_asn1_meth, - &dh_asn1_meth + &dh_asn1_meth, + &ed25519ph_asn1_meth }; const size_t asn1_evp_pkey_methods_size = sizeof(asn1_evp_pkey_methods)/sizeof(asn1_evp_pkey_methods[0]); diff --git a/crypto/fipsmodule/evp/evp.c b/crypto/fipsmodule/evp/evp.c index 496cb3b681..f241054889 100644 --- a/crypto/fipsmodule/evp/evp.c +++ b/crypto/fipsmodule/evp/evp.c @@ -479,6 +479,9 @@ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, case EVP_PKEY_ED25519: method = &ed25519_asn1_meth; break; + case EVP_PKEY_ED25519PH: + method = &ed25519ph_asn1_meth; + break; case EVP_PKEY_HMAC: method = &hmac_asn1_meth; break; @@ -516,6 +519,9 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, case EVP_PKEY_ED25519: method = &ed25519_asn1_meth; break; + case EVP_PKEY_ED25519PH: + method = &ed25519ph_asn1_meth; + break; default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); return 0; @@ -589,6 +595,30 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { 0, (void *)out_md); } +int EVP_PKEY_CTX_set_signature_context(EVP_PKEY_CTX *ctx, + const uint8_t *context, + size_t context_len) { + EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS params = {context, context_len}; + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_SIGNING_CONTEXT, 0, ¶ms); +} + +int EVP_PKEY_CTX_get0_signature_context(EVP_PKEY_CTX *ctx, + const uint8_t **context, + size_t *context_len) { + GUARD_PTR(context); + GUARD_PTR(context_len); + EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS params = {NULL, 0}; + if (!EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_SIGNING_CONTEXT, 0, ¶ms)) { + return 0; + } + *context = params.context; + *context_len = params.context_len; + return 1; +} + + void *EVP_PKEY_get0(const EVP_PKEY *pkey) { SET_DIT_AUTO_RESET; GUARD_PTR(pkey); diff --git a/crypto/fipsmodule/evp/internal.h b/crypto/fipsmodule/evp/internal.h index d5186af738..454d1c4294 100644 --- a/crypto/fipsmodule/evp/internal.h +++ b/crypto/fipsmodule/evp/internal.h @@ -207,6 +207,8 @@ int EVP_RSA_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void * #define EVP_PKEY_CTRL_MD 1 #define EVP_PKEY_CTRL_GET_MD 2 +#define EVP_PKEY_CTRL_SIGNING_CONTEXT 3 +#define EVP_PKEY_CTRL_GET_SIGNING_CONTEXT 4 // EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|: // 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key. @@ -382,8 +384,8 @@ void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); #define ED25519_PUBLIC_KEY_OFFSET 32 #define FIPS_EVP_PKEY_METHODS 8 -#define NON_FIPS_EVP_PKEY_METHODS 3 -#define ASN1_EVP_PKEY_METHODS 10 +#define NON_FIPS_EVP_PKEY_METHODS 4 +#define ASN1_EVP_PKEY_METHODS 11 struct fips_evp_pkey_methods { const EVP_PKEY_METHOD * methods[FIPS_EVP_PKEY_METHODS]; @@ -397,6 +399,12 @@ const EVP_PKEY_METHOD *EVP_PKEY_hmac_pkey_meth(void); const EVP_PKEY_METHOD *EVP_PKEY_ed25519_pkey_meth(void); const EVP_PKEY_METHOD *EVP_PKEY_kem_pkey_meth(void); const EVP_PKEY_METHOD *EVP_PKEY_pqdsa_pkey_meth(void); +const EVP_PKEY_METHOD *EVP_PKEY_ed25519ph_pkey_meth(void); + +struct evp_pkey_ctx_signature_context_params_st { + const uint8_t *context; + size_t context_len; +}; // EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS #if defined(__cplusplus) } // extern C diff --git a/crypto/fipsmodule/self_check/self_check.c b/crypto/fipsmodule/self_check/self_check.c index 8f3be51cd1..1ff3ba4921 100644 --- a/crypto/fipsmodule/self_check/self_check.c +++ b/crypto/fipsmodule/self_check/self_check.c @@ -799,83 +799,107 @@ static int boringssl_self_test_ffdh(void) { static int boringssl_self_test_ml_kem(void) { int ret = 0; - const uint8_t kKeyGenSeed[MLKEM512_KEYGEN_SEED_LEN] = { + static const uint8_t kKeyGenEKSeed[MLKEM512_KEYGEN_SEED_LEN] = { + 0xf8, 0x8c, 0xb2, 0x5f, 0x89, 0xa3, 0x55, 0x5f, 0xae, 0xc6, 0x71, 0xa1, + 0xdf, 0xc6, 0xf6, 0x1d, 0x60, 0xd0, 0x62, 0x22, 0x7d, 0x6a, 0x8f, 0xf6, + 0x2b, 0x3c, 0x6d, 0x7b, 0xd6, 0x14, 0x0f, 0x66, 0x24, 0xc0, 0x84, 0xa6, + 0x4d, 0xa7, 0x4c, 0x63, 0x32, 0x7e, 0x11, 0x77, 0x58, 0xaa, 0x33, 0x8a, + 0x02, 0xe4, 0x43, 0x74, 0x10, 0xb8, 0xf9, 0xf2, 0x00, 0x88, 0xa1, 0x29, + 0xc1, 0x68, 0x3d, 0xe7 + }; + static const uint8_t kKeyGenEK[MLKEM512_PUBLIC_KEY_BYTES] = { + 0xa7, 0xcc, 0x68, 0xf8, 0xd0, 0x21, 0x10, 0xca, 0x57, 0x20, 0x22, 0x3b, + 0x9e, 0x2a, 0x89, 0x87, 0xc8, 0xa2, 0x48, 0x35, 0xa2, 0x0d, 0xab, 0xcb, + 0xef, 0xa4, 0x30, 0xe7, 0x4a, 0x85, 0xaf, 0x80, 0xb9, 0xb7, 0x4b, 0x74, + 0x57, 0x4c, 0x5e, 0x5f, 0x58, 0x54, 0x59, 0xca, 0x36, 0x10, 0x94, 0x0f, + 0x0b, 0x57, 0xb3, 0x33, 0x44, 0xce, 0xac, 0xcc, 0xc1, 0x35, 0x55, 0x7b, + 0x82, 0xf4, 0x96, 0x86, 0x88, 0xa0, 0x16, 0x8c, 0x1a, 0xa2, 0x94, 0x0e, + 0x56, 0x04, 0x48, 0x2b, 0xf8, 0xb9, 0x00, 0xa4, 0x34, 0x30, 0x96, 0x44, + 0x63, 0x30, 0xcf, 0xee, 0x10, 0x91, 0x7c, 0x03, 0x38, 0x18, 0x1b, 0x7f, + 0xe8, 0xd3, 0x0f, 0x48, 0x16, 0x08, 0x7d, 0x62, 0x99, 0xf2, 0x25, 0x41, + 0x7f, 0x53, 0x3e, 0xe4, 0x04, 0x73, 0x89, 0x48, 0x47, 0xbd, 0x45, 0x29, + 0x13, 0x67, 0xbe, 0x6b, 0x1a, 0x7d, 0xee, 0x55, 0xbb, 0x21, 0xd6, 0x0e, + 0x38, 0x28, 0x55, 0x2f, 0x4c, 0x8a, 0x6f, 0x3c, 0x54, 0xfc, 0x74, 0xcf, + 0x67, 0xa6, 0x14, 0xee, 0xab, 0x00, 0x2a, 0x07, 0x68, 0x51, 0x87, 0x9c, + 0xef, 0x22, 0x18, 0xfd, 0xb3, 0x76, 0x61, 0x23, 0xc2, 0xde, 0x32, 0xa2, + 0x69, 0xb6, 0xaa, 0x46, 0x61, 0xb6, 0x93, 0x70, 0x31, 0x4c, 0x00, 0x44, + 0x46, 0xf7, 0x25, 0x8c, 0x40, 0xb2, 0xea, 0x78, 0x9f, 0x40, 0xca, 0x02, + 0x3b, 0xbb, 0x12, 0x17, 0xc2, 0xc4, 0x4b, 0x38, 0x0c, 0x6e, 0x31, 0x94, + 0xed, 0xd1, 0x29, 0xd0, 0x39, 0x21, 0x8d, 0x9b, 0x75, 0x19, 0x4a, 0x38, + 0x6d, 0x94, 0x4a, 0xcc, 0xe7, 0xa9, 0x72, 0x0a, 0xb0, 0x26, 0x36, 0x20, + 0x04, 0xe9, 0x5b, 0xf9, 0x22, 0x92, 0x90, 0xb5, 0x36, 0x13, 0x41, 0x60, + 0x82, 0xe8, 0x2b, 0xa8, 0xa4, 0x2a, 0x5f, 0xf1, 0x47, 0x59, 0xf5, 0x77, + 0x12, 0x39, 0x57, 0x06, 0xb3, 0x07, 0xf7, 0x63, 0x5e, 0xce, 0xe4, 0x23, + 0x17, 0xa4, 0x8e, 0xb3, 0xb9, 0x06, 0x83, 0xf3, 0xab, 0x53, 0xd1, 0x7c, + 0x50, 0xf5, 0x3c, 0x6c, 0xfb, 0x1c, 0x0c, 0xf5, 0x9d, 0x6f, 0x2a, 0x98, + 0x10, 0x21, 0x42, 0x8a, 0x7a, 0xc5, 0xed, 0xf1, 0x3b, 0x26, 0x84, 0x4d, + 0x83, 0xc3, 0x1d, 0x36, 0x08, 0x71, 0x0e, 0x62, 0x3a, 0xab, 0xb2, 0x4b, + 0x6c, 0x5b, 0x48, 0xba, 0xeb, 0xc1, 0xb3, 0x07, 0x89, 0x72, 0x58, 0x92, + 0x01, 0xb7, 0xa3, 0x0b, 0xc0, 0x93, 0x15, 0x61, 0x2b, 0x06, 0x76, 0x55, + 0xbe, 0xc4, 0x03, 0xa6, 0x9c, 0x89, 0xeb, 0x13, 0x7c, 0x31, 0x15, 0x79, + 0x71, 0x09, 0x8c, 0xb6, 0x93, 0xba, 0x4a, 0xe9, 0xae, 0x40, 0xa8, 0x03, + 0x1c, 0xec, 0x92, 0x58, 0x0b, 0xcc, 0x1b, 0x5a, 0xb3, 0xec, 0xd1, 0xaa, + 0x5f, 0x79, 0xaa, 0x2c, 0xd6, 0x92, 0x49, 0xd1, 0x38, 0xc8, 0x96, 0x5a, + 0x81, 0xc8, 0x7a, 0x07, 0xeb, 0x59, 0xa4, 0x61, 0x2e, 0x60, 0x65, 0x8f, + 0x4d, 0xf0, 0x28, 0xce, 0xf8, 0xaf, 0x1b, 0x83, 0x7e, 0x0a, 0xb0, 0xbf, + 0xed, 0xb7, 0x26, 0x90, 0x42, 0x90, 0xd0, 0xbc, 0x41, 0xdf, 0x6a, 0x67, + 0xf7, 0xa4, 0x16, 0x66, 0x09, 0x95, 0x24, 0x39, 0x63, 0x19, 0x60, 0x64, + 0x8e, 0x22, 0x9a, 0x21, 0xf2, 0xa4, 0xd8, 0x2a, 0xba, 0xd3, 0xec, 0x81, + 0x35, 0xdc, 0x9b, 0xb4, 0x3c, 0x70, 0x3d, 0x3b, 0x33, 0xe4, 0x37, 0xc9, + 0xef, 0x7b, 0xca, 0x91, 0xc3, 0x46, 0x56, 0x76, 0x74, 0x01, 0x25, 0xa1, + 0x5a, 0xd1, 0x70, 0x70, 0x88, 0xb1, 0x01, 0xb4, 0x27, 0x3d, 0x3c, 0x4b, + 0xf3, 0x01, 0x81, 0xb4, 0xb2, 0x57, 0x5d, 0xe7, 0x5c, 0xcf, 0xc1, 0x33, + 0x12, 0xa2, 0xa6, 0xbc, 0xeb, 0xc4, 0x77, 0xa9, 0x66, 0x8e, 0x75, 0x16, + 0x29, 0xb5, 0x69, 0xbf, 0xa2, 0x0b, 0xec, 0xa0, 0x98, 0x00, 0x99, 0x2c, + 0x63, 0xf0, 0x4b, 0x6b, 0x4a, 0x7d, 0xf9, 0x77, 0xa0, 0x01, 0x31, 0xc2, + 0xf8, 0x72, 0x2e, 0x51, 0x38, 0x77, 0x52, 0x35, 0xb5, 0x17, 0xa7, 0x09, + 0x85, 0x21, 0x67, 0xc1, 0xd4, 0x15, 0xfd, 0xc7, 0xad, 0x32, 0xf2, 0xaa, + 0xca, 0x43, 0x7e, 0x9c, 0xc6, 0xb2, 0x48, 0xd9, 0xca, 0x7c, 0x65, 0xb4, + 0x05, 0xe6, 0x8d, 0x24, 0xe8, 0x1b, 0x86, 0x88, 0xca, 0xa2, 0x2b, 0x3c, + 0xf5, 0xc9, 0xb1, 0x47, 0xf0, 0xcc, 0x27, 0xe6, 0x67, 0xa8, 0x0b, 0x83, + 0xcc, 0xbb, 0x4f, 0x41, 0x61, 0xa5, 0xff, 0xd0, 0x19, 0x4b, 0x1b, 0x57, + 0x20, 0xe6, 0x8e, 0xa0, 0xf5, 0x99, 0x97, 0xf2, 0x67, 0x40, 0x97, 0x2d, + 0x2c, 0x81, 0x24, 0xd7, 0xa6, 0xad, 0x83, 0x27, 0xc2, 0x07, 0x5a, 0x3f, + 0x76, 0xb9, 0x68, 0xd2, 0xaa, 0xad, 0x19, 0xc0, 0x06, 0x97, 0x59, 0x9e, + 0x0b, 0xe4, 0x9f, 0xa6, 0xd6, 0x5b, 0x40, 0x88, 0xb0, 0xbe, 0x69, 0x2d, + 0xcd, 0xa0, 0x28, 0x09, 0x58, 0x52, 0xa0, 0xd7, 0x20, 0x5e, 0x44, 0x17, + 0x40, 0x9c, 0x03, 0x17, 0x78, 0x03, 0x05, 0xa8, 0x78, 0xfb, 0x58, 0x29, + 0x63, 0xb6, 0x95, 0x3f, 0x6b, 0x8f, 0x08, 0x80, 0xb0, 0x50, 0x17, 0x83, + 0x01, 0xd6, 0x59, 0xbe, 0x3a, 0x4d, 0xb7, 0xe0, 0xbf, 0x25, 0x87, 0x12, + 0x91, 0x64, 0x17, 0x8f, 0x32, 0x70, 0x7d, 0x40, 0x39, 0x2d, 0x85, 0x71, + 0x3d, 0xea, 0x82, 0x91, 0x39, 0x99, 0xaa, 0x6c, 0x35, 0xaa, 0x94, 0xb3, + 0x54, 0x7a, 0xbe, 0x40, 0xe2, 0xb0, 0xba, 0x82, 0xb5, 0xb7, 0x83, 0x19, + 0x18, 0x2a, 0x5a, 0x47, 0xd1, 0x73, 0x17, 0x6b, 0xa6, 0xfa, 0x3a, 0x4d, + 0x70, 0xa8, 0x13, 0x0b, 0x31, 0x07, 0x43, 0xfa, 0x8a, 0xaa, 0xe3, 0x14, + 0x38, 0x1c, 0x9b, 0x7f, 0x49, 0x99, 0x1f, 0x19, 0xa4, 0xff, 0x83, 0x69, + 0x63, 0x8d, 0xe3, 0x80, 0xb5, 0xd8, 0x28, 0xb7, 0xb5, 0xfc, 0xfd, 0xd9, + 0x1f, 0xe6, 0x8e, 0xfe, 0x16, 0xd4, 0xcd, 0x9e, 0xed, 0x66, 0xd6, 0x5c, + 0x1d, 0x2d, 0x8c, 0xaf, 0x5a, 0xf4, 0xa6, 0x92}; + uint8_t keygen_decaps[MLKEM512_SECRET_KEY_BYTES] = {0}; + uint8_t keygen_encaps[MLKEM512_PUBLIC_KEY_BYTES] = {0}; + + if (ml_kem_512_keypair_deterministic_no_self_test( + keygen_encaps, keygen_decaps, kKeyGenEKSeed) || + !check_test(kKeyGenEK, keygen_encaps, sizeof(keygen_encaps), + "ML-KEM-keyGen-encaps")) { + goto err; + } + + // Use a separate seed for the decaps key so break-kat.go doesn't get confused + // about having two copies of the encaps key due to the way the decaps key is + // defined: FIPS 203 section 6.1 + // dk = (dkPKE‖ek‖H(ek)‖𝑧) + // where dkPKE is the secret key, ek is the public key, and z is the hash of + // the public key + static const uint8_t kKeyGenDKSeed[MLKEM512_KEYGEN_SEED_LEN] = { 0xec, 0xdb, 0x97, 0x62, 0xf4, 0x78, 0xb2, 0xfa, 0x26, 0x3d, 0xf4, 0x6d, 0xe4, 0x47, 0xf3, 0xd1, 0x52, 0xa1, 0xbc, 0x0e, 0x02, 0xee, 0x95, 0x36, 0x77, 0x30, 0x11, 0x64, 0xd1, 0x5d, 0x20, 0xd7, 0x1b, 0x07, 0x4b, 0xff, 0x80, 0x44, 0x44, 0x5e, 0x11, 0x66, 0x0b, 0x1b, 0x6b, 0x26, 0xdf, 0x24, 0x2b, 0x8f, 0xc0, 0x2b, 0x9e, 0x8d, 0xf5, 0x38, 0xdb, 0x17, 0xa6, 0x39, 0xd7, 0xc4, 0x61, 0x32 - }; - const uint8_t kKeyGenEK[MLKEM512_PUBLIC_KEY_BYTES] = { - 0xe9, 0xe0, 0x22, 0x0a, 0x69, 0x45, 0x56, 0xbc, 0x0a, 0x4b, 0x5a, 0xad, - 0xe0, 0x32, 0xb2, 0xaa, 0x87, 0x7c, 0x0d, 0xa8, 0x16, 0xef, 0x32, 0xa8, - 0x4d, 0x77, 0xbb, 0xff, 0x46, 0x56, 0xe6, 0x80, 0x85, 0x4e, 0x69, 0x61, - 0xa4, 0x17, 0x08, 0x2b, 0xd4, 0x6f, 0x50, 0x23, 0xc4, 0x7c, 0xea, 0x09, - 0xbb, 0xa2, 0x14, 0x5d, 0x41, 0x51, 0x88, 0xe1, 0x38, 0x03, 0xbb, 0x5e, - 0x7f, 0xc1, 0x9d, 0x39, 0x81, 0x9e, 0x59, 0xca, 0x7f, 0xdc, 0x38, 0x05, - 0x1d, 0x96, 0x94, 0x01, 0xd4, 0xc4, 0x11, 0xda, 0xc0, 0x0a, 0x47, 0xab, - 0x57, 0x52, 0x7d, 0xaa, 0x89, 0x7a, 0x37, 0x75, 0x93, 0x51, 0xb4, 0xb1, - 0x18, 0x5b, 0x14, 0x96, 0xd7, 0x9a, 0xa3, 0x32, 0x29, 0xbe, 0xa3, 0xc0, - 0xe8, 0xdb, 0xcf, 0x1d, 0x7a, 0x64, 0x73, 0x09, 0x28, 0x77, 0x5c, 0x74, - 0xc9, 0x46, 0x18, 0x1b, 0xb8, 0x8e, 0x0a, 0x38, 0xa1, 0x65, 0xeb, 0xbd, - 0xc7, 0x86, 0x0b, 0x01, 0x4c, 0x59, 0x89, 0x4c, 0x72, 0x11, 0xbc, 0x23, - 0xd3, 0x90, 0x77, 0xe6, 0x29, 0x44, 0xd3, 0xc4, 0x8c, 0x43, 0x4b, 0x73, - 0x7b, 0x1a, 0x64, 0xb5, 0xf9, 0xa1, 0x64, 0x6a, 0x18, 0xa5, 0x19, 0x5a, - 0x54, 0x60, 0x3f, 0xfc, 0x28, 0x0b, 0xf5, 0xea, 0x1b, 0xf3, 0xd8, 0xcb, - 0x41, 0x12, 0xaa, 0x82, 0xfa, 0xb8, 0x9e, 0x26, 0x33, 0x66, 0x55, 0x97, - 0xbe, 0xd3, 0x0d, 0xe6, 0xc8, 0x89, 0x7a, 0x96, 0x13, 0xea, 0x8c, 0x11, - 0x73, 0x65, 0x24, 0xa7, 0x08, 0x62, 0x66, 0x52, 0x3f, 0xba, 0xb8, 0x87, - 0x46, 0x54, 0x94, 0xeb, 0xfc, 0x96, 0xfb, 0xe4, 0x46, 0x67, 0x75, 0xbc, - 0x0d, 0x70, 0x7e, 0x62, 0x4b, 0xb3, 0xde, 0x70, 0x0e, 0xaa, 0xc9, 0xb3, - 0x7c, 0x2b, 0xc1, 0x2b, 0x52, 0xaa, 0x2d, 0xfb, 0x73, 0xb7, 0x00, 0x6b, - 0xd9, 0x56, 0xc0, 0xb9, 0x32, 0x4c, 0x47, 0x29, 0x5e, 0x4e, 0x4c, 0x4c, - 0xc4, 0x7b, 0xa9, 0xb5, 0xa8, 0x99, 0x69, 0x4b, 0x38, 0xa6, 0x4a, 0x29, - 0x12, 0x06, 0x84, 0xbf, 0x64, 0xc6, 0x48, 0x21, 0x1b, 0x18, 0xd0, 0x17, - 0xce, 0x34, 0x84, 0x9c, 0x4a, 0x09, 0x2b, 0x24, 0xbc, 0xb8, 0x96, 0x0d, - 0x87, 0x04, 0x22, 0xeb, 0xd9, 0x54, 0xbc, 0x72, 0x64, 0xba, 0x95, 0xa7, - 0x27, 0xa3, 0x19, 0x26, 0xf3, 0x1c, 0x12, 0x38, 0x1d, 0x0d, 0x05, 0x1e, - 0x1e, 0x04, 0x19, 0x0b, 0x94, 0x93, 0x22, 0x44, 0x28, 0x45, 0xf3, 0xaa, - 0x6f, 0xb1, 0x79, 0x40, 0x44, 0x2a, 0x9c, 0x1a, 0x18, 0x3b, 0x23, 0x97, - 0xdc, 0xc0, 0x77, 0x0c, 0xb2, 0xb4, 0xa0, 0x7a, 0xaf, 0x0a, 0xf5, 0x26, - 0x36, 0x77, 0x8a, 0xc9, 0x94, 0x9d, 0x2d, 0xb4, 0x2f, 0x3d, 0x03, 0x6b, - 0xc8, 0x42, 0xb2, 0xf3, 0xb0, 0xb1, 0x1d, 0x27, 0x8e, 0xa0, 0x25, 0xcc, - 0x16, 0xac, 0x8b, 0x69, 0x86, 0xa9, 0xb1, 0x8b, 0x33, 0x56, 0x79, 0x0d, - 0xbc, 0x82, 0x1d, 0x0a, 0xc7, 0xb5, 0xea, 0xe9, 0x65, 0xfc, 0xf1, 0x4b, - 0x0e, 0x20, 0x2b, 0x00, 0xec, 0x5d, 0x70, 0x7c, 0x45, 0xaf, 0x52, 0xbe, - 0x2d, 0x97, 0x71, 0xbc, 0xc5, 0x3b, 0x31, 0xf2, 0x52, 0x5a, 0xb5, 0x3f, - 0x95, 0xa3, 0xb0, 0x02, 0x42, 0xc1, 0x1c, 0x49, 0x4e, 0x25, 0x54, 0x43, - 0x8b, 0x0a, 0x4f, 0x68, 0x19, 0x40, 0x19, 0x18, 0x1b, 0xbd, 0xb1, 0x94, - 0x91, 0x03, 0x07, 0xbc, 0x19, 0xaf, 0xae, 0x55, 0x3d, 0xd6, 0x66, 0x56, - 0x43, 0x32, 0xc0, 0x78, 0x60, 0x4f, 0xbd, 0x8b, 0xc4, 0xfd, 0xc9, 0x2f, - 0x92, 0x01, 0x80, 0x9a, 0xb4, 0x95, 0xc1, 0xb5, 0x35, 0x53, 0x0b, 0xad, - 0x2e, 0xb3, 0x57, 0x53, 0xf9, 0x19, 0x56, 0xb5, 0x8b, 0xfb, 0xf6, 0x2d, - 0x1e, 0x33, 0xc8, 0x61, 0xf7, 0x38, 0x46, 0x33, 0x4c, 0x4a, 0x2a, 0xc5, - 0x57, 0x69, 0x84, 0xef, 0x11, 0x63, 0xa5, 0x04, 0x54, 0xa3, 0xe4, 0xce, - 0x83, 0x88, 0x98, 0xf2, 0x25, 0x86, 0x81, 0x89, 0xbd, 0xae, 0x5a, 0x03, - 0xef, 0xd8, 0x00, 0x1d, 0x2a, 0x9f, 0x55, 0x7c, 0xb6, 0xcd, 0x93, 0xa4, - 0x6f, 0xbb, 0x13, 0x79, 0xd8, 0x16, 0x45, 0xb8, 0x53, 0xcb, 0x98, 0xb4, - 0x7b, 0xa8, 0x7a, 0x66, 0xfc, 0xbc, 0x0a, 0xda, 0x76, 0x50, 0x6b, 0x8d, - 0xcd, 0x65, 0x90, 0x42, 0x64, 0x0e, 0xf6, 0x16, 0x82, 0x0f, 0xf2, 0x0b, - 0x26, 0x43, 0x33, 0x99, 0x37, 0x1d, 0xc4, 0xc5, 0x02, 0x87, 0x34, 0x9c, - 0xa2, 0x76, 0x3e, 0x30, 0x73, 0x86, 0x5c, 0x5b, 0xc9, 0xaa, 0xa1, 0x43, - 0x7b, 0x86, 0xb2, 0x0b, 0x25, 0xb6, 0xf0, 0x88, 0xbd, 0x6a, 0x4c, 0x94, - 0x83, 0x84, 0x2d, 0x7c, 0x65, 0x25, 0x7c, 0xc4, 0x2a, 0xd7, 0xc7, 0xb2, - 0x6f, 0x58, 0xc8, 0xed, 0x19, 0x9b, 0x84, 0x8b, 0x8c, 0x6f, 0x40, 0x8d, - 0x48, 0x76, 0x37, 0x75, 0x18, 0x88, 0xa9, 0x5a, 0x44, 0x9c, 0xab, 0x47, - 0xb7, 0xa2, 0xac, 0xe6, 0xa8, 0x2c, 0x7d, 0x46, 0x91, 0x05, 0x26, 0x41, - 0x4a, 0xb1, 0x49, 0xb1, 0x13, 0x43, 0xb0, 0xea, 0x32, 0xd9, 0x69, 0xa5, - 0x08, 0xa8, 0x1c, 0xf8, 0x96, 0xb0, 0x81, 0x08, 0x7f, 0x4d, 0x52, 0xa2, - 0xa9, 0xe0, 0x77, 0x87, 0x8a, 0x43, 0xe5, 0x97, 0x1d, 0x74, 0x86, 0x3a, - 0x7b, 0xf2, 0x00, 0x37, 0xb2, 0x97, 0x47, 0x03, 0x14, 0x0e, 0xa8, 0x16, - 0x0a, 0x5b, 0xa7, 0x22, 0x27, 0xc1, 0x5b, 0xec, 0x5d, 0xf1, 0x71, 0x14, - 0x01, 0x98, 0x89, 0x6d, 0x31, 0x73, 0x2a, 0x24, 0x1f, 0x5b, 0x93, 0x8f, - 0xf2, 0x33, 0xcb, 0xa2, 0xdc, 0x82, 0xde, 0x91, 0xc6, 0xb4, 0x93, 0x78, - 0x2b, 0x61, 0x63, 0xbc, 0x12, 0x82, 0xdf, 0x85, 0x5e, 0xe6, 0xa6, 0xa6, - 0x59, 0x75, 0xb3, 0x3c, 0xb6, 0xa2, 0x7d, 0x25, 0x8b, 0xd3, 0x17, 0xd0, - 0x4c, 0xef, 0x8e, 0xb5, 0x57, 0xba, 0x02, 0xd4, 0x94, 0x71, 0x92, 0x3c, - 0xd6, 0x0e, 0x99, 0x17, 0x96, 0x6b, 0xe9, 0x0f}; - const uint8_t kKeyGenDK[MLKEM512_SECRET_KEY_BYTES] = { +}; + static const uint8_t kKeyGenDK[MLKEM512_SECRET_KEY_BYTES] = { 0x88, 0xc1, 0x2c, 0xea, 0xa6, 0xcb, 0x91, 0xf5, 0x89, 0xac, 0xb8, 0x6d, 0x91, 0x3c, 0x7a, 0x60, 0xf7, 0xcd, 0xab, 0xe3, 0xb7, 0xb5, 0x90, 0x09, 0x1d, 0x00, 0x84, 0xe2, 0x9a, 0x04, 0x9b, 0x43, 0x68, 0x41, 0xf2, 0x47, @@ -1012,20 +1036,15 @@ static int boringssl_self_test_ml_kem(void) { 0x2f, 0x55, 0xa2, 0x46, 0x1b, 0x07, 0x4b, 0xff, 0x80, 0x44, 0x44, 0x5e, 0x11, 0x66, 0x0b, 0x1b, 0x6b, 0x26, 0xdf, 0x24, 0x2b, 0x8f, 0xc0, 0x2b, 0x9e, 0x8d, 0xf5, 0x38, 0xdb, 0x17, 0xa6, 0x39, 0xd7, 0xc4, 0x61, 0x32}; - - uint8_t keygen_decaps[MLKEM512_SECRET_KEY_BYTES] = {0}; - uint8_t keygen_encaps[MLKEM512_PUBLIC_KEY_BYTES] = {0}; - if (ml_kem_512_keypair_deterministic_no_self_test( - keygen_encaps, keygen_decaps, kKeyGenSeed) || + keygen_encaps, keygen_decaps, kKeyGenDKSeed) || !check_test(kKeyGenDK, keygen_decaps, sizeof(keygen_decaps), - "ML-KEM keyGen decaps") || - !check_test(kKeyGenEK, keygen_encaps, sizeof(keygen_encaps), - "ML-KEM keyGen encaps")) { + "ML-KEM-keyGen-decaps") + ) { goto err; - } + } - const uint8_t kEncapEK[MLKEM512_PUBLIC_KEY_BYTES] = { + static const uint8_t kEncapEK[MLKEM512_PUBLIC_KEY_BYTES] = { 0x57, 0xc3, 0xba, 0x4c, 0xd7, 0x81, 0xd8, 0x69, 0x0b, 0x4c, 0x39, 0x0d, 0x9a, 0x58, 0xb3, 0x5d, 0x69, 0xa5, 0x2d, 0x52, 0xcd, 0x19, 0x01, 0x2a, 0x25, 0xe1, 0x58, 0xa2, 0xc1, 0x9b, 0x75, 0x47, 0x0a, 0x03, 0x9a, 0x05, @@ -1093,11 +1112,11 @@ static int boringssl_self_test_ml_kem(void) { 0x97, 0x3f, 0x15, 0xe7, 0xc5, 0x9b, 0x89, 0x4a, 0xab, 0x27, 0xf5, 0xce, 0xad, 0xdd, 0xe8, 0x25, 0x33, 0x3f, 0x44, 0x03, 0x9b, 0x02, 0xe7, 0xbd, 0xec, 0x21, 0xfc, 0x0d, 0x8f, 0x9b, 0x3a, 0x22}; - const uint8_t kEncapM[MLKEM512_ENCAPS_SEED_LEN] = { + static const uint8_t kEncapM[MLKEM512_ENCAPS_SEED_LEN] = { 0x2c, 0x87, 0xaa, 0x8b, 0x11, 0x76, 0x75, 0x54, 0x74, 0xdf, 0x76, 0x3b, 0x2a, 0xe0, 0x46, 0x35, 0x39, 0xe9, 0x53, 0xe0, 0x04, 0xc4, 0x6a, 0x11, 0x83, 0xfd, 0x53, 0xcf, 0x84, 0xef, 0x81, 0x03}; - const uint8_t kEncapCiphertext[MLKEM512_CIPHERTEXT_BYTES] = { + static const uint8_t kEncapCiphertext[MLKEM512_CIPHERTEXT_BYTES] = { 0x43, 0x1a, 0x4f, 0x1b, 0x2d, 0x2c, 0x6c, 0x00, 0xf1, 0x69, 0x0b, 0xbe, 0x48, 0x25, 0x41, 0xef, 0x3d, 0x56, 0x37, 0x74, 0xda, 0xff, 0x83, 0x20, 0x7f, 0x96, 0xde, 0x7e, 0x5e, 0x4a, 0x59, 0xd5, 0xd9, 0x36, 0xd9, 0x44, @@ -1162,7 +1181,7 @@ static int boringssl_self_test_ml_kem(void) { 0x7d, 0xbe, 0xe8, 0x51, 0x64, 0xe4, 0xc0, 0x99, 0xa2, 0x7a, 0x45, 0x83, 0xe9, 0x24, 0x7d, 0x07, 0x8f, 0x88, 0x30, 0xb4, 0x68, 0x74, 0xc1, 0xb0, 0x10, 0xbf, 0x3c, 0xd9, 0x0e, 0xb0, 0x77, 0x49, 0x61, 0xf2, 0x39, 0xba}; - const uint8_t kEncapSharedSecret[MLKEM512_SHARED_SECRET_LEN] = { + static const uint8_t kEncapSharedSecret[MLKEM512_SHARED_SECRET_LEN] = { 0xa7, 0x72, 0xdf, 0x2d, 0xe2, 0x50, 0xac, 0x7d, 0x89, 0x6b, 0xbb, 0x82, 0x0b, 0x57, 0xf2, 0xae, 0x05, 0xf9, 0xa4, 0x12, 0xab, 0x55, 0xba, 0xa4, 0x21, 0xd4, 0xaf, 0x6d, 0xac, 0x62, 0x66, 0x2a}; @@ -1173,13 +1192,13 @@ static int boringssl_self_test_ml_kem(void) { if (ml_kem_512_encapsulate_deterministic_no_self_test( ciphertext, shared_secret, kEncapEK, kEncapM) || !check_test(kEncapCiphertext, ciphertext, sizeof(kEncapCiphertext), - "ML-KEM encapsulate ciphertext") || + "ML-KEM-encapsulate-ciphertext") || !check_test(kEncapSharedSecret, shared_secret, sizeof(kEncapSharedSecret), - "ML-KEM encapsulate shared secret")) { + "ML-KEM-encapsulate-shared-secret")) { goto err; } - const uint8_t kDecapDK[MLKEM512_SECRET_KEY_BYTES] = { + static const uint8_t kDecapDK[MLKEM512_SECRET_KEY_BYTES] = { 0x73, 0x9b, 0x8b, 0x1f, 0x6a, 0x57, 0x66, 0x31, 0x0b, 0x06, 0x19, 0x04, 0x02, 0x14, 0x38, 0xbb, 0xd6, 0x1a, 0x14, 0xf0, 0x85, 0xfd, 0xe0, 0x29, 0xb5, 0x33, 0x86, 0xec, 0x37, 0x61, 0xaa, 0xe7, 0x78, 0x28, 0xfb, 0x19, @@ -1316,7 +1335,7 @@ static int boringssl_self_test_ml_kem(void) { 0x6e, 0x66, 0x72, 0x63, 0xb5, 0x0d, 0x48, 0xc4, 0x85, 0x5a, 0xe2, 0x49, 0xab, 0x4c, 0x80, 0xc9, 0xb4, 0x93, 0xd2, 0x2b, 0xf9, 0x59, 0xcd, 0x6e, 0x85, 0xfd, 0x28, 0xc0, 0xcd, 0x9f, 0xae, 0xce, 0xd7, 0x0f, 0xa7, 0x90}; - const uint8_t kDecapCiphertext[MLKEM512_CIPHERTEXT_BYTES] = { + static const uint8_t kDecapCiphertext[MLKEM512_CIPHERTEXT_BYTES] = { 0xaf, 0x4a, 0x00, 0x68, 0xc3, 0x73, 0x44, 0xd7, 0xe1, 0x06, 0xa9, 0xcd, 0x39, 0x77, 0x9c, 0xf8, 0xc7, 0x67, 0xd5, 0xb8, 0x1c, 0xb3, 0x44, 0x34, 0x40, 0xda, 0xde, 0x14, 0xc2, 0xc4, 0x83, 0x27, 0xba, 0x34, 0x28, 0x45, @@ -1381,11 +1400,11 @@ static int boringssl_self_test_ml_kem(void) { 0x5c, 0x61, 0x38, 0x04, 0xaf, 0x15, 0xac, 0x2c, 0x65, 0x55, 0x3b, 0x69, 0xd5, 0xd0, 0x12, 0xcd, 0x90, 0xe5, 0x0a, 0x40, 0xfd, 0xdb, 0x8e, 0xda, 0xa8, 0x33, 0x13, 0xb0, 0x08, 0x9b, 0x5d, 0x69, 0x97, 0x19, 0x3f, 0x21}; - const uint8_t kDecapSharedSecret[MLKEM512_SHARED_SECRET_LEN] = { + static const uint8_t kDecapSharedSecret[MLKEM512_SHARED_SECRET_LEN] = { 0xbe, 0x41, 0xc0, 0x7a, 0xd0, 0x59, 0x67, 0xab, 0xf7, 0x00, 0xb8, 0xb2, 0xe6, 0x97, 0x5e, 0x3c, 0x1e, 0x87, 0x50, 0x3c, 0xa0, 0xb5, 0x83, 0xe1, 0xd7, 0x30, 0x46, 0x23, 0x0e, 0x26, 0x5e, 0x5a}; - const uint8_t kDecapCiphertextRejection[MLKEM512_CIPHERTEXT_BYTES] = { + static const uint8_t kDecapCiphertextRejection[MLKEM512_CIPHERTEXT_BYTES] = { 0x18, 0x1a, 0xf9, 0xb9, 0xf1, 0x63, 0xa3, 0x04, 0x9d, 0x97, 0xd8, 0x19, 0x4b, 0x5c, 0x26, 0x35, 0x5f, 0xc9, 0xf9, 0xdc, 0xbf, 0x12, 0x05, 0x76, 0xab, 0xe4, 0x4d, 0x71, 0xa0, 0xd9, 0x91, 0x06, 0xd5, 0x57, 0x5d, 0xb4, @@ -1450,7 +1469,7 @@ static int boringssl_self_test_ml_kem(void) { 0xab, 0xe3, 0x2e, 0x84, 0x49, 0x99, 0xb4, 0x47, 0x7c, 0x99, 0x8a, 0x9f, 0xb3, 0xc9, 0xba, 0xbb, 0xe8, 0x3c, 0x6e, 0xc6, 0x13, 0x74, 0x0c, 0x2b, 0x04, 0x75, 0xec, 0xb7, 0x32, 0xde, 0x51, 0x64, 0x38, 0x68, 0xeb, 0xb7}; - const uint8_t kDecapSharedSecretRejection[MLKEM512_SHARED_SECRET_LEN] = { + static const uint8_t kDecapSharedSecretRejection[MLKEM512_SHARED_SECRET_LEN] = { 0x98, 0xed, 0x60, 0x0f, 0xfd, 0x9e, 0x01, 0x9f, 0x35, 0x0e, 0x0a, 0x15, 0xd4, 0x69, 0x5b, 0xa0, 0x96, 0xce, 0x2b, 0x32, 0xc3, 0x75, 0x24, 0x4f, 0x79, 0xa5, 0x74, 0xda, 0x06, 0xb4, 0xb1, 0xbd}; @@ -2071,33 +2090,15 @@ static int boringssl_self_test_ml_dsa(void) { static int boringssl_self_test_eddsa(void) { int ret = 0; - const uint8_t kEd25519PrivateKey[ED25519_PRIVATE_KEY_SEED_LEN] = { + static const uint8_t kEd25519PrivateKey[ED25519_PRIVATE_KEY_SEED_LEN] = { 0xb3, 0x99, 0x05, 0xbf, 0x43, 0x0b, 0x2a, 0xd2, 0x1d, 0xb6, 0x5d, 0x49, 0xa6, 0xab, 0x03, 0xc1, 0x7d, 0xdb, 0x72, 0xe7, 0xa9, 0x8e, 0xb9, 0x8f, 0xae, 0x59, 0x91, 0x7a, 0xe2, 0x5f, 0x92, 0x14}; - const uint8_t kEd25519PublicKey[ED25519_PUBLIC_KEY_LEN] = { + static const uint8_t kEd25519PublicKey[ED25519_PUBLIC_KEY_LEN] = { 0xe7, 0x75, 0xcf, 0x0e, 0x33, 0x48, 0x52, 0xa7, 0xe6, 0x99, 0xbe, 0xba, 0x13, 0xbc, 0x24, 0xf8, 0x32, 0xf3, 0xc2, 0xa3, 0xa0, 0x3d, 0xc9, 0x3c, 0x42, 0xb5, 0x92, 0x76, 0x15, 0xa5, 0x46, 0xba}; - const uint8_t kEd25519Signature[ED25519_SIGNATURE_LEN] = { - 0x30, 0x1a, 0x4c, 0x56, 0xe0, 0x37, 0x0b, 0x57, 0x2f, 0x7d, 0x8c, - 0x75, 0x1b, 0x5c, 0xfa, 0xb6, 0xc3, 0x98, 0x7c, 0x6f, 0x5d, 0xe8, - 0x7c, 0xac, 0x4d, 0x71, 0x16, 0x73, 0xda, 0x8c, 0xb2, 0x19, 0x86, - 0x03, 0xcd, 0x91, 0x82, 0x73, 0xa5, 0x34, 0x24, 0x93, 0xf1, 0xc1, - 0xad, 0x0e, 0x8a, 0x78, 0x45, 0x15, 0xa7, 0xfe, 0xc8, 0xc9, 0xbe, - 0xa2, 0xa3, 0xf1, 0xcf, 0x7b, 0x3a, 0x89, 0x10, 0x0f}; - const uint8_t kEd25519Message[128] = { - 0x13, 0x1d, 0x2a, 0xa9, 0x8f, 0x46, 0xfd, 0x5a, 0xca, 0xef, 0x8e, 0x92, - 0xfa, 0x8c, 0x50, 0xd4, 0x8b, 0xda, 0xdf, 0xfe, 0x13, 0xd7, 0x9c, 0xc7, - 0x1b, 0x95, 0x85, 0x5f, 0xaf, 0xa4, 0x84, 0x66, 0x50, 0x2a, 0x1c, 0x61, - 0x4d, 0xb7, 0x85, 0xfc, 0xc9, 0x4c, 0x50, 0x61, 0x65, 0x23, 0x93, 0x42, - 0xcb, 0x9b, 0x3e, 0xe6, 0x3b, 0x35, 0xdc, 0x2f, 0x7e, 0x78, 0x61, 0x15, - 0x42, 0xc7, 0xa6, 0x1b, 0x50, 0xf3, 0xb6, 0x8e, 0xcf, 0x1b, 0x70, 0xca, - 0xc0, 0x1b, 0x34, 0xef, 0x06, 0x1b, 0x3f, 0x7c, 0xaa, 0xc8, 0x26, 0x56, - 0xbf, 0xd5, 0x5a, 0x06, 0xb8, 0xeb, 0x7d, 0xbe, 0x82, 0x45, 0x17, 0xfe, - 0x3c, 0x56, 0x7d, 0xa5, 0xa0, 0x3e, 0x0b, 0xf2, 0xf1, 0xfe, 0xbb, 0x96, - 0x3c, 0x94, 0x1a, 0xfc, 0x36, 0xe4, 0x5a, 0x5a, 0xc5, 0xe2, 0x71, 0xcd, - 0x99, 0x56, 0xcc, 0xda, 0x0d, 0x62, 0xc8, 0x7c}; + uint8_t ed25519_private_key[ED25519_PRIVATE_KEY_LEN] = {0}; OPENSSL_memcpy(ed25519_private_key, kEd25519PrivateKey, ED25519_PRIVATE_KEY_SEED_LEN); @@ -2105,17 +2106,42 @@ static int boringssl_self_test_eddsa(void) { kEd25519PublicKey, ED25519_PUBLIC_KEY_LEN); uint8_t ed25519_out_sig[ED25519_SIGNATURE_LEN] = {0}; - if (!ED25519_sign_no_self_test(&ed25519_out_sig[0], &kEd25519Message[0], - sizeof(kEd25519Message), + + static const uint8_t kEd25519SignMessage[32] = { + 0x19, 0x61, 0xd1, 0xd5, 0x2d, 0x8c, 0x04, 0x5f, 0xdf, 0xc1, 0xc6, 0x82, + 0xb3, 0x5f, 0x07, 0xaa, 0xe1, 0xd3, 0xb6, 0xe5, 0x48, 0x63, 0x98, 0x30, + 0xee, 0xd9, 0x29, 0xbc, 0x12, 0x2d, 0x79, 0x9f}; + static const uint8_t kEd25519SignSignature[ED25519_SIGNATURE_LEN] = { + 0xa8, 0x81, 0xe8, 0xd9, 0x5d, 0xdb, 0xd5, 0xd1, 0x47, 0x60, 0xaf, 0x4e, + 0xcf, 0xce, 0x45, 0x96, 0xf7, 0x2e, 0x04, 0xd7, 0xee, 0xcc, 0xb9, 0xc6, + 0xa1, 0x93, 0xe2, 0x4d, 0xd7, 0x35, 0xb1, 0x3c, 0x18, 0xa5, 0x34, 0xc7, + 0x79, 0x31, 0x45, 0x46, 0x9d, 0xd1, 0x6f, 0x0c, 0x5e, 0x03, 0x71, 0xa3, + 0xfb, 0x85, 0x06, 0x35, 0x97, 0xc0, 0x92, 0x45, 0x97, 0xcb, 0x42, 0x75, + 0x60, 0xdb, 0x2a, 0x0b}; + + if (!ED25519_sign_no_self_test(ed25519_out_sig, kEd25519SignMessage, + sizeof(kEd25519SignMessage), ed25519_private_key) || - !check_test(&kEd25519Signature[0], &ed25519_out_sig[0], + !check_test(kEd25519SignSignature, ed25519_out_sig, ED25519_SIGNATURE_LEN, "ED25519 sign")) { - fprintf(stderr, "ED25519 sign failed.\n"); + fprintf(stderr, "ED25519-sign failed.\n"); goto err; } - if (!ED25519_verify_no_self_test(&kEd25519Message[0], sizeof(kEd25519Message), - ed25519_out_sig, kEd25519PublicKey)) { - fprintf(stderr, "ED25519 verify failed.\n"); + + static const uint8_t kEd25519VerifyMessage[32] = { + 0x71, 0x3a, 0x7a, 0xde, 0x3d, 0x9e, 0x10, 0x9f, 0x9f, 0xc1, 0x9b, 0xc3, + 0x24, 0xe0, 0x41, 0x72, 0xee, 0x7e, 0x4d, 0x4a, 0xc6, 0x36, 0x69, 0xb7, + 0xbc, 0xdb, 0xd6, 0xd2, 0xde, 0x87, 0xdf, 0x0e}; + static const uint8_t kEd25519VerifySignature[ED25519_SIGNATURE_LEN] = { + 0x44, 0xf2, 0x38, 0xf7, 0xea, 0x71, 0x54, 0xce, 0xdd, 0x95, 0x63, 0x11, + 0x44, 0x07, 0x8f, 0xfe, 0xc6, 0x55, 0x93, 0x8f, 0x73, 0xe2, 0x96, 0x76, + 0x72, 0x8b, 0x40, 0x0f, 0x8f, 0x46, 0xc8, 0x04, 0x8d, 0x5b, 0xf3, 0xab, + 0x12, 0x43, 0x42, 0xeb, 0xae, 0x54, 0xb6, 0xe0, 0x4f, 0x3f, 0x16, 0x7b, + 0x5e, 0xe8, 0xbd, 0xcf, 0xec, 0x9b, 0xe6, 0xff, 0x65, 0xbc, 0xc6, 0x9a, + 0x78, 0x89, 0x67, 0x0a}; + if (!ED25519_verify_no_self_test(kEd25519VerifyMessage, sizeof(kEd25519VerifyMessage), + kEd25519VerifySignature, kEd25519PublicKey)) { + fprintf(stderr, "ED25519-verify failed.\n"); goto err; } @@ -2127,57 +2153,36 @@ static int boringssl_self_test_eddsa(void) { static int boringssl_self_test_hasheddsa(void) { int ret = 0; - const uint8_t kEd25519PrivateKey[ED25519_PRIVATE_KEY_SEED_LEN] = { + static const uint8_t kEd25519PrivateKey[ED25519_PRIVATE_KEY_SEED_LEN] = { 0xc3, 0x53, 0x7a, 0x4f, 0x31, 0x5e, 0xc5, 0x8f, 0x5d, 0xe4, 0xc2, 0x8d, 0xc5, 0x32, 0x7c, 0x79, 0xfb, 0x40, 0x7c, 0xb6, 0x70, 0xbe, 0x05, 0xf1, 0x1b, 0x0f, 0x70, 0x06, 0x40, 0x70, 0x21, 0x27 }; - const uint8_t kEd25519PublicKey[ED25519_PUBLIC_KEY_LEN] = { + static const uint8_t kEd25519PublicKey[ED25519_PUBLIC_KEY_LEN] = { 0x63, 0x36, 0xa6, 0x15, 0xdf, 0x2d, 0xe9, 0x3b, 0x8d, 0xab, 0x78, 0xe9, 0x7b, 0x82, 0x7b, 0x2d, 0x5c, 0xeb, 0xeb, 0xd7, 0xfa, 0xa7, 0x7e, 0x3d, 0x97, 0xea, 0xf3, 0x6b, 0x12, 0xf7, 0x22, 0xe3 }; - const uint8_t kEd25519Signature[ED25519_SIGNATURE_LEN] = { - 0x58, 0xe6, 0xd7, 0x14, 0x6d, 0x6a, 0x0b, 0x45, 0x74, 0x40, 0x81, - 0xdd, 0x25, 0x8d, 0xcf, 0xa0, 0x6d, 0x64, 0x83, 0xdc, 0x94, 0xdd, - 0xeb, 0xa2, 0x48, 0x02, 0x48, 0x0f, 0x83, 0x55, 0x57, 0xbb, 0xe0, - 0x66, 0x4b, 0x43, 0xbc, 0xef, 0x16, 0x9f, 0x37, 0xa8, 0xbe, 0xb4, - 0xaf, 0x5a, 0x8e, 0xc0, 0xdf, 0x41, 0x33, 0xad, 0xe2, 0x89, 0x6d, - 0x32, 0xae, 0x54, 0x84, 0x14, 0xcd, 0xca, 0x68, 0x09 - }; - const uint8_t kEd25519Message[128] = { - 0x8f, 0x19, 0x9e, 0xaf, 0x21, 0x04, 0xa0, 0xfa, 0x04, 0x87, 0x0c, 0x01, - 0x1d, 0xec, 0x2f, 0xc7, 0xf1, 0x1a, 0x02, 0x6f, 0xb4, 0x87, 0xd9, 0xef, - 0x8e, 0x14, 0x2c, 0x93, 0x9f, 0x94, 0x71, 0x88, 0x91, 0x93, 0xcf, 0x63, - 0xd5, 0x2c, 0x04, 0xb7, 0x3b, 0xe8, 0xdf, 0x58, 0x5f, 0x19, 0x2c, 0x39, - 0x29, 0xb9, 0xb4, 0xb9, 0xd0, 0xb2, 0xbc, 0x5f, 0x7c, 0x73, 0xdc, 0x25, - 0xbb, 0xdb, 0xe2, 0xe3, 0xdf, 0x6b, 0x1b, 0x49, 0x26, 0x59, 0x81, 0xa6, - 0xd4, 0xd2, 0x22, 0x70, 0xe6, 0x56, 0x63, 0x6a, 0x3a, 0xe8, 0x6e, 0x82, - 0x78, 0x50, 0xf3, 0xac, 0xdd, 0xf5, 0xbd, 0x56, 0xd3, 0xd8, 0x89, 0x5d, - 0x59, 0xc5, 0xae, 0xc2, 0x83, 0x66, 0x21, 0x98, 0x3c, 0x2d, 0x0a, 0xc4, - 0x5f, 0x99, 0x54, 0x39, 0xca, 0xaf, 0xfd, 0x45, 0x39, 0x3c, 0xa9, 0x8d, - 0x2e, 0x9f, 0xaf, 0x47, 0xf2, 0xbd, 0xd3, 0xde - }; - const uint8_t kEd25519Context[205] = { - 0xcb, 0x83, 0x11, 0x77, 0x1d, 0xe5, 0x02, 0xec, 0x83, 0x79, 0x1b, 0x3d, - 0x2b, 0x6e, 0x63, 0x2b, 0x44, 0xc6, 0x17, 0x1e, 0x35, 0x84, 0x90, 0xa9, - 0x0c, 0x76, 0x36, 0x74, 0x4f, 0xd0, 0xe4, 0xcf, 0x89, 0xbf, 0xd6, 0x12, - 0xe6, 0x89, 0x29, 0xb2, 0x9e, 0xa4, 0x0a, 0xe4, 0x7e, 0x46, 0x9a, 0x50, - 0x35, 0x6a, 0x1e, 0x88, 0x77, 0xec, 0x70, 0xa2, 0x96, 0xf8, 0x01, 0x47, - 0x97, 0xa1, 0x91, 0x8e, 0x5e, 0x9a, 0x84, 0xc6, 0xbf, 0x98, 0x95, 0x62, - 0x4e, 0x8f, 0x0a, 0xa5, 0x26, 0x27, 0xa2, 0x0d, 0xbd, 0xcd, 0x16, 0xe1, - 0x5f, 0x42, 0x69, 0x0d, 0x85, 0x96, 0xab, 0x7c, 0xec, 0x77, 0x41, 0xa9, - 0x4a, 0x31, 0x0b, 0x20, 0x54, 0x58, 0x1e, 0x4b, 0x4b, 0x7d, 0xca, 0xe1, - 0xf9, 0xf5, 0x38, 0x42, 0x74, 0xed, 0xbe, 0xd9, 0x4a, 0xdb, 0xbf, 0x69, - 0xbb, 0xd8, 0x1e, 0xde, 0xe4, 0xe1, 0xdf, 0x18, 0x70, 0x03, 0x9a, 0x5f, - 0x69, 0x16, 0xfb, 0x7c, 0xa7, 0x60, 0xbd, 0x1e, 0xac, 0x24, 0xe5, 0xa3, - 0x74, 0x8f, 0x5d, 0xcc, 0x90, 0xb2, 0xac, 0xe5, 0x91, 0x74, 0x37, 0x4f, - 0xd4, 0xc6, 0xac, 0x08, 0x9c, 0x76, 0x05, 0xdf, 0x99, 0xad, 0xd1, 0xd2, - 0xb9, 0x4f, 0x8c, 0xf7, 0xc0, 0x50, 0xde, 0xf3, 0x27, 0xf3, 0xa5, 0x90, - 0xea, 0x7c, 0x8f, 0x76, 0xe3, 0x33, 0x0d, 0x3a, 0xe9, 0xb5, 0xcb, 0x33, - 0x58, 0x7e, 0x6f, 0x8a, 0x17, 0x0d, 0x96, 0x1a, 0x20, 0x48, 0x48, 0x20, - 0x28 + static const uint8_t kEd25519Context[32] = { + 0x76, 0x34, 0x2c, 0x15, 0xb7, 0x11, 0x97, 0x5d, 0x86, 0xd0, 0x11, 0xdd, + 0x28, 0xec, 0x76, 0xf9, 0xb9, 0xe7, 0x2a, 0xb1, 0x5a, 0x50, 0x15, 0xb0, + 0xdd, 0xca, 0xfa, 0x8f, 0xed, 0x54, 0x80, 0x66 }; + + static const uint8_t kEd25519SignMessage[32] = { + 0xf9, 0xbf, 0xec, 0x63, 0xc4, 0xe0, 0x73, 0xfa, 0x97, 0x1a, 0x80, 0x49, + 0x91, 0x47, 0xd0, 0x0a, 0xcd, 0x26, 0xaa, 0xe1, 0xff, 0x03, 0x64, 0xdb, + 0x20, 0xf8, 0xa7, 0xa4, 0x95, 0x4d, 0xb3, 0x87 + }; + static const uint8_t kEd25519SignSignature[ED25519_SIGNATURE_LEN] = { + 0x0b, 0x93, 0x3d, 0x3f, 0x59, 0x00, 0xe3, 0xa1, 0xe5, 0x39, 0x47, 0xce, + 0x97, 0x32, 0xc7, 0x01, 0x40, 0x37, 0xe9, 0xc9, 0x4b, 0x71, 0xcd, 0x3a, + 0xfb, 0x60, 0x46, 0xaa, 0x29, 0xfe, 0xa9, 0xbb, 0xd8, 0x1c, 0x50, 0x54, + 0x10, 0x64, 0xc6, 0x59, 0xd0, 0x07, 0x5f, 0xb3, 0x8c, 0x8b, 0x42, 0x0f, + 0x81, 0x48, 0x68, 0x2d, 0xc9, 0xf8, 0x38, 0x43, 0x55, 0x10, 0x5c, 0x39, + 0x70, 0xd2, 0x06, 0x09 +}; + uint8_t ed25519_private_key[ED25519_PRIVATE_KEY_LEN] = {0}; OPENSSL_memcpy(ed25519_private_key, kEd25519PrivateKey, ED25519_PRIVATE_KEY_SEED_LEN); @@ -2186,16 +2191,30 @@ static int boringssl_self_test_hasheddsa(void) { uint8_t ed25519_out_sig[ED25519_SIGNATURE_LEN] = {0}; if (!ED25519ph_sign_no_self_test( - &ed25519_out_sig[0], &kEd25519Message[0], sizeof(kEd25519Message), - ed25519_private_key, &kEd25519Context[0], sizeof(kEd25519Context)) || - !check_test(&kEd25519Signature[0], &ed25519_out_sig[0], + &ed25519_out_sig[0], kEd25519SignMessage, sizeof(kEd25519SignMessage), + ed25519_private_key, kEd25519Context, sizeof(kEd25519Context)) || + !check_test(kEd25519SignSignature, ed25519_out_sig, ED25519_SIGNATURE_LEN, "ED25519 sign")) { - fprintf(stderr, "ED25519ph sign failed.\n"); + fprintf(stderr, "ED25519ph-sign failed.\n"); goto err; } - if (!ED25519ph_verify_no_self_test(&kEd25519Message[0], sizeof(kEd25519Message), - ed25519_out_sig, kEd25519PublicKey, &kEd25519Context[0], sizeof(kEd25519Context))) { - fprintf(stderr, "ED25519ph verify failed.\n"); + + static const uint8_t kEd25519VerifyMessage[32] = { + 0x36, 0xc7, 0xf4, 0x5a, 0x29, 0xa6, 0x84, 0xa8, 0x01, 0x37, 0x53, 0xb1, + 0xc6, 0x10, 0x09, 0x79, 0x1f, 0xbc, 0x6e, 0xd4, 0xaf, 0x81, 0x31, 0xaa, + 0x4b, 0xc2, 0x76, 0x3d, 0x7f, 0xd5, 0xf7, 0x50 + }; + static const uint8_t kEd25519VerifySignature[ED25519_SIGNATURE_LEN] = { + 0x10, 0x1b, 0xcc, 0xa2, 0x56, 0xef, 0x62, 0x0b, 0xb0, 0x87, 0x59, 0x2e, + 0x91, 0x73, 0x36, 0xd8, 0x54, 0x2b, 0x71, 0x72, 0x8e, 0x2a, 0x27, 0x48, + 0xc5, 0x5c, 0x71, 0x9b, 0x82, 0x5d, 0xad, 0x45, 0x21, 0xbf, 0xb3, 0x75, + 0x62, 0x4b, 0x27, 0xff, 0xf8, 0x1c, 0xbf, 0x71, 0x65, 0xe5, 0xba, 0x4a, + 0x98, 0xe8, 0xc4, 0x51, 0xb3, 0xc3, 0xc2, 0xfa, 0x23, 0x27, 0x8f, 0x2b, + 0xb7, 0x45, 0x81, 0x07 +}; + if (!ED25519ph_verify_no_self_test(kEd25519VerifyMessage, sizeof(kEd25519VerifyMessage), + kEd25519VerifySignature, kEd25519PublicKey, kEd25519Context, sizeof(kEd25519Context))) { + fprintf(stderr, "ED25519ph-verify failed.\n"); goto err; } @@ -2358,18 +2377,18 @@ int boringssl_self_test_hmac_sha256(void) { } static int boringssl_self_test_hkdf_sha256(void) { - const uint8_t kHKDF_ikm_tc1[] = { // RFC 5869 Test Case 1 + static const uint8_t kHKDF_ikm_tc1[] = { // RFC 5869 Test Case 1 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; - const uint8_t kHKDF_salt_tc1[] = { + static const uint8_t kHKDF_salt_tc1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; - const uint8_t kHKDF_info_tc1[] = { + static const uint8_t kHKDF_info_tc1[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; - const uint8_t kHKDF_okm_tc1_sha256[] = { + static const uint8_t kHKDF_okm_tc1_sha256[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, @@ -2712,19 +2731,19 @@ static int boringssl_self_test_fast(void) { } // KBKDF counter HMAC-SHA-256 - const uint8_t kKBKDF_ctr_hmac_secret[] = { + static const uint8_t kKBKDF_ctr_hmac_secret[] = { 0xdd, 0x1d, 0x91, 0xb7, 0xd9, 0x0b, 0x2b, 0xd3, 0x13, 0x85, 0x33, 0xce, 0x92, 0xb2, 0x72, 0xfb, 0xf8, 0xa3, 0x69, 0x31, 0x6a, 0xef, 0xe2, 0x42, 0xe6, 0x59, 0xcc, 0x0a, 0xe2, 0x38, 0xaf, 0xe0 }; - const uint8_t kKBKDF_ctr_hmac_info[] = { + static const uint8_t kKBKDF_ctr_hmac_info[] = { 0x01, 0x32, 0x2b, 0x96, 0xb3, 0x0a, 0xcd, 0x19, 0x79, 0x79, 0x44, 0x4e, 0x46, 0x8e, 0x1c, 0x5c, 0x68, 0x59, 0xbf, 0x1b, 0x1c, 0xf9, 0x51, 0xb7, 0xe7, 0x25, 0x30, 0x3e, 0x23, 0x7e, 0x46, 0xb8, 0x64, 0xa1, 0x45, 0xfa, 0xb2, 0x5e, 0x51, 0x7b, 0x08, 0xf8, 0x68, 0x3d, 0x03, 0x15, 0xbb, 0x29, 0x11, 0xd8, 0x0a, 0x0e, 0x8a, 0xba, 0x17, 0xf3, 0xb4, 0x13, 0xfa, 0xac }; - const uint8_t kKBKDF_ctr_hmac_output[] = { + static const uint8_t kKBKDF_ctr_hmac_output[] = { 0x10, 0x62, 0x13, 0x42, 0xbf, 0xb0, 0xfd, 0x40, 0x04, 0x6c, 0x0e, 0x29, 0xf2, 0xcf, 0xdb, 0xf0 }; diff --git a/crypto/obj/obj_dat.h b/crypto/obj/obj_dat.h index eb284bb0d0..1f0120f9ca 100644 --- a/crypto/obj/obj_dat.h +++ b/crypto/obj/obj_dat.h @@ -56,7 +56,7 @@ /* This file is generated by crypto/obj/objects.go. */ -#define NUM_NID 997 +#define NUM_NID 998 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -9004,6 +9004,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { {"MLDSA44", "MLDSA44", NID_MLDSA44, 9, &kObjectData[6333], 0}, {"MLDSA65", "MLDSA65", NID_MLDSA65, 9, &kObjectData[6342], 0}, {"MLDSA87", "MLDSA87", NID_MLDSA87, 9, &kObjectData[6351], 0}, + {"ED25519ph", "ED25519ph", NID_ED25519ph, 0, NULL, 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -9101,6 +9102,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 67 /* DSA-old */, 297 /* DVCS */, 949 /* ED25519 */, + 997 /* ED25519ph */, 960 /* ED448 */, 99 /* GN */, 969 /* HKDF */, @@ -10012,6 +10014,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 392 /* Domain */, 132 /* E-mail Protection */, 949 /* ED25519 */, + 997 /* ED25519ph */, 960 /* ED448 */, 389 /* Enterprises */, 384 /* Experimental */, diff --git a/crypto/obj/obj_mac.num b/crypto/obj/obj_mac.num index 72782a89e7..b25bf8cb6d 100644 --- a/crypto/obj/obj_mac.num +++ b/crypto/obj/obj_mac.num @@ -984,3 +984,4 @@ PQDSA 993 MLDSA44 994 MLDSA65 995 MLDSA87 996 +ED25519ph 997 diff --git a/crypto/obj/objects.txt b/crypto/obj/objects.txt index 791704d5a3..c5d4c4e926 100644 --- a/crypto/obj/objects.txt +++ b/crypto/obj/objects.txt @@ -1353,6 +1353,7 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme 1 3 101 111 : X448 1 3 101 112 : ED25519 1 3 101 113 : ED448 + : ED25519ph : ChaCha20-Poly1305 : chacha20-poly1305 diff --git a/include/openssl/base.h b/include/openssl/base.h index 1c9f8898ad..b2ed56d1b2 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -352,6 +352,7 @@ typedef struct kem_key_st KEM_KEY; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; typedef struct evp_pkey_st EVP_PKEY; +typedef struct evp_pkey_ctx_signature_context_params_st EVP_PKEY_CTX_SIGNATURE_CONTEXT_PARAMS; typedef struct hmac_ctx_st HMAC_CTX; typedef struct md4_state_st MD4_CTX; typedef struct md5_state_st MD5_CTX; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 306dcd7096..78cac8fb01 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -194,6 +194,7 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int #define EVP_PKEY_RSA_PSS NID_rsassaPss #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey #define EVP_PKEY_ED25519 NID_ED25519 +#define EVP_PKEY_ED25519PH NID_ED25519ph #define EVP_PKEY_X25519 NID_X25519 #define EVP_PKEY_HKDF NID_hkdf #define EVP_PKEY_HMAC NID_hmac @@ -815,6 +816,36 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md); +// EVP_PKEY_CTX_set_signature_context sets |context| of length |context_len| to +// be used as the context octet string for the signing operation. |context| will +// be copied to an internal buffer allowing for the caller to free it +// afterwards. +// +// EVP_PKEY_ED25519PH is the only key type that currently supports setting a +// a signature context that is used in computing the HashEdDSA signature. +// +// Callers must use the |EVP_DigestSignInit| -> |EVP_DigestSignUpdate| -> +// |EVP_DigestSignFinal| or |EVP_DigestVerifyInit| -> |EVP_DigestVerifyUpdate| +// -> |EVP_DigestVerifyFinal| call pattern to allow configuration of the +// signature context on the |EVP_PKEY_CTX|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_signature_context(EVP_PKEY_CTX *ctx, + const uint8_t *context, + size_t context_len); + +// EVP_PKEY_CTX_get0_signature_context sets |*context| to point to the internal +// buffer containing the signing context octet string (which may be NULL) and +// writes the length to |*context_len|. +// +// EVP_PKEY_ED25519PH is the only key type that currently supports retrieving a +// a signature context that is used in computing the HashEdDSA signature. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get0_signature_context(EVP_PKEY_CTX *ctx, + const uint8_t **context, + size_t *context_len); + // RSA specific control functions. // EVP_PKEY_CTX_set_rsa_padding sets the padding type to use. It should be one diff --git a/include/openssl/nid.h b/include/openssl/nid.h index 2ec2a9105b..cefc0f6b95 100644 --- a/include/openssl/nid.h +++ b/include/openssl/nid.h @@ -4379,6 +4379,9 @@ extern "C" { #define NID_MLDSA87 996 #define OBJ_MLDSA87 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 19L +#define SN_ED25519ph "ED25519ph" +#define NID_ED25519ph 997 + #if defined(__cplusplus) } /* extern C */ #endif diff --git a/tests/ci/run_benchmark_build_tests.sh b/tests/ci/run_benchmark_build_tests.sh index 7af958914f..3ad3e5f4fe 100755 --- a/tests/ci/run_benchmark_build_tests.sh +++ b/tests/ci/run_benchmark_build_tests.sh @@ -71,7 +71,7 @@ function build_boringssl { # has changes in speed.cc that could affect the comparison of the FIPS to non-FIPS, or if new # algorithms have been added to speed.cc build_aws_lc_fips -"${BUILD_ROOT}/tool/bssl" speed -timeout_ms 10 +"${BUILD_ROOT}/tool/bssl" speed -timeout_ms 10 -chunks 1,2,16,256,20000 build_aws_lc_branch fips-2021-10-20 build_aws_lc_branch fips-2022-11-02 @@ -94,15 +94,15 @@ open32:${install_dir}/openssl-${openssl_3_2_branch};\ openmaster:${install_dir}/openssl-${openssl_master_branch};\ boringssl:${install_dir}/boringssl;" -LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2021-10-20/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2021" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2022-11-02/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2022" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2024-09-27/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2022" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_1_0_2_branch}/lib" "${BUILD_ROOT}/tool/open102" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_1_1_1_branch}/lib" "${BUILD_ROOT}/tool/open111" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_3_1_branch}/lib64" "${BUILD_ROOT}/tool/open31" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_3_2_branch}/lib64" "${BUILD_ROOT}/tool/open32" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_master_branch}/lib64" "${BUILD_ROOT}/tool/openmaster" -timeout_ms 10 -LD_LIBRARY_PATH="${install_dir}/boringssl" "${BUILD_ROOT}/tool/boringssl" -timeout_ms 10 +LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2021-10-20/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2021" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2022-11-02/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2022" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/aws-lc-fips-2024-09-27/lib" "${BUILD_ROOT}/tool/aws-lc-fips-2022" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_1_0_2_branch}/lib" "${BUILD_ROOT}/tool/open102" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_1_1_1_branch}/lib" "${BUILD_ROOT}/tool/open111" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_3_1_branch}/lib64" "${BUILD_ROOT}/tool/open31" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_3_2_branch}/lib64" "${BUILD_ROOT}/tool/open32" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/openssl-${openssl_master_branch}/lib64" "${BUILD_ROOT}/tool/openmaster" -timeout_ms 10 -chunks 1,2,16,256,20000 +LD_LIBRARY_PATH="${install_dir}/boringssl" "${BUILD_ROOT}/tool/boringssl" -timeout_ms 10 -chunks 1,2,16,256,20000 echo "Testing ossl_bm with OpenSSL 1.0 with the legacy build option" run_build -DOPENSSL_1_0_INSTALL_DIR="${install_dir}/openssl-${openssl_1_0_2_branch}" -DASAN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo diff --git a/tool/speed.cc b/tool/speed.cc index 0b0176b8bd..051b11b3e6 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -1048,6 +1048,10 @@ static bool SpeedAES256XTS(const std::string &name, //const size_t in_len, // Benchmark initialisation and encryption for (size_t in_len : g_chunk_lengths) { + if (in_len < AES_BLOCK_SIZE) { + // AES-XTS requires encrypting at least the block size + continue; + } in.resize(in_len); out.resize(in_len); std::fill(in.begin(), in.end(), 0x5a); @@ -1080,6 +1084,10 @@ static bool SpeedAES256XTS(const std::string &name, //const size_t in_len, results.Print(name + " decrypt init"); for (size_t in_len : g_chunk_lengths) { + if (in_len < AES_BLOCK_SIZE) { + // AES-XTS requires decrypting at least the block size + continue; + } in.resize(in_len); out.resize(in_len); std::fill(in.begin(), in.end(), 0x5a); @@ -1156,25 +1164,21 @@ static bool SpeedHmacChunk(const EVP_MD *md, std::string name, #else BM_NAMESPACE::UniquePtr ctx(HMAC_CTX_new()); #endif - uint8_t scratch[16384]; + std::unique_ptr input(new uint8_t[chunk_len]); const size_t key_len = EVP_MD_size(md); std::unique_ptr key(new uint8_t[key_len]); BM_memset(key.get(), 0, key_len); - if (chunk_len > sizeof(scratch)) { - return false; - } - if (!HMAC_Init_ex(ctx.get(), key.get(), key_len, md, NULL /* ENGINE */)) { fprintf(stderr, "Failed to create HMAC_CTX.\n"); } TimeResults results; - if (!TimeFunction(&results, [&ctx, chunk_len, &scratch]() -> bool { + if (!TimeFunction(&results, [&ctx, chunk_len, &input]() -> bool { uint8_t digest[EVP_MAX_MD_SIZE]; unsigned int md_len; return HMAC_Init_ex(ctx.get(), NULL, 0, NULL, NULL) && - HMAC_Update(ctx.get(), scratch, chunk_len) && + HMAC_Update(ctx.get(), input.get(), chunk_len) && HMAC_Final(ctx.get(), digest, &md_len); })) { fprintf(stderr, "HMAC_Final failed.\n"); @@ -1221,22 +1225,19 @@ static bool SpeedHmac(const EVP_MD *md, const std::string &name, static bool SpeedHmacChunkOneShot(const EVP_MD *md, std::string name, size_t chunk_len) { - uint8_t scratch[16384]; + std::unique_ptr input(new uint8_t[chunk_len]); const size_t key_len = EVP_MD_size(md); std::unique_ptr key(new uint8_t[key_len]); BM_memset(key.get(), 0, key_len); - if (chunk_len > sizeof(scratch)) { - return false; - } TimeResults results; - if (!TimeFunction(&results, [&key, key_len, md, chunk_len, &scratch]() -> bool { + if (!TimeFunction(&results, [&key, key_len, md, chunk_len, &input]() -> bool { uint8_t digest[EVP_MAX_MD_SIZE] = {0}; unsigned int md_len = EVP_MAX_MD_SIZE; - return HMAC(md, key.get(), key_len, scratch, chunk_len, digest, &md_len) != nullptr; + return HMAC(md, key.get(), key_len, input.get(), chunk_len, digest, &md_len) != nullptr; })) { fprintf(stderr, "HMAC_Final failed.\n"); ERR_print_errors_fp(stderr); @@ -1262,19 +1263,14 @@ static bool SpeedHmacOneShot(const EVP_MD *md, const std::string &name, return true; } -const size_t SCRATCH_SIZE = 16384; using RandomFunction = std::function; static bool SpeedRandomChunk(RandomFunction function, std::string name, size_t chunk_len) { - std::unique_ptr scratch(new uint8_t[SCRATCH_SIZE]); - - if (chunk_len > SCRATCH_SIZE) { - return false; - } + std::unique_ptr output(new uint8_t[chunk_len]); TimeResults results; - if (!TimeFunction(&results, [chunk_len, &scratch, &function]() -> bool { - function(scratch.get(), chunk_len); + if (!TimeFunction(&results, [chunk_len, &output, &function]() -> bool { + function(output.get(), chunk_len); return true; })) { return false; diff --git a/util/fipstools/break-kat.go b/util/fipstools/break-kat.go index 8eee35d5cf..793da5d4ea 100644 --- a/util/fipstools/break-kat.go +++ b/util/fipstools/break-kat.go @@ -14,23 +14,36 @@ import ( var ( kats = map[string]string{ - "HMAC-SHA-256": "dad91293dfcf2a7c8ecd13fe353fa75b", - "AES-CBC-encrypt": "078609a6c5ac2544699adf682fa377f9be8ab6aef563e8c56a36b84f557fadd3", - "AES-CBC-decrypt": "347aa5a024b28257b36510be583d4f47adb7bbeedc6005bbbd0d0a9f06bb7b10", - "AES-GCM-encrypt": "8fcc4099808e75caaff582898848a88d808b55ab4e9370797d940be8cc1d7884", - "AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c", - "DRBG": "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27", - "DRBG-reseed": "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe", - "SHA-1": "132fd9bad5c1826263bafbb699f707a5", - "SHA-256": "ff3b857da7236a2baa0f396b51522217", - "SHA-512": "212512f8d2ad8322781c6c4d69a9daa1", - "TLS-KDF": "abc3657b094c7628a0b282996fe75a75f4984fd94d4ecc2fcf53a2c469a3f731", - "RSA-sign": "d2b56e53306f720d7929d8708bf46f1c22300305582b115bedcac722d8aa5ab2", - "RSA-verify": "c5ef030d00a13e3a705b23e1e3de3f2c8e84b2e82d1bec14116f8245e5b6fa4b207f12afe72c8d36675acb7d670f6a5c590e44716c3df31104bea89f61becd6cc188814801d308ceec2a843ec7f25ebcdde588dd8980326928b10843c4b3190338b0a07c5a94a53f6d84de7947f3db3d9f730610bf463c291fd901ab8a54e47dbb196d8af53ef15fd06b7ad0ddb65c83c8fee8d0a708334733cbe7b03322695d9a406a687867b38294d8634805d4cb68737355d776484df3cd8b8feb51fd94608218d88eb2f2d04064312ad0412e7a96d49a9d71d76606ab7a5bd99bc31c37593c837f15ba8601926a1f6919d1110b55906e18e29e2a94045ae9218bc6c8da74", - "ECDSA-sign": "1e35930be860d0942ca7bbd6f6ded87f157e4de24f81ed4b875c0e018e89a81f", - "ECDSA-verify": "6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c3c77d1b6e09e747bc5ab5501d75e618d8e5b272e159ff3413cb71a81408d5605", - "Z-computation": "e7604491269afb5b102d6ea52cb59feb70aede6ce3bfb3e0105485abd861d77b", - "FFDH": "a14f8ad36be37b18b8f35864392f150ab7ee22c47e1870052a3f17918274af18aaeaf4cf6aacfde96c9d586eb7ebaff6b03fe3b79a8e2ff9dd6df34caaf2ac70fd3771d026b41a561ee90e4337d0575f8a0bd160c868e7e3cef88aa1d88448b1e4742ba11480a9f8a8b737347c408d74a7d57598c48875629df0c85327a124ddec1ad50cd597a985588434ce19c6f044a1696b5f244b899b7e77d4f6f20213ae8eb15d37eb8e67e6c8bdbc4fd6e17426283da96f23a897b210058c7c70fb126a5bf606dbeb1a6d5cca04184c4e95c2e8a70f50f5c1eabd066bd79c180456316ac02d366eb3b0e7ba82fb70dcbd737ca55734579dd250fffa8e0584be99d32b35", + "HMAC-SHA-256": "dad91293dfcf2a7c8ecd13fe353fa75b", + "AES-CBC-encrypt": "078609a6c5ac2544699adf682fa377f9be8ab6aef563e8c56a36b84f557fadd3", + "AES-CBC-decrypt": "347aa5a024b28257b36510be583d4f47adb7bbeedc6005bbbd0d0a9f06bb7b10", + "AES-GCM-encrypt": "8fcc4099808e75caaff582898848a88d808b55ab4e9370797d940be8cc1d7884", + "AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c", + "DRBG": "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27", + "DRBG-reseed": "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe", + "SHA-1": "132fd9bad5c1826263bafbb699f707a5", + "SHA-256": "ff3b857da7236a2baa0f396b51522217", + "SHA-512": "212512f8d2ad8322781c6c4d69a9daa1", + "SHA3-256": "d83c721ee51b060c5a41438a8221e040", + "HKDF-SHA-256": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "TLS-KDF": "abc3657b094c7628a0b282996fe75a75f4984fd94d4ecc2fcf53a2c469a3f731", + "PBKDF2": "70617373776F726450415353574F524470617373776F7264", + "SSKDF": "39a1e2b3899e87efecf6271282d8f8008f252686dd35bfc39a0f71478da48c691565cee431254dd50cab7462c6cf199be9bf5c", + "KBKDF": "dd1d91b7d90b2bd3138533ce92b272fbf8a369316aefe242e659cc0ae238afe0", + "RSA-sign": "d2b56e53306f720d7929d8708bf46f1c22300305582b115bedcac722d8aa5ab2", + "RSA-verify": "c5ef030d00a13e3a705b23e1e3de3f2c8e84b2e82d1bec14116f8245e5b6fa4b207f12afe72c8d36675acb7d670f6a5c590e44716c3df31104bea89f61becd6cc188814801d308ceec2a843ec7f25ebcdde588dd8980326928b10843c4b3190338b0a07c5a94a53f6d84de7947f3db3d9f730610bf463c291fd901ab8a54e47dbb196d8af53ef15fd06b7ad0ddb65c83c8fee8d0a708334733cbe7b03322695d9a406a687867b38294d8634805d4cb68737355d776484df3cd8b8feb51fd94608218d88eb2f2d04064312ad0412e7a96d49a9d71d76606ab7a5bd99bc31c37593c837f15ba8601926a1f6919d1110b55906e18e29e2a94045ae9218bc6c8da74", + "ECDSA-sign": "1e35930be860d0942ca7bbd6f6ded87f157e4de24f81ed4b875c0e018e89a81f", + "ECDSA-verify": "6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c3c77d1b6e09e747bc5ab5501d75e618d8e5b272e159ff3413cb71a81408d5605", + "Z-computation": "e7604491269afb5b102d6ea52cb59feb70aede6ce3bfb3e0105485abd861d77b", + "FFDH": "a14f8ad36be37b18b8f35864392f150ab7ee22c47e1870052a3f17918274af18aaeaf4cf6aacfde96c9d586eb7ebaff6b03fe3b79a8e2ff9dd6df34caaf2ac70fd3771d026b41a561ee90e4337d0575f8a0bd160c868e7e3cef88aa1d88448b1e4742ba11480a9f8a8b737347c408d74a7d57598c48875629df0c85327a124ddec1ad50cd597a985588434ce19c6f044a1696b5f244b899b7e77d4f6f20213ae8eb15d37eb8e67e6c8bdbc4fd6e17426283da96f23a897b210058c7c70fb126a5bf606dbeb1a6d5cca04184c4e95c2e8a70f50f5c1eabd066bd79c180456316ac02d366eb3b0e7ba82fb70dcbd737ca55734579dd250fffa8e0584be99d32b35", + "ED25519-sign": "1961d1d52d8c045fdfc1c682b35f07aae1d3b6e548639830eed929bc122d799f", + "ED25519-verify": "44f238f7ea7154cedd95631144078ffec655938f73e29676728b400f8f46c8048d5bf3ab124342ebae54b6e04f3f167b5ee8bdcfec9be6ff65bcc69a7889670a", + "ED25519ph-sign": "f9bfec63c4e073fa971a80499147d00acd26aae1ff0364db20f8a7a4954db387", + "ED25519ph-verify": "101bcca256ef620bb087592e917336d8542b71728e2a2748c55c719b825dad4521bfb375624b27fff81cbf7165e5ba4a98e8c451b3c3c2fa23278f2bb7458107", + "ML-KEM-keyGen-decaps": "88c12ceaa6cb91f589acb86d913c7a60f7cdabe3b7b590091d0084e29a049b436841f2473b03165ae9c6a9826d6c650d04b388eff594505b7e54709530546825a070a625b0e5fa866e6aaf40c2414246240973c7598aae7c363e4303abb7a11131b464a943996de7592ca04922ea8a4d73b443ea048c06acc4e55a8f254bf6d271fd827119ec5b5580498bfcc09eb0266f8c2b45988ae98c1e5402b7003463f20359470159c0509fa971153443ce2580c0b2443f8ac2b0810401e73052d626bf58c674ee48880c408d1f313a94b1667f897628c55a83e28634a20710d25da88b2ac90c0f5d6b0ed6e080fd2c24bb11816b5c607957781db2287966717ffa500a03025839164115ba5ea7b717344588169e8a85a9e83c516cab5ee6e63b7c736ce90628ddeca99a6bc547588681bc2223f39fbc4464b41c63d924afeba1098960bd43c12fd0080f490c8c50f4843222303c6821ad7b663d8844a1368a19549e5cfc83d14a8491205c44f5492bf609b69c526c95aa5e508ecf714b7955b61f6cab340b06200432ce3b1ecd0a075a8332046865959a25698a081df3532691348a2581d606a0e0b2cf2e8b3c9afc594e926eb0d7c702c0c3e5b54ee2c86ca20cc476aaaca3208f32a20190562c27338202071e11665f134273bdaacbc952b994ba9462671226514b446113e7ab7edb9c54c311c4da94104d262a80280e39201e755191763983c439a95aeaafa767c2cb594829e6313e386982d6621acc4bb0991a60790a2b0c5f3139aadd7045f7d849aa209bf60bc15ed82667414b70b71a7e184e164280af00bf95a9ad3de41dcf19623610cfb30687a5a082a2458870eb33d649b3fce3317e0362ee6175fb811c7fe3647ca21020673aedd23bf0470cd8735ce53a78082668e49a5132d1336a084360187fcff9227cdc0d7f205b2af2c88dc6bc9a04b41f429fa9a386f58b8f216cbf6714a619597caa5a9bf668048d7135105a9425cb46fe807a406459b067b716f5a47730974b207826716fe3f747fd74cd8c025720b1003f27b2dea695f221971cd5af81a1a795001f125c285c150ddc9959e9e0220a694556bc0a4b5aade032b2aa877c0da816ef32a84d77bbff4656e680854e6961a417082bd46f5023c47cea09bba2145d415188e13803bb5e7fc19d39819e59ca7fdc38051d969401d4c411dac00a47ab57527daa897a37759351b4b1185b1496d79aa33229bea3c0e8dbcf1d7a64730928775c74c946181bb88e0a38a165ebbdc7860b014c59894c7211bc23d39077e62944d3c48c434b737b1a64b5f9a1646a18a5195a54603ffc280bf5ea1bf3d8cb4112aa82fab89e2633665597bed30de6c8897a9613ea8c11736524a7086266523fbab887465494ebfc96fbe4466775bc0d707e624bb3de700eaac9b37c2bc12b52aa2dfb73b7006bd956c0b9324c47295e4e4c4cc47ba9b5a899694b38a64a29120684bf64c648211b18d017ce34849c4a092b24bcb8960d870422ebd954bc7264ba95a727a31926f31c12381d0d051e1e04190b949322442845f3aa6fb17940442a9c1a183b2397dcc0770cb2b4a07aaf0af52636778ac9949d2db42f3d036bc842b2f3b0b11d278ea025cc16ac8b6986a9b18b3356790dbc821d0ac7b5eae965fcf14b0e202b00ec5d707c45af52be2d9771bcc53b31f2525ab53f95a3b00242c11c494e2554438b0a4f68194019181bbdb194910307bc19afae553dd666564332c078604fbd8bc4fdc92f9201809ab495c1b535530bad2eb35753f91956b58bfbf62d1e33c861f73846334c4a2ac5576984ef1163a50454a3e4ce838898f225868189bdae5a03efd8001d2a9f557cb6cd93a46fbb1379d81645b853cb98b47ba87a66fcbc0ada76506b8dcd659042640ef616820ff20b26433399371dc4c50287349ca2763e3073865c5bc9aaa1437b86b20b25b6f088bd6a4c9483842d7c65257cc42ad7c7b26f58c8ed199b848b8c6f408d487637751888a95a449cab47b7a2ace6a82c7d46910526414ab149b11343b0ea32d969a508a81cf896b081087f4d52a2a9e077878a43e5971d74863a7bf20037b2974703140ea8160a5ba72227c15bec5df171140198896d31732a241f5b938ff233cba2dc82de91c6b493782b6163bc1282df855ee6a6a65975b33cb6a27d258bd317d04cef8eb557ba02d49471923cd60e9917966be90f56d2d53fa3bc2629740abbd16720a9a7069a64de7a26328817d74a7c2f55a2461b074bff8044445e11660b1b6b26df242b8fc02b9e8df538db17a639d7c46132", + "ML-KEM-keyGen-encaps": "a7cc68f8d02110ca5720223b9e2a8987c8a24835a20dabcbefa430e74a85af80b9b74b74574c5e5f585459ca3610940f0b57b33344ceacccc135557b82f4968688a0168c1aa2940e5604482bf8b900a4343096446330cfee10917c0338181b7fe8d30f4816087d6299f225417f533ee40473894847bd45291367be6b1a7dee55bb21d60e3828552f4c8a6f3c54fc74cf67a614eeab002a076851879cef2218fdb3766123c2de32a269b6aa4661b69370314c004446f7258c40b2ea789f40ca023bbb1217c2c44b380c6e3194edd129d039218d9b75194a386d944acce7a9720ab026362004e95bf9229290b53613416082e82ba8a42a5ff14759f57712395706b307f7635ecee42317a48eb3b90683f3ab53d17c50f53c6cfb1c0cf59d6f2a981021428a7ac5edf13b26844d83c31d3608710e623aabb24b6c5b48baebc1b3078972589201b7a30bc09315612b067655bec403a69c89eb137c31157971098cb693ba4ae9ae40a8031cec92580bcc1b5ab3ecd1aa5f79aa2cd69249d138c8965a81c87a07eb59a4612e60658f4df028cef8af1b837e0ab0bfedb726904290d0bc41df6a67f7a4166609952439631960648e229a21f2a4d82abad3ec8135dc9bb43c703d3b33e437c9ef7bca91c3465676740125a15ad1707088b101b4273d3c4bf30181b4b2575de75ccfc13312a2a6bcebc477a9668e751629b569bfa20beca09800992c63f04b6b4a7df977a00131c2f8722e5138775235b517a709852167c1d415fdc7ad32f2aaca437e9cc6b248d9ca7c65b405e68d24e81b8688caa22b3cf5c9b147f0cc27e667a80b83ccbb4f4161a5ffd0194b1b5720e68ea0f59997f26740972d2c8124d7a6ad8327c2075a3f76b968d2aaad19c00697599e0be49fa6d65b4088b0be692dcda028095852a0d7205e4417409c0317780305a878fb582963b6953f6b8f0880b050178301d659be3a4db7e0bf2587129164178f32707d40392d85713dea82913999aa6c35aa94b3547abe40e2b0ba82b5b78319182a5a47d173176ba6fa3a4d70a8130b310743fa8aaae314381c9b7f49991f19a4ff8369638de380b5d828b7b5fcfdd91fe68efe16d4cd9eed66d65c1d2d8caf5af4a692", + "ML-KEM-encapsulate-ciphertext": "431a4f1b2d2c6c00f1690bbe482541ef3d563774daff83207f96de7e5e4a59d5d936d9443ad422e645793e7a60a9b0a76cd672d20c69b82a5563df52d96f9a6cdfc56fbd4fd8d5a8afeb2a09d92ec854094794b4ed2db381f04c68439608aa9902a4d1689e2eb1e5f07a4a1c709262d7c2ff2f81f6eeaab2a86a41ba210eb1bf8e75febccd1a15b4d7a7b60257c89d00bd81d39fcb8d1ce3278102595dd652f7fb7d5584874f3327b174043b350ebd4d41fe08bd0e854d41cbb027c481da64dc6151b88dececcf022ddac2e22736c147e0773294231c0589967154c526b0b7cdd59568eeff5749a40cb100c60c6480897655d96e9f64d61684c0b3150646732c19409fe565540a31894703cf0179cae85bc8c1a5732649836e48e676405b9591b65ba25f9b489b9e5772aa1ed5a00143cb9f5449fd013457a3c13874cb58c75b52c9b6a9ae495ccb504a89cb5f145695b921632fb85b0316b30d4ad17fef0862d6b1e6ca6a611c8a6a7234b4362c5ca0ad9f7697687798cf624dc9f35fbb376e09953156532a9033709df755b46cc6d83de3a111e19a76b361e0ef14c91db8d91c6c6d9e3e46f42291fd6cbf5cfd122716fb0675698e602ab39ee98e0d8145eebaaa9374f5b3bb0df4d0fd83a40e0d25038c39e9bee01cf79c86f3086158d031d5c5e86bc7e7eb16e622505f2888213884c0b5252289b11fce5bfeebfbef0a32ceaf9c14c6250090028463db6f8d19684f541108fe934d88e7ef5cce9daebb32700b9397691a684298c9bf1b7c22d1bcec3fcacfbb17f2ed2b98b85e6a8fe2482996b5e099e9d0211cb9412614de87dc18d23613ed7f6c29cc37b727116dd901c2817938c29fcd026089336addc09eca90de9a25a6374fee86bcdd06ae3daaf0b1bc5b3b2790d4d9f759bef8ac743612a2bbf6e45de8b22efa61226625d4c39f346b844c5ebec5355866c00b726cc1640cb237c34a20a7c603d251f46e6b3b0fa71b3276835e3e9da5b9485e789614af49f1e9504db2528631fbe1cd7dbee85164e4c099a27a4583e9247d078f8830b46874c1b010bf3cd90eb0774961f239ba", + "ML-KEM-encapsulate-shared-secret": "a772df2de250ac7d896bbb820b57f2ae05f9a412ab55baa421d4af6dac62662a", } listTests = flag.Bool("list-tests", false, "List known test values and exit") diff --git a/util/fipstools/test-break-kat.sh b/util/fipstools/test-break-kat.sh index 86f58e23ce..b586f8e9f0 100755 --- a/util/fipstools/test-break-kat.sh +++ b/util/fipstools/test-break-kat.sh @@ -32,8 +32,9 @@ KATS=$(go run util/fipstools/break-kat.go --list-tests) for kat in $KATS; do go run util/fipstools/break-kat.go $TEST_FIPS_BIN $kat > break-kat-bin chmod u+x ./break-kat-bin - if ! (./break-kat-bin 2>&1 >/dev/null || true) | \ - egrep -q "^$kat[^a-zA-Z0-9]"; then + # Only capture stderr + output=$(2>&1 ./break-kat-bin 2>&1 >/dev/null || true) + if ! echo "$output" | egrep -q "^${kat}[^a-zA-Z0-9]"; then echo "Failure for $kat did not mention that name in the output" exit 1 fi diff --git a/util/fipstools/test_fips.c b/util/fipstools/test_fips.c index fae8665f27..7593b6d59c 100644 --- a/util/fipstools/test_fips.c +++ b/util/fipstools/test_fips.c @@ -22,16 +22,20 @@ #include #include #include +#include #include #include -#include #include +#include +#include #include #include #include #include #include +#include "../../crypto/fipsmodule/evp/internal.h" +#include "../../crypto/fipsmodule/kem/internal.h" #include "../../crypto/fipsmodule/rand/internal.h" #include "../../crypto/internal.h" @@ -394,6 +398,52 @@ int main(int argc, char **argv) { ECDSA_SIG_free(sig); EC_KEY_free(ec_key); + /* Ed25519 */ + printf("About to Ed25519 sign "); + hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256)); + uint8_t ed_public_key[ED25519_PUBLIC_KEY_LEN]; + uint8_t ed_private_key[ED25519_PRIVATE_KEY_LEN]; + ED25519_keypair(ed_public_key, ed_private_key); + uint8_t ed_signature[ED25519_SIGNATURE_LEN]; + if (!ED25519_sign(ed_signature,kPlaintextSHA256, sizeof(kPlaintextSHA256), ed_private_key) || + !ED25519_verify(kPlaintextSHA256, sizeof(kPlaintextSHA256), ed_signature, ed_public_key)) { + printf("ED25519 Sign/Verify PWCT failed.\n"); + goto err; + } + printf("got signature "); + hexdump(ed_signature, sizeof(ed_signature)); + + /* Ed25519ph */ + printf("About to Ed25519ph sign "); + hexdump(kPlaintextSHA256, sizeof(kPlaintextSHA256)); + uint8_t ed25519_ph_context[32] = { + 0xfe, 0x52, 0xbb, 0xd2, 0x45, 0x54, 0x46, 0xad, 0xa5, 0x24, 0x6b, 0x5a, + 0xf3, 0xba, 0x82, 0x93, 0x9c, 0xed, 0xa6, 0xa1, 0x8f, 0x59, 0xd3, 0x37, + 0x48, 0xde, 0x40, 0x7a, 0xfe, 0x31, 0x48, 0xd1 + }; + if (!ED25519ph_sign(ed_signature, kPlaintextSHA256, sizeof(kPlaintextSHA256), ed_private_key, ed25519_ph_context, sizeof(ed25519_ph_context)) || + !ED25519ph_verify(kPlaintextSHA256, sizeof(kPlaintextSHA256), ed_signature, ed_public_key, ed25519_ph_context, sizeof(ed25519_ph_context))) { + printf("ED25519ph Sign/Verify PWCT failed.\n"); + goto err; + } + printf("got signature "); + hexdump(ed_signature, sizeof(ed_signature)); + + /* ML-KEM */ + printf("About to Generate ML-KEM key\n"); + EVP_PKEY *raw = NULL; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, NULL); + if (ctx == NULL || !EVP_PKEY_CTX_kem_set_params(ctx, NID_MLKEM512) || + !EVP_PKEY_keygen_init(ctx) || + !EVP_PKEY_keygen(ctx, &raw)) { + printf("ML-KEM keygen failed.\n"); + goto err; + } + printf("Generated public key: "); + hexdump(raw->pkey.kem_key->public_key, raw->pkey.kem_key->kem->public_key_len); + EVP_PKEY_free(raw); + EVP_PKEY_CTX_free(ctx); + /* DBRG */ CTR_DRBG_STATE drbg; printf("About to seed CTR-DRBG with ");