Skip to content

Commit 430691d

Browse files
panvatargos
authored andcommitted
crypto: support SLH-DSA KeyObject, sign, and verify
PR-URL: #59537 Reviewed-By: Tobias Nießen <[email protected]>
1 parent 5bfdc7e commit 430691d

33 files changed

+542
-37
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ constexpr static PQCMapping pqc_mappings[] = {
3030
{"ML-KEM-512", EVP_PKEY_ML_KEM_512},
3131
{"ML-KEM-768", EVP_PKEY_ML_KEM_768},
3232
{"ML-KEM-1024", EVP_PKEY_ML_KEM_1024},
33+
{"SLH-DSA-SHA2-128f", EVP_PKEY_SLH_DSA_SHA2_128F},
34+
{"SLH-DSA-SHA2-128s", EVP_PKEY_SLH_DSA_SHA2_128S},
35+
{"SLH-DSA-SHA2-192f", EVP_PKEY_SLH_DSA_SHA2_192F},
36+
{"SLH-DSA-SHA2-192s", EVP_PKEY_SLH_DSA_SHA2_192S},
37+
{"SLH-DSA-SHA2-256f", EVP_PKEY_SLH_DSA_SHA2_256F},
38+
{"SLH-DSA-SHA2-256s", EVP_PKEY_SLH_DSA_SHA2_256S},
39+
{"SLH-DSA-SHAKE-128f", EVP_PKEY_SLH_DSA_SHAKE_128F},
40+
{"SLH-DSA-SHAKE-128s", EVP_PKEY_SLH_DSA_SHAKE_128S},
41+
{"SLH-DSA-SHAKE-192f", EVP_PKEY_SLH_DSA_SHAKE_192F},
42+
{"SLH-DSA-SHAKE-192s", EVP_PKEY_SLH_DSA_SHAKE_192S},
43+
{"SLH-DSA-SHAKE-256f", EVP_PKEY_SLH_DSA_SHAKE_256F},
44+
{"SLH-DSA-SHAKE-256s", EVP_PKEY_SLH_DSA_SHAKE_256S},
3345
};
3446

3547
#endif
@@ -2659,6 +2671,18 @@ bool EVPKeyPointer::isOneShotVariant() const {
26592671
case EVP_PKEY_ML_DSA_44:
26602672
case EVP_PKEY_ML_DSA_65:
26612673
case EVP_PKEY_ML_DSA_87:
2674+
case EVP_PKEY_SLH_DSA_SHA2_128F:
2675+
case EVP_PKEY_SLH_DSA_SHA2_128S:
2676+
case EVP_PKEY_SLH_DSA_SHA2_192F:
2677+
case EVP_PKEY_SLH_DSA_SHA2_192S:
2678+
case EVP_PKEY_SLH_DSA_SHA2_256F:
2679+
case EVP_PKEY_SLH_DSA_SHA2_256S:
2680+
case EVP_PKEY_SLH_DSA_SHAKE_128F:
2681+
case EVP_PKEY_SLH_DSA_SHAKE_128S:
2682+
case EVP_PKEY_SLH_DSA_SHAKE_192F:
2683+
case EVP_PKEY_SLH_DSA_SHAKE_192S:
2684+
case EVP_PKEY_SLH_DSA_SHAKE_256F:
2685+
case EVP_PKEY_SLH_DSA_SHAKE_256S:
26622686
#endif
26632687
return true;
26642688
default:

doc/api/crypto.md

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,35 @@ try {
7777

7878
The following table lists the asymmetric key types recognized by the [`KeyObject`][] API:
7979

80-
| Key Type | Description | OID |
81-
| --------------------------- | -------------- | ----------------------- |
82-
| `'dh'` | Diffie-Hellman | 1.2.840.113549.1.3.1 |
83-
| `'dsa'` | DSA | 1.2.840.10040.4.1 |
84-
| `'ec'` | Elliptic curve | 1.2.840.10045.2.1 |
85-
| `'ed25519'` | Ed25519 | 1.3.101.112 |
86-
| `'ed448'` | Ed448 | 1.3.101.113 |
87-
| `'ml-dsa-44'`[^openssl35] | ML-DSA-44 | 2.16.840.1.101.3.4.3.17 |
88-
| `'ml-dsa-65'`[^openssl35] | ML-DSA-65 | 2.16.840.1.101.3.4.3.18 |
89-
| `'ml-dsa-87'`[^openssl35] | ML-DSA-87 | 2.16.840.1.101.3.4.3.19 |
90-
| `'ml-kem-1024'`[^openssl35] | ML-KEM-1024 | 2.16.840.1.101.3.4.4.3 |
91-
| `'ml-kem-512'`[^openssl35] | ML-KEM-512 | 2.16.840.1.101.3.4.4.1 |
92-
| `'ml-kem-768'`[^openssl35] | ML-KEM-768 | 2.16.840.1.101.3.4.4.2 |
93-
| `'rsa-pss'` | RSA PSS | 1.2.840.113549.1.1.10 |
94-
| `'rsa'` | RSA | 1.2.840.113549.1.1.1 |
95-
| `'x25519'` | X25519 | 1.3.101.110 |
96-
| `'x448'` | X448 | 1.3.101.111 |
80+
| Key Type | Description | OID |
81+
| ---------------------------------- | ------------------ | ----------------------- |
82+
| `'dh'` | Diffie-Hellman | 1.2.840.113549.1.3.1 |
83+
| `'dsa'` | DSA | 1.2.840.10040.4.1 |
84+
| `'ec'` | Elliptic curve | 1.2.840.10045.2.1 |
85+
| `'ed25519'` | Ed25519 | 1.3.101.112 |
86+
| `'ed448'` | Ed448 | 1.3.101.113 |
87+
| `'ml-dsa-44'`[^openssl35] | ML-DSA-44 | 2.16.840.1.101.3.4.3.17 |
88+
| `'ml-dsa-65'`[^openssl35] | ML-DSA-65 | 2.16.840.1.101.3.4.3.18 |
89+
| `'ml-dsa-87'`[^openssl35] | ML-DSA-87 | 2.16.840.1.101.3.4.3.19 |
90+
| `'ml-kem-1024'`[^openssl35] | ML-KEM-1024 | 2.16.840.1.101.3.4.4.3 |
91+
| `'ml-kem-512'`[^openssl35] | ML-KEM-512 | 2.16.840.1.101.3.4.4.1 |
92+
| `'ml-kem-768'`[^openssl35] | ML-KEM-768 | 2.16.840.1.101.3.4.4.2 |
93+
| `'rsa-pss'` | RSA PSS | 1.2.840.113549.1.1.10 |
94+
| `'rsa'` | RSA | 1.2.840.113549.1.1.1 |
95+
| `'slh-dsa-sha2-128f'`[^openssl35] | SLH-DSA-SHA2-128f | 2.16.840.1.101.3.4.3.21 |
96+
| `'slh-dsa-sha2-128s'`[^openssl35] | SLH-DSA-SHA2-128s | 2.16.840.1.101.3.4.3.22 |
97+
| `'slh-dsa-sha2-192f'`[^openssl35] | SLH-DSA-SHA2-192f | 2.16.840.1.101.3.4.3.23 |
98+
| `'slh-dsa-sha2-192s'`[^openssl35] | SLH-DSA-SHA2-192s | 2.16.840.1.101.3.4.3.24 |
99+
| `'slh-dsa-sha2-256f'`[^openssl35] | SLH-DSA-SHA2-256f | 2.16.840.1.101.3.4.3.25 |
100+
| `'slh-dsa-sha2-256s'`[^openssl35] | SLH-DSA-SHA2-256s | 2.16.840.1.101.3.4.3.26 |
101+
| `'slh-dsa-shake-128f'`[^openssl35] | SLH-DSA-SHAKE-128f | 2.16.840.1.101.3.4.3.27 |
102+
| `'slh-dsa-shake-128s'`[^openssl35] | SLH-DSA-SHAKE-128s | 2.16.840.1.101.3.4.3.28 |
103+
| `'slh-dsa-shake-192f'`[^openssl35] | SLH-DSA-SHAKE-192f | 2.16.840.1.101.3.4.3.29 |
104+
| `'slh-dsa-shake-192s'`[^openssl35] | SLH-DSA-SHAKE-192s | 2.16.840.1.101.3.4.3.30 |
105+
| `'slh-dsa-shake-256f'`[^openssl35] | SLH-DSA-SHAKE-256f | 2.16.840.1.101.3.4.3.31 |
106+
| `'slh-dsa-shake-256s'`[^openssl35] | SLH-DSA-SHAKE-256s | 2.16.840.1.101.3.4.3.32 |
107+
| `'x25519'` | X25519 | 1.3.101.110 |
108+
| `'x448'` | X448 | 1.3.101.111 |
97109

98110
## Class: `Certificate`
99111

@@ -2046,6 +2058,9 @@ Other key details might be exposed via this API using additional attributes.
20462058
<!-- YAML
20472059
added: v11.6.0
20482060
changes:
2061+
- version: REPLACEME
2062+
pr-url: https://github.com/nodejs/node/pull/59537
2063+
description: Add support for SLH-DSA keys.
20492064
- version: v24.7.0
20502065
pr-url: https://github.com/nodejs/node/pull/59461
20512066
description: Add support for ML-KEM keys.
@@ -3911,6 +3926,9 @@ underlying hash function. See [`crypto.createHmac()`][] for more information.
39113926
<!-- YAML
39123927
added: v10.12.0
39133928
changes:
3929+
- version: REPLACEME
3930+
pr-url: https://github.com/nodejs/node/pull/59537
3931+
description: Add support for SLH-DSA key pairs.
39143932
- version: v24.7.0
39153933
pr-url: https://github.com/nodejs/node/pull/59461
39163934
description: Add support for ML-KEM key pairs.
@@ -4036,6 +4054,9 @@ a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
40364054
<!-- YAML
40374055
added: v10.12.0
40384056
changes:
4057+
- version: REPLACEME
4058+
pr-url: https://github.com/nodejs/node/pull/59537
4059+
description: Add support for SLH-DSA key pairs.
40394060
- version: v24.7.0
40404061
pr-url: https://github.com/nodejs/node/pull/59461
40414062
description: Add support for ML-KEM key pairs.
@@ -5691,6 +5712,9 @@ Throws an error if FIPS mode is not available.
56915712
<!-- YAML
56925713
added: v12.0.0
56935714
changes:
5715+
- version: REPLACEME
5716+
pr-url: https://github.com/nodejs/node/pull/59537
5717+
description: Add support for SLH-DSA signing.
56945718
- version: v24.6.0
56955719
pr-url: https://github.com/nodejs/node/pull/59259
56965720
description: Add support for ML-DSA signing.
@@ -5807,6 +5831,9 @@ not introduce timing vulnerabilities.
58075831
<!-- YAML
58085832
added: v12.0.0
58095833
changes:
5834+
- version: REPLACEME
5835+
pr-url: https://github.com/nodejs/node/pull/59537
5836+
description: Add support for SLH-DSA signature verification.
58105837
- version: v24.6.0
58115838
pr-url: https://github.com/nodejs/node/pull/59259
58125839
description: Add support for ML-DSA signature verification.

lib/internal/crypto/keygen.js

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ const {
2525
EVP_PKEY_ML_KEM_1024,
2626
EVP_PKEY_ML_KEM_512,
2727
EVP_PKEY_ML_KEM_768,
28+
EVP_PKEY_SLH_DSA_SHA2_128F,
29+
EVP_PKEY_SLH_DSA_SHA2_128S,
30+
EVP_PKEY_SLH_DSA_SHA2_192F,
31+
EVP_PKEY_SLH_DSA_SHA2_192S,
32+
EVP_PKEY_SLH_DSA_SHA2_256F,
33+
EVP_PKEY_SLH_DSA_SHA2_256S,
34+
EVP_PKEY_SLH_DSA_SHAKE_128F,
35+
EVP_PKEY_SLH_DSA_SHAKE_128S,
36+
EVP_PKEY_SLH_DSA_SHAKE_192F,
37+
EVP_PKEY_SLH_DSA_SHAKE_192S,
38+
EVP_PKEY_SLH_DSA_SHAKE_256F,
39+
EVP_PKEY_SLH_DSA_SHAKE_256S,
2840
EVP_PKEY_X25519,
2941
EVP_PKEY_X448,
3042
OPENSSL_EC_NAMED_CURVE,
@@ -168,7 +180,7 @@ function parseKeyEncoding(keyType, options = kEmptyObject) {
168180
];
169181
}
170182

171-
const ids = {
183+
const nidOnlyKeyPairs = {
172184
'ed25519': EVP_PKEY_ED25519,
173185
'ed448': EVP_PKEY_ED448,
174186
'x25519': EVP_PKEY_X25519,
@@ -179,6 +191,18 @@ const ids = {
179191
'ml-kem-512': EVP_PKEY_ML_KEM_512,
180192
'ml-kem-768': EVP_PKEY_ML_KEM_768,
181193
'ml-kem-1024': EVP_PKEY_ML_KEM_1024,
194+
'slh-dsa-sha2-128f': EVP_PKEY_SLH_DSA_SHA2_128F,
195+
'slh-dsa-sha2-128s': EVP_PKEY_SLH_DSA_SHA2_128S,
196+
'slh-dsa-sha2-192f': EVP_PKEY_SLH_DSA_SHA2_192F,
197+
'slh-dsa-sha2-192s': EVP_PKEY_SLH_DSA_SHA2_192S,
198+
'slh-dsa-sha2-256f': EVP_PKEY_SLH_DSA_SHA2_256F,
199+
'slh-dsa-sha2-256s': EVP_PKEY_SLH_DSA_SHA2_256S,
200+
'slh-dsa-shake-128f': EVP_PKEY_SLH_DSA_SHAKE_128F,
201+
'slh-dsa-shake-128s': EVP_PKEY_SLH_DSA_SHAKE_128S,
202+
'slh-dsa-shake-192f': EVP_PKEY_SLH_DSA_SHAKE_192F,
203+
'slh-dsa-shake-192s': EVP_PKEY_SLH_DSA_SHAKE_192S,
204+
'slh-dsa-shake-256f': EVP_PKEY_SLH_DSA_SHAKE_256F,
205+
'slh-dsa-shake-256s': EVP_PKEY_SLH_DSA_SHAKE_256S,
182206
};
183207

184208
function createJob(mode, type, options) {
@@ -293,22 +317,6 @@ function createJob(mode, type, options) {
293317
paramEncoding,
294318
...encoding);
295319
}
296-
case 'ed25519':
297-
case 'ed448':
298-
case 'x25519':
299-
case 'x448':
300-
case 'ml-dsa-44':
301-
case 'ml-dsa-65':
302-
case 'ml-dsa-87':
303-
case 'ml-kem-512':
304-
case 'ml-kem-768':
305-
case 'ml-kem-1024':
306-
{
307-
if (ids[type] === undefined) {
308-
throw new ERR_INVALID_ARG_VALUE('type', type, 'must be a supported key type');
309-
}
310-
return new NidKeyPairGenJob(mode, ids[type], ...encoding);
311-
}
312320
case 'dh':
313321
{
314322
validateObject(options, 'options');
@@ -347,10 +355,13 @@ function createJob(mode, type, options) {
347355
generator == null ? 2 : generator,
348356
...encoding);
349357
}
350-
default:
351-
// Fall through
358+
default: {
359+
if (nidOnlyKeyPairs[type] === undefined) {
360+
throw new ERR_INVALID_ARG_VALUE('type', type, 'must be a supported key type');
361+
}
362+
return new NidKeyPairGenJob(mode, nidOnlyKeyPairs[type], ...encoding);
363+
}
352364
}
353-
throw new ERR_INVALID_ARG_VALUE('type', type, 'must be a supported key type');
354365
}
355366

356367
// Symmetric Key Generation

src/crypto/crypto_keys.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,30 @@ Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
997997
return env()->crypto_ml_kem_768_string();
998998
case EVP_PKEY_ML_KEM_1024:
999999
return env()->crypto_ml_kem_1024_string();
1000+
case EVP_PKEY_SLH_DSA_SHA2_128F:
1001+
return env()->crypto_slh_dsa_sha2_128f_string();
1002+
case EVP_PKEY_SLH_DSA_SHA2_128S:
1003+
return env()->crypto_slh_dsa_sha2_128s_string();
1004+
case EVP_PKEY_SLH_DSA_SHA2_192F:
1005+
return env()->crypto_slh_dsa_sha2_192f_string();
1006+
case EVP_PKEY_SLH_DSA_SHA2_192S:
1007+
return env()->crypto_slh_dsa_sha2_192s_string();
1008+
case EVP_PKEY_SLH_DSA_SHA2_256F:
1009+
return env()->crypto_slh_dsa_sha2_256f_string();
1010+
case EVP_PKEY_SLH_DSA_SHA2_256S:
1011+
return env()->crypto_slh_dsa_sha2_256s_string();
1012+
case EVP_PKEY_SLH_DSA_SHAKE_128F:
1013+
return env()->crypto_slh_dsa_shake_128f_string();
1014+
case EVP_PKEY_SLH_DSA_SHAKE_128S:
1015+
return env()->crypto_slh_dsa_shake_128s_string();
1016+
case EVP_PKEY_SLH_DSA_SHAKE_192F:
1017+
return env()->crypto_slh_dsa_shake_192f_string();
1018+
case EVP_PKEY_SLH_DSA_SHAKE_192S:
1019+
return env()->crypto_slh_dsa_shake_192s_string();
1020+
case EVP_PKEY_SLH_DSA_SHAKE_256F:
1021+
return env()->crypto_slh_dsa_shake_256f_string();
1022+
case EVP_PKEY_SLH_DSA_SHAKE_256S:
1023+
return env()->crypto_slh_dsa_shake_256s_string();
10001024
#endif
10011025
default:
10021026
return Undefined(env()->isolate());
@@ -1324,6 +1348,18 @@ void Initialize(Environment* env, Local<Object> target) {
13241348
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_512);
13251349
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_768);
13261350
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_1024);
1351+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_128F);
1352+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_128S);
1353+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_192F);
1354+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_192S);
1355+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_256F);
1356+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHA2_256S);
1357+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_128F);
1358+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_128S);
1359+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_192F);
1360+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_192S);
1361+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_256F);
1362+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_SLH_DSA_SHAKE_256S);
13271363
#endif
13281364
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
13291365
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);

src/env_properties.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@
121121
V(crypto_ml_kem_512_string, "ml-kem-512") \
122122
V(crypto_ml_kem_768_string, "ml-kem-768") \
123123
V(crypto_ml_kem_1024_string, "ml-kem-1024") \
124+
V(crypto_slh_dsa_sha2_128f_string, "slh-dsa-sha2-128f") \
125+
V(crypto_slh_dsa_sha2_128s_string, "slh-dsa-sha2-128s") \
126+
V(crypto_slh_dsa_sha2_192f_string, "slh-dsa-sha2-192f") \
127+
V(crypto_slh_dsa_sha2_192s_string, "slh-dsa-sha2-192s") \
128+
V(crypto_slh_dsa_sha2_256f_string, "slh-dsa-sha2-256f") \
129+
V(crypto_slh_dsa_sha2_256s_string, "slh-dsa-sha2-256s") \
130+
V(crypto_slh_dsa_shake_128f_string, "slh-dsa-shake-128f") \
131+
V(crypto_slh_dsa_shake_128s_string, "slh-dsa-shake-128s") \
132+
V(crypto_slh_dsa_shake_192f_string, "slh-dsa-shake-192f") \
133+
V(crypto_slh_dsa_shake_192s_string, "slh-dsa-shake-192s") \
134+
V(crypto_slh_dsa_shake_256f_string, "slh-dsa-shake-256f") \
135+
V(crypto_slh_dsa_shake_256s_string, "slh-dsa-shake-256s") \
124136
V(crypto_x25519_string, "x25519") \
125137
V(crypto_x448_string, "x448") \
126138
V(crypto_rsa_string, "rsa") \

0 commit comments

Comments
 (0)