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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4333,6 +4333,27 @@ std::optional<EVP_PKEY_CTX*> 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<char*>("Ed25519ctx"), 0),
OSSL_PARAM_construct_octet_string(
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
const_cast<unsigned char*>(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,
Expand All @@ -4357,6 +4378,27 @@ std::optional<EVP_PKEY_CTX*> 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<char*>("Ed25519ctx"), 0),
OSSL_PARAM_construct_octet_string(
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
const_cast<unsigned char*>(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,
Expand Down
21 changes: 15 additions & 6 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -6037,6 +6037,9 @@ Throws an error if FIPS mode is not available.
<!-- YAML
added: v12.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62474
description: Add support for Ed25519 context parameter.
- version: v24.8.0
pr-url: https://github.com/nodejs/node/pull/59570
description: Add support for ML-DSA, Ed448, and SLH-DSA context parameter.
Expand Down Expand Up @@ -6100,9 +6103,10 @@ additional properties can be passed:
`crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest
size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the
maximum permissible value.
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed448, ML-DSA, and SLH-DSA,
this option specifies the optional context to differentiate signatures generated
for different purposes with the same key.
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed25519[^openssl32]
(using Ed25519ctx from [RFC 8032][]), Ed448, ML-DSA, and SLH-DSA,
this option specifies the optional context to differentiate signatures
generated for different purposes with the same key.

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

Expand Down Expand Up @@ -6162,6 +6166,9 @@ not introduce timing vulnerabilities.
<!-- YAML
added: v12.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62474
description: Add support for Ed25519 context parameter.
- version: v24.8.0
pr-url: https://github.com/nodejs/node/pull/59570
description: Add support for ML-DSA, Ed448, and SLH-DSA context parameter.
Expand Down Expand Up @@ -6231,9 +6238,10 @@ additional properties can be passed:
`crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest
size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the
maximum permissible value.
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed448, ML-DSA, and SLH-DSA,
this option specifies the optional context to differentiate signatures generated
for different purposes with the same key.
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed25519[^openssl32]
(using Ed25519ctx from [RFC 8032][]), Ed448, ML-DSA, and SLH-DSA,
this option specifies the optional context to differentiate signatures
generated for different purposes with the same key.

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

Expand Down Expand Up @@ -6832,6 +6840,7 @@ See the [list of SSL OP Flags][] for details.
[RFC 5208]: https://www.rfc-editor.org/rfc/rfc5208.txt
[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280.txt
[RFC 7517]: https://www.rfc-editor.org/rfc/rfc7517.txt
[RFC 8032]: https://www.rfc-editor.org/rfc/rfc8032.txt
[Web Crypto API documentation]: webcrypto.md
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
[`Buffer`]: buffer.md
Expand Down
1 change: 1 addition & 0 deletions src/crypto/crypto_sig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ bool SupportsContextString(const EVPKeyPointer& key) {
return false;
#else
switch (key.id()) {
case EVP_PKEY_ED25519:
case EVP_PKEY_ED448:
#if OPENSSL_WITH_PQC
case EVP_PKEY_ML_DSA_44:
Expand Down
Loading
Loading