Skip to content

Commit 9df9b66

Browse files
authored
crypto: add support for Ed25519 context parameter
Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #62474 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent e7a900d commit 9df9b66

File tree

5 files changed

+301
-9
lines changed

5 files changed

+301
-9
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4363,6 +4363,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
43634363
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
43644364
EVP_PKEY_CTX* ctx = nullptr;
43654365

4366+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4367+
// Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode.
4368+
// Without it, OpenSSL silently ignores the context string.
4369+
if (key.id() == EVP_PKEY_ED25519) {
4370+
const OSSL_PARAM params[] = {
4371+
OSSL_PARAM_construct_utf8_string(
4372+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4373+
OSSL_PARAM_construct_octet_string(
4374+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4375+
const_cast<unsigned char*>(context_string.data),
4376+
context_string.len),
4377+
OSSL_PARAM_END};
4378+
4379+
if (!EVP_DigestSignInit_ex(
4380+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4381+
return std::nullopt;
4382+
}
4383+
return ctx;
4384+
}
4385+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4386+
43664387
const OSSL_PARAM params[] = {
43674388
OSSL_PARAM_construct_octet_string(
43684389
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
@@ -4387,6 +4408,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
43874408
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
43884409
EVP_PKEY_CTX* ctx = nullptr;
43894410

4411+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4412+
// Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode.
4413+
// Without it, OpenSSL silently ignores the context string.
4414+
if (key.id() == EVP_PKEY_ED25519) {
4415+
const OSSL_PARAM params[] = {
4416+
OSSL_PARAM_construct_utf8_string(
4417+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4418+
OSSL_PARAM_construct_octet_string(
4419+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4420+
const_cast<unsigned char*>(context_string.data),
4421+
context_string.len),
4422+
OSSL_PARAM_END};
4423+
4424+
if (!EVP_DigestVerifyInit_ex(
4425+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4426+
return std::nullopt;
4427+
}
4428+
return ctx;
4429+
}
4430+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4431+
43904432
const OSSL_PARAM params[] = {
43914433
OSSL_PARAM_construct_octet_string(
43924434
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,

doc/api/crypto.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6060,6 +6060,9 @@ Throws an error if FIPS mode is not available.
60606060
<!-- YAML
60616061
added: v12.0.0
60626062
changes:
6063+
- version: REPLACEME
6064+
pr-url: https://github.com/nodejs/node/pull/62474
6065+
description: Add support for Ed25519 context parameter.
60636066
- version: v24.8.0
60646067
pr-url: https://github.com/nodejs/node/pull/59570
60656068
description: Add support for ML-DSA, Ed448, and SLH-DSA context parameter.
@@ -6123,9 +6126,10 @@ additional properties can be passed:
61236126
`crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest
61246127
size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the
61256128
maximum permissible value.
6126-
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed448, ML-DSA, and SLH-DSA,
6127-
this option specifies the optional context to differentiate signatures generated
6128-
for different purposes with the same key.
6129+
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed25519[^openssl32]
6130+
(using Ed25519ctx from [RFC 8032][]), Ed448, ML-DSA, and SLH-DSA,
6131+
this option specifies the optional context to differentiate signatures
6132+
generated for different purposes with the same key.
61296133

61306134
If the `callback` function is provided this function uses libuv's threadpool.
61316135

@@ -6185,6 +6189,9 @@ not introduce timing vulnerabilities.
61856189
<!-- YAML
61866190
added: v12.0.0
61876191
changes:
6192+
- version: REPLACEME
6193+
pr-url: https://github.com/nodejs/node/pull/62474
6194+
description: Add support for Ed25519 context parameter.
61886195
- version: v24.8.0
61896196
pr-url: https://github.com/nodejs/node/pull/59570
61906197
description: Add support for ML-DSA, Ed448, and SLH-DSA context parameter.
@@ -6254,9 +6261,10 @@ additional properties can be passed:
62546261
`crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest
62556262
size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the
62566263
maximum permissible value.
6257-
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed448, ML-DSA, and SLH-DSA,
6258-
this option specifies the optional context to differentiate signatures generated
6259-
for different purposes with the same key.
6264+
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed25519[^openssl32]
6265+
(using Ed25519ctx from [RFC 8032][]), Ed448, ML-DSA, and SLH-DSA,
6266+
this option specifies the optional context to differentiate signatures
6267+
generated for different purposes with the same key.
62606268

62616269
The `signature` argument is the previously calculated signature for the `data`.
62626270

@@ -6855,6 +6863,7 @@ See the [list of SSL OP Flags][] for details.
68556863
[RFC 5208]: https://www.rfc-editor.org/rfc/rfc5208.txt
68566864
[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280.txt
68576865
[RFC 7517]: https://www.rfc-editor.org/rfc/rfc7517.txt
6866+
[RFC 8032]: https://www.rfc-editor.org/rfc/rfc8032.txt
68586867
[Web Crypto API documentation]: webcrypto.md
68596868
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
68606869
[`Buffer`]: buffer.md

src/crypto/crypto_sig.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ bool SupportsContextString(const EVPKeyPointer& key) {
241241
return false;
242242
#else
243243
switch (key.id()) {
244+
case EVP_PKEY_ED25519:
244245
case EVP_PKEY_ED448:
245246
#if OPENSSL_WITH_PQC
246247
case EVP_PKEY_ML_DSA_44:

0 commit comments

Comments
 (0)