From dd205266f1cd28c2b0d87fb8c7cd2f1dec0321d4 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 28 Mar 2026 11:26:23 +0100 Subject: [PATCH] crypto: add support for Ed25519 context parameter Signed-off-by: Filip Skokan --- deps/ncrypto/ncrypto.cc | 42 +++++ doc/api/crypto.md | 21 ++- src/crypto/crypto_sig.cc | 1 + test/parallel/test-crypto-eddsa-variants.js | 198 ++++++++++++++++++++ test/parallel/test-crypto-sign-verify.js | 48 ++++- 5 files changed, 301 insertions(+), 9 deletions(-) create mode 100644 test/parallel/test-crypto-eddsa-variants.js diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 87a6b7a3501e4d..dce78a33026b3c 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -4333,6 +4333,27 @@ std::optional EVPMDCtxPointer::signInitWithContext( #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING EVP_PKEY_CTX* ctx = nullptr; +#ifdef OSSL_SIGNATURE_PARAM_INSTANCE + // Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode. + // Without it, OpenSSL silently ignores the context string. + if (key.id() == EVP_PKEY_ED25519) { + const OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string( + OSSL_SIGNATURE_PARAM_INSTANCE, const_cast("Ed25519ctx"), 0), + OSSL_PARAM_construct_octet_string( + OSSL_SIGNATURE_PARAM_CONTEXT_STRING, + const_cast(context_string.data), + context_string.len), + OSSL_PARAM_END}; + + if (!EVP_DigestSignInit_ex( + ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) { + return std::nullopt; + } + return ctx; + } +#endif // OSSL_SIGNATURE_PARAM_INSTANCE + const OSSL_PARAM params[] = { OSSL_PARAM_construct_octet_string( OSSL_SIGNATURE_PARAM_CONTEXT_STRING, @@ -4357,6 +4378,27 @@ std::optional EVPMDCtxPointer::verifyInitWithContext( #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING EVP_PKEY_CTX* ctx = nullptr; +#ifdef OSSL_SIGNATURE_PARAM_INSTANCE + // Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode. + // Without it, OpenSSL silently ignores the context string. + if (key.id() == EVP_PKEY_ED25519) { + const OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string( + OSSL_SIGNATURE_PARAM_INSTANCE, const_cast("Ed25519ctx"), 0), + OSSL_PARAM_construct_octet_string( + OSSL_SIGNATURE_PARAM_CONTEXT_STRING, + const_cast(context_string.data), + context_string.len), + OSSL_PARAM_END}; + + if (!EVP_DigestVerifyInit_ex( + ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) { + return std::nullopt; + } + return ctx; + } +#endif // OSSL_SIGNATURE_PARAM_INSTANCE + const OSSL_PARAM params[] = { OSSL_PARAM_construct_octet_string( OSSL_SIGNATURE_PARAM_CONTEXT_STRING, diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 8f3f1fac1fae0b..e64c36b6ac98dc 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -6037,6 +6037,9 @@ Throws an error if FIPS mode is not available.