Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 38befee

Browse filesBrowse files
panvaaduh95
authored andcommitted
crypto: add JWK support for ML-KEM and SLH-DSA key types
Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #62706 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 2004d8d commit 38befee
Copy full SHA for 38befee

39 files changed

+842-357Lines changed: 842 additions & 357 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎benchmark/crypto/kem.js‎

Copy file name to clipboardExpand all lines: benchmark/crypto/kem.js
-3Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ const bench = common.createBenchmark(main, {
5454
// assess whether mutexes over the key material impact the operation
5555
if (p.keyFormat === 'keyObject.unique')
5656
return p.mode === 'async-parallel';
57-
// JWK is not supported for ml-kem for now
58-
if (p.keyFormat === 'jwk')
59-
return !p.keyType.startsWith('ml-');
6057
// raw-public is only supported for encapsulate, not rsa
6158
if (p.keyFormat === 'raw-public')
6259
return p.keyType !== 'rsa' && p.op === 'encapsulate';
Collapse file

‎doc/api/crypto.md‎

Copy file name to clipboardExpand all lines: doc/api/crypto.md
+27-15Lines changed: 27 additions & 15 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,23 @@ The following table lists the asymmetric key types recognized by the
8888
| `'ml-dsa-44'`[^openssl35] | ML-DSA-44 | 2.16.840.1.101.3.4.3.17 ||||| ||
8989
| `'ml-dsa-65'`[^openssl35] | ML-DSA-65 | 2.16.840.1.101.3.4.3.18 ||||| ||
9090
| `'ml-dsa-87'`[^openssl35] | ML-DSA-87 | 2.16.840.1.101.3.4.3.19 ||||| ||
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-
| `'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+
| `'ml-kem-1024'`[^openssl35] | ML-KEM-1024 | 2.16.840.1.101.3.4.4.3 ||| || ||
9494
| `'rsa-pss'` | RSA PSS | 1.2.840.113549.1.1.10 ||| | | | |
9595
| `'rsa'` | RSA | 1.2.840.113549.1.1.1 |||| | | |
96-
| `'slh-dsa-sha2-128f'`[^openssl35] | SLH-DSA-SHA2-128f | 2.16.840.1.101.3.4.3.21 ||| ||| |
97-
| `'slh-dsa-sha2-128s'`[^openssl35] | SLH-DSA-SHA2-128s | 2.16.840.1.101.3.4.3.20 ||| ||| |
98-
| `'slh-dsa-sha2-192f'`[^openssl35] | SLH-DSA-SHA2-192f | 2.16.840.1.101.3.4.3.23 ||| ||| |
99-
| `'slh-dsa-sha2-192s'`[^openssl35] | SLH-DSA-SHA2-192s | 2.16.840.1.101.3.4.3.22 ||| ||| |
100-
| `'slh-dsa-sha2-256f'`[^openssl35] | SLH-DSA-SHA2-256f | 2.16.840.1.101.3.4.3.25 ||| ||| |
101-
| `'slh-dsa-sha2-256s'`[^openssl35] | SLH-DSA-SHA2-256s | 2.16.840.1.101.3.4.3.24 ||| ||| |
102-
| `'slh-dsa-shake-128f'`[^openssl35] | SLH-DSA-SHAKE-128f | 2.16.840.1.101.3.4.3.27 ||| ||| |
103-
| `'slh-dsa-shake-128s'`[^openssl35] | SLH-DSA-SHAKE-128s | 2.16.840.1.101.3.4.3.26 ||| ||| |
104-
| `'slh-dsa-shake-192f'`[^openssl35] | SLH-DSA-SHAKE-192f | 2.16.840.1.101.3.4.3.29 ||| ||| |
105-
| `'slh-dsa-shake-192s'`[^openssl35] | SLH-DSA-SHAKE-192s | 2.16.840.1.101.3.4.3.28 ||| ||| |
106-
| `'slh-dsa-shake-256f'`[^openssl35] | SLH-DSA-SHAKE-256f | 2.16.840.1.101.3.4.3.31 ||| ||| |
107-
| `'slh-dsa-shake-256s'`[^openssl35] | SLH-DSA-SHAKE-256s | 2.16.840.1.101.3.4.3.30 ||| ||| |
96+
| `'slh-dsa-sha2-128f'`[^openssl35] | SLH-DSA-SHA2-128f | 2.16.840.1.101.3.4.3.21 ||| ||| |
97+
| `'slh-dsa-sha2-128s'`[^openssl35] | SLH-DSA-SHA2-128s | 2.16.840.1.101.3.4.3.20 ||| ||| |
98+
| `'slh-dsa-sha2-192f'`[^openssl35] | SLH-DSA-SHA2-192f | 2.16.840.1.101.3.4.3.23 ||| ||| |
99+
| `'slh-dsa-sha2-192s'`[^openssl35] | SLH-DSA-SHA2-192s | 2.16.840.1.101.3.4.3.22 ||| ||| |
100+
| `'slh-dsa-sha2-256f'`[^openssl35] | SLH-DSA-SHA2-256f | 2.16.840.1.101.3.4.3.25 ||| ||| |
101+
| `'slh-dsa-sha2-256s'`[^openssl35] | SLH-DSA-SHA2-256s | 2.16.840.1.101.3.4.3.24 ||| ||| |
102+
| `'slh-dsa-shake-128f'`[^openssl35] | SLH-DSA-SHAKE-128f | 2.16.840.1.101.3.4.3.27 ||| ||| |
103+
| `'slh-dsa-shake-128s'`[^openssl35] | SLH-DSA-SHAKE-128s | 2.16.840.1.101.3.4.3.26 ||| ||| |
104+
| `'slh-dsa-shake-192f'`[^openssl35] | SLH-DSA-SHAKE-192f | 2.16.840.1.101.3.4.3.29 ||| ||| |
105+
| `'slh-dsa-shake-192s'`[^openssl35] | SLH-DSA-SHAKE-192s | 2.16.840.1.101.3.4.3.28 ||| ||| |
106+
| `'slh-dsa-shake-256f'`[^openssl35] | SLH-DSA-SHAKE-256f | 2.16.840.1.101.3.4.3.31 ||| ||| |
107+
| `'slh-dsa-shake-256s'`[^openssl35] | SLH-DSA-SHAKE-256s | 2.16.840.1.101.3.4.3.30 ||| ||| |
108108
| `'x25519'` | X25519 | 1.3.101.110 |||||| |
109109
| `'x448'` | X448 | 1.3.101.111 |||||| |
110110

@@ -2399,6 +2399,10 @@ type, value, and parameters. This method is not
23992399
<!-- YAML
24002400
added: v11.6.0
24012401
changes:
2402+
- version: REPLACEME
2403+
pr-url: https://github.com/nodejs/node/pull/62706
2404+
description: Added JWK format support for ML-KEM and SLH-DSA
2405+
key types.
24022406
- version: v26.0.0
24032407
pr-url: https://github.com/nodejs/node/pull/62240
24042408
description: Added support for `'raw-public'`, `'raw-private'`,
@@ -3928,6 +3932,10 @@ input.on('readable', () => {
39283932
<!-- YAML
39293933
added: v11.6.0
39303934
changes:
3935+
- version: REPLACEME
3936+
pr-url: https://github.com/nodejs/node/pull/62706
3937+
description: Added JWK format support for ML-KEM and SLH-DSA
3938+
key types.
39313939
- version: v26.0.0
39323940
pr-url: https://github.com/nodejs/node/pull/62453
39333941
description: Passing a CryptoKey as `key` is deprecated.
@@ -3979,6 +3987,10 @@ of the passphrase is limited to 1024 bytes.
39793987
<!-- YAML
39803988
added: v11.6.0
39813989
changes:
3990+
- version: REPLACEME
3991+
pr-url: https://github.com/nodejs/node/pull/62706
3992+
description: Added JWK format support for ML-KEM and SLH-DSA
3993+
key types.
39823994
- version: v26.0.0
39833995
pr-url: https://github.com/nodejs/node/pull/62453
39843996
description: Passing a CryptoKey as `key` is deprecated.
Collapse file

‎doc/api/webcrypto.md‎

Copy file name to clipboardExpand all lines: doc/api/webcrypto.md
+12-6Lines changed: 12 additions & 6 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,9 @@ The algorithms currently supported include:
11321132
<!-- YAML
11331133
added: v15.0.0
11341134
changes:
1135+
- version: REPLACEME
1136+
pr-url: https://github.com/nodejs/node/pull/62706
1137+
description: Added JWK format support for ML-KEM key types.
11351138
- version: v24.8.0
11361139
pr-url: https://github.com/nodejs/node/pull/59647
11371140
description: KMAC algorithms are now supported.
@@ -1190,9 +1193,9 @@ specification.
11901193
| `'ML-DSA-44'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
11911194
| `'ML-DSA-65'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
11921195
| `'ML-DSA-87'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
1193-
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1194-
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1195-
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1196+
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1197+
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1198+
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
11961199
| `'RSA-OAEP'` | ✔ | ✔ | ✔ | | | | |
11971200
| `'RSA-PSS'` | ✔ | ✔ | ✔ | | | | |
11981201
| `'RSASSA-PKCS1-v1_5'` | ✔ | ✔ | ✔ | | | | |
@@ -1280,6 +1283,9 @@ The {CryptoKey} (secret key) generating algorithms supported include:
12801283
<!-- YAML
12811284
added: v15.0.0
12821285
changes:
1286+
- version: REPLACEME
1287+
pr-url: https://github.com/nodejs/node/pull/62706
1288+
description: Added JWK format support for ML-KEM key types.
12831289
- version: v26.0.0
12841290
pr-url: https://github.com/nodejs/node/pull/62218
12851291
description: Importing ML-DSA and ML-KEM PKCS#8 keys
@@ -1353,9 +1359,9 @@ The algorithms currently supported include:
13531359
| `'ML-DSA-44'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
13541360
| `'ML-DSA-65'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
13551361
| `'ML-DSA-87'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
1356-
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1357-
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1358-
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1362+
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1363+
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
1364+
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
13591365
| `'PBKDF2'` | | | | ✔ | ✔ | | |
13601366
| `'RSA-OAEP'` | ✔ | ✔ | ✔ | | | | |
13611367
| `'RSA-PSS'` | ✔ | ✔ | ✔ | | | | |
Collapse file

‎lib/internal/crypto/ml_kem.js‎

Copy file name to clipboardExpand all lines: lib/internal/crypto/ml_kem.js
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ const {
4343

4444
const {
4545
importDerKey,
46+
importJwkKey,
4647
importRawKey,
48+
validateJwk,
4749
} = require('internal/crypto/webcrypto_util');
4850

4951
const generateKeyPair = promisify(_generateKeyPair);
@@ -177,6 +179,18 @@ function mlKemImportKey(
177179
keyObject = importRawKey(isPublic, keyData, isPublic ? kKeyFormatRawPublic : kKeyFormatRawPrivate, name);
178180
break;
179181
}
182+
case 'jwk': {
183+
validateJwk(keyData, 'AKP', extractable, usagesSet, 'enc');
184+
185+
if (keyData.alg !== name)
186+
throw lazyDOMException(
187+
'JWK "alg" Parameter and algorithm name mismatch', 'DataError');
188+
189+
const isPublic = keyData.priv === undefined;
190+
verifyAcceptableMlKemKeyUse(name, isPublic, usagesSet);
191+
keyObject = importJwkKey(isPublic, keyData);
192+
break;
193+
}
180194
default:
181195
return undefined;
182196
}
Collapse file

‎lib/internal/crypto/webcrypto.js‎

Copy file name to clipboardExpand all lines: lib/internal/crypto/webcrypto.js
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,12 @@ async function exportKeyJWK(key) {
603603
case 'ML-DSA-65':
604604
// Fall through
605605
case 'ML-DSA-87':
606+
// Fall through
607+
case 'ML-KEM-512':
608+
// Fall through
609+
case 'ML-KEM-768':
610+
// Fall through
611+
case 'ML-KEM-1024':
606612
break;
607613
case 'Ed25519':
608614
// Fall through
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@
394394
'src/crypto/crypto_cipher.cc',
395395
'src/crypto/crypto_context.cc',
396396
'src/crypto/crypto_ec.cc',
397-
'src/crypto/crypto_ml_dsa.cc',
397+
'src/crypto/crypto_pqc.cc',
398398
'src/crypto/crypto_kem.cc',
399399
'src/crypto/crypto_hmac.cc',
400400
'src/crypto/crypto_kmac.cc',
@@ -432,7 +432,7 @@
432432
'src/crypto/crypto_clienthello.h',
433433
'src/crypto/crypto_context.h',
434434
'src/crypto/crypto_ec.h',
435-
'src/crypto/crypto_ml_dsa.h',
435+
'src/crypto/crypto_pqc.h',
436436
'src/crypto/crypto_hkdf.h',
437437
'src/crypto/crypto_pbkdf2.h',
438438
'src/crypto/crypto_sig.h',
Collapse file

‎src/crypto/crypto_keys.cc‎

Copy file name to clipboardExpand all lines: src/crypto/crypto_keys.cc
+33-3Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "crypto/crypto_dh.h"
66
#include "crypto/crypto_dsa.h"
77
#include "crypto/crypto_ec.h"
8-
#include "crypto/crypto_ml_dsa.h"
8+
#include "crypto/crypto_pqc.h"
99
#include "crypto/crypto_rsa.h"
1010
#include "crypto/crypto_util.h"
1111
#include "env-inl.h"
@@ -200,7 +200,37 @@ bool ExportJWKAsymmetricKey(Environment* env,
200200
case EVP_PKEY_ML_DSA_65:
201201
// Fall through
202202
case EVP_PKEY_ML_DSA_87:
203-
return ExportJwkMlDsaKey(env, key, target);
203+
// Fall through
204+
case EVP_PKEY_SLH_DSA_SHA2_128F:
205+
// Fall through
206+
case EVP_PKEY_SLH_DSA_SHA2_128S:
207+
// Fall through
208+
case EVP_PKEY_SLH_DSA_SHA2_192F:
209+
// Fall through
210+
case EVP_PKEY_SLH_DSA_SHA2_192S:
211+
// Fall through
212+
case EVP_PKEY_SLH_DSA_SHA2_256F:
213+
// Fall through
214+
case EVP_PKEY_SLH_DSA_SHA2_256S:
215+
// Fall through
216+
case EVP_PKEY_SLH_DSA_SHAKE_128F:
217+
// Fall through
218+
case EVP_PKEY_SLH_DSA_SHAKE_128S:
219+
// Fall through
220+
case EVP_PKEY_SLH_DSA_SHAKE_192F:
221+
// Fall through
222+
case EVP_PKEY_SLH_DSA_SHAKE_192S:
223+
// Fall through
224+
case EVP_PKEY_SLH_DSA_SHAKE_256F:
225+
// Fall through
226+
case EVP_PKEY_SLH_DSA_SHAKE_256S:
227+
// Fall through
228+
case EVP_PKEY_ML_KEM_512:
229+
// Fall through
230+
case EVP_PKEY_ML_KEM_768:
231+
// Fall through
232+
case EVP_PKEY_ML_KEM_1024:
233+
return ExportJwkPqcKey(env, key, target);
204234
#endif
205235
}
206236
THROW_ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(env);
@@ -723,7 +753,7 @@ static KeyObjectData ImportJWKFromArgs(Environment* env, Local<Object> jwk) {
723753
return ImportJWKEdKey(env, jwk);
724754
} else if (*kty_string == std::string_view("AKP")) {
725755
#if OPENSSL_WITH_PQC
726-
return ImportJWKAkpKey(env, jwk);
756+
return ImportJWKPqcKey(env, jwk);
727757
#else
728758
THROW_ERR_INVALID_ARG_VALUE(env, "Unsupported key type");
729759
return {};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.