Skip to content

Commit dd20526

Browse files
committed
crypto: add support for Ed25519 context parameter
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent cf2b05c commit dd20526

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
@@ -4333,6 +4333,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
43334333
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
43344334
EVP_PKEY_CTX* ctx = nullptr;
43354335

4336+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4337+
// Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode.
4338+
// Without it, OpenSSL silently ignores the context string.
4339+
if (key.id() == EVP_PKEY_ED25519) {
4340+
const OSSL_PARAM params[] = {
4341+
OSSL_PARAM_construct_utf8_string(
4342+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4343+
OSSL_PARAM_construct_octet_string(
4344+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4345+
const_cast<unsigned char*>(context_string.data),
4346+
context_string.len),
4347+
OSSL_PARAM_END};
4348+
4349+
if (!EVP_DigestSignInit_ex(
4350+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4351+
return std::nullopt;
4352+
}
4353+
return ctx;
4354+
}
4355+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4356+
43364357
const OSSL_PARAM params[] = {
43374358
OSSL_PARAM_construct_octet_string(
43384359
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
@@ -4357,6 +4378,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
43574378
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
43584379
EVP_PKEY_CTX* ctx = nullptr;
43594380

4381+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4382+
// Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode.
4383+
// Without it, OpenSSL silently ignores the context string.
4384+
if (key.id() == EVP_PKEY_ED25519) {
4385+
const OSSL_PARAM params[] = {
4386+
OSSL_PARAM_construct_utf8_string(
4387+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4388+
OSSL_PARAM_construct_octet_string(
4389+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4390+
const_cast<unsigned char*>(context_string.data),
4391+
context_string.len),
4392+
OSSL_PARAM_END};
4393+
4394+
if (!EVP_DigestVerifyInit_ex(
4395+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4396+
return std::nullopt;
4397+
}
4398+
return ctx;
4399+
}
4400+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4401+
43604402
const OSSL_PARAM params[] = {
43614403
OSSL_PARAM_construct_octet_string(
43624404
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,

doc/api/crypto.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6037,6 +6037,9 @@ Throws an error if FIPS mode is not available.
60376037
<!-- YAML
60386038
added: v12.0.0
60396039
changes:
6040+
- version: REPLACEME
6041+
pr-url: https://github.com/nodejs/node/pull/62474
6042+
description: Add support for Ed25519 context parameter.
60406043
- version: v24.8.0
60416044
pr-url: https://github.com/nodejs/node/pull/59570
60426045
description: Add support for ML-DSA, Ed448, and SLH-DSA context parameter.
@@ -6100,9 +6103,10 @@ additional properties can be passed:
61006103
`crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest
61016104
size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the
61026105
maximum permissible value.
6103-
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed448, ML-DSA, and SLH-DSA,
6104-
this option specifies the optional context to differentiate signatures generated
6105-
for different purposes with the same key.
6106+
* `context` {ArrayBuffer|Buffer|TypedArray|DataView} For Ed25519[^openssl32]
6107+
(using Ed25519ctx from [RFC 8032][]), Ed448, ML-DSA, and SLH-DSA,
6108+
this option specifies the optional context to differentiate signatures
6109+
generated for different purposes with the same key.
61066110

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

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

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

@@ -6832,6 +6840,7 @@ See the [list of SSL OP Flags][] for details.
68326840
[RFC 5208]: https://www.rfc-editor.org/rfc/rfc5208.txt
68336841
[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280.txt
68346842
[RFC 7517]: https://www.rfc-editor.org/rfc/rfc7517.txt
6843+
[RFC 8032]: https://www.rfc-editor.org/rfc/rfc8032.txt
68356844
[Web Crypto API documentation]: webcrypto.md
68366845
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
68376846
[`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)