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
3 changes: 0 additions & 3 deletions benchmark/crypto/kem.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ const bench = common.createBenchmark(main, {
// assess whether mutexes over the key material impact the operation
if (p.keyFormat === 'keyObject.unique')
return p.mode === 'async-parallel';
// JWK is not supported for ml-kem for now
if (p.keyFormat === 'jwk')
return !p.keyType.startsWith('ml-');
// raw-public is only supported for encapsulate, not rsa
if (p.keyFormat === 'raw-public')
return p.keyType !== 'rsa' && p.op === 'encapsulate';
Expand Down
42 changes: 27 additions & 15 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,23 @@ The following table lists the asymmetric key types recognized by the
| `'ml-dsa-44'`[^openssl35] | ML-DSA-44 | 2.16.840.1.101.3.4.3.17 | ✔ | ✔ | ✔ | ✔ | | ✔ |
| `'ml-dsa-65'`[^openssl35] | ML-DSA-65 | 2.16.840.1.101.3.4.3.18 | ✔ | ✔ | ✔ | ✔ | | ✔ |
| `'ml-dsa-87'`[^openssl35] | ML-DSA-87 | 2.16.840.1.101.3.4.3.19 | ✔ | ✔ | ✔ | ✔ | | ✔ |
| `'ml-kem-512'`[^openssl35] | ML-KEM-512 | 2.16.840.1.101.3.4.4.1 | ✔ | ✔ | | ✔ | | ✔ |
| `'ml-kem-768'`[^openssl35] | ML-KEM-768 | 2.16.840.1.101.3.4.4.2 | ✔ | ✔ | | ✔ | | ✔ |
| `'ml-kem-1024'`[^openssl35] | ML-KEM-1024 | 2.16.840.1.101.3.4.4.3 | ✔ | ✔ | | ✔ | | ✔ |
| `'ml-kem-512'`[^openssl35] | ML-KEM-512 | 2.16.840.1.101.3.4.4.1 | ✔ | ✔ | | ✔ | | ✔ |
| `'ml-kem-768'`[^openssl35] | ML-KEM-768 | 2.16.840.1.101.3.4.4.2 | ✔ | ✔ | | ✔ | | ✔ |
| `'ml-kem-1024'`[^openssl35] | ML-KEM-1024 | 2.16.840.1.101.3.4.4.3 | ✔ | ✔ | | ✔ | | ✔ |
| `'rsa-pss'` | RSA PSS | 1.2.840.113549.1.1.10 | ✔ | ✔ | | | | |
| `'rsa'` | RSA | 1.2.840.113549.1.1.1 | ✔ | ✔ | ✔ | | | |
| `'slh-dsa-sha2-128f'`[^openssl35] | SLH-DSA-SHA2-128f | 2.16.840.1.101.3.4.3.21 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-128s'`[^openssl35] | SLH-DSA-SHA2-128s | 2.16.840.1.101.3.4.3.20 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-192f'`[^openssl35] | SLH-DSA-SHA2-192f | 2.16.840.1.101.3.4.3.23 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-192s'`[^openssl35] | SLH-DSA-SHA2-192s | 2.16.840.1.101.3.4.3.22 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-256f'`[^openssl35] | SLH-DSA-SHA2-256f | 2.16.840.1.101.3.4.3.25 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-256s'`[^openssl35] | SLH-DSA-SHA2-256s | 2.16.840.1.101.3.4.3.24 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-128f'`[^openssl35] | SLH-DSA-SHAKE-128f | 2.16.840.1.101.3.4.3.27 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-128s'`[^openssl35] | SLH-DSA-SHAKE-128s | 2.16.840.1.101.3.4.3.26 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-192f'`[^openssl35] | SLH-DSA-SHAKE-192f | 2.16.840.1.101.3.4.3.29 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-192s'`[^openssl35] | SLH-DSA-SHAKE-192s | 2.16.840.1.101.3.4.3.28 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-256f'`[^openssl35] | SLH-DSA-SHAKE-256f | 2.16.840.1.101.3.4.3.31 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-256s'`[^openssl35] | SLH-DSA-SHAKE-256s | 2.16.840.1.101.3.4.3.30 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-128f'`[^openssl35] | SLH-DSA-SHA2-128f | 2.16.840.1.101.3.4.3.21 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-128s'`[^openssl35] | SLH-DSA-SHA2-128s | 2.16.840.1.101.3.4.3.20 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-192f'`[^openssl35] | SLH-DSA-SHA2-192f | 2.16.840.1.101.3.4.3.23 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-192s'`[^openssl35] | SLH-DSA-SHA2-192s | 2.16.840.1.101.3.4.3.22 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-256f'`[^openssl35] | SLH-DSA-SHA2-256f | 2.16.840.1.101.3.4.3.25 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-sha2-256s'`[^openssl35] | SLH-DSA-SHA2-256s | 2.16.840.1.101.3.4.3.24 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-128f'`[^openssl35] | SLH-DSA-SHAKE-128f | 2.16.840.1.101.3.4.3.27 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-128s'`[^openssl35] | SLH-DSA-SHAKE-128s | 2.16.840.1.101.3.4.3.26 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-192f'`[^openssl35] | SLH-DSA-SHAKE-192f | 2.16.840.1.101.3.4.3.29 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-192s'`[^openssl35] | SLH-DSA-SHAKE-192s | 2.16.840.1.101.3.4.3.28 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-256f'`[^openssl35] | SLH-DSA-SHAKE-256f | 2.16.840.1.101.3.4.3.31 | ✔ | ✔ | | ✔ | ✔ | |
| `'slh-dsa-shake-256s'`[^openssl35] | SLH-DSA-SHAKE-256s | 2.16.840.1.101.3.4.3.30 | ✔ | ✔ | | ✔ | ✔ | |
| `'x25519'` | X25519 | 1.3.101.110 | ✔ | ✔ | ✔ | ✔ | ✔ | |
| `'x448'` | X448 | 1.3.101.111 | ✔ | ✔ | ✔ | ✔ | ✔ | |

Expand Down Expand Up @@ -2397,6 +2397,10 @@ type, value, and parameters. This method is not
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62706
description: Added JWK format support for ML-KEM and SLH-DSA
key types.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62240
description: Added support for `'raw-public'`, `'raw-private'`,
Expand Down Expand Up @@ -3926,6 +3930,10 @@ input.on('readable', () => {
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62706
description: Added JWK format support for ML-KEM and SLH-DSA
key types.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
Expand Down Expand Up @@ -3977,6 +3985,10 @@ of the passphrase is limited to 1024 bytes.
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62706
description: Added JWK format support for ML-KEM and SLH-DSA
key types.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62453
description: Passing a CryptoKey as `key` is deprecated.
Expand Down
18 changes: 12 additions & 6 deletions doc/api/webcrypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,9 @@ The algorithms currently supported include:
<!-- YAML
added: v15.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62706
description: Added JWK format support for ML-KEM key types.
- version: v24.8.0
pr-url: https://github.com/nodejs/node/pull/59647
description: KMAC algorithms are now supported.
Expand Down Expand Up @@ -1190,9 +1193,9 @@ specification.
| `'ML-DSA-44'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-DSA-65'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-DSA-87'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'RSA-OAEP'` | ✔ | ✔ | ✔ | | | | |
| `'RSA-PSS'` | ✔ | ✔ | ✔ | | | | |
| `'RSASSA-PKCS1-v1_5'` | ✔ | ✔ | ✔ | | | | |
Expand Down Expand Up @@ -1280,6 +1283,9 @@ The {CryptoKey} (secret key) generating algorithms supported include:
<!-- YAML
added: v15.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62706
description: Added JWK format support for ML-KEM key types.
- version: v25.9.0
pr-url: https://github.com/nodejs/node/pull/62218
description: Importing ML-DSA and ML-KEM PKCS#8 keys
Expand Down Expand Up @@ -1353,9 +1359,9 @@ The algorithms currently supported include:
| `'ML-DSA-44'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-DSA-65'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-DSA-87'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ |
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-512'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-768'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'ML-KEM-1024'`[^modern-algos] | ✔ | ✔ | | | | ✔ | ✔ |
| `'PBKDF2'` | | | | ✔ | ✔ | | |
| `'RSA-OAEP'` | ✔ | ✔ | ✔ | | | | |
| `'RSA-PSS'` | ✔ | ✔ | ✔ | | | | |
Expand Down
14 changes: 14 additions & 0 deletions lib/internal/crypto/ml_kem.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ const {

const {
importDerKey,
importJwkKey,
importRawKey,
validateJwk,
} = require('internal/crypto/webcrypto_util');

const generateKeyPair = promisify(_generateKeyPair);
Expand Down Expand Up @@ -177,6 +179,18 @@ function mlKemImportKey(
keyObject = importRawKey(isPublic, keyData, isPublic ? kKeyFormatRawPublic : kKeyFormatRawPrivate, name);
break;
}
case 'jwk': {
validateJwk(keyData, 'AKP', extractable, usagesSet, 'enc');

if (keyData.alg !== name)
throw lazyDOMException(
'JWK "alg" Parameter and algorithm name mismatch', 'DataError');

const isPublic = keyData.priv === undefined;
verifyAcceptableMlKemKeyUse(name, isPublic, usagesSet);
keyObject = importJwkKey(isPublic, keyData);
break;
}
default:
return undefined;
}
Expand Down
6 changes: 6 additions & 0 deletions lib/internal/crypto/webcrypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ async function exportKeyJWK(key) {
case 'ML-DSA-65':
// Fall through
case 'ML-DSA-87':
// Fall through
case 'ML-KEM-512':
// Fall through
case 'ML-KEM-768':
// Fall through
case 'ML-KEM-1024':
break;
case 'Ed25519':
// Fall through
Expand Down
4 changes: 2 additions & 2 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@
'src/crypto/crypto_cipher.cc',
'src/crypto/crypto_context.cc',
'src/crypto/crypto_ec.cc',
'src/crypto/crypto_ml_dsa.cc',
'src/crypto/crypto_pqc.cc',
'src/crypto/crypto_kem.cc',
'src/crypto/crypto_hmac.cc',
'src/crypto/crypto_kmac.cc',
Expand Down Expand Up @@ -426,7 +426,7 @@
'src/crypto/crypto_clienthello.h',
'src/crypto/crypto_context.h',
'src/crypto/crypto_ec.h',
'src/crypto/crypto_ml_dsa.h',
'src/crypto/crypto_pqc.h',
'src/crypto/crypto_hkdf.h',
'src/crypto/crypto_pbkdf2.h',
'src/crypto/crypto_sig.h',
Expand Down
36 changes: 33 additions & 3 deletions src/crypto/crypto_keys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "crypto/crypto_dh.h"
#include "crypto/crypto_dsa.h"
#include "crypto/crypto_ec.h"
#include "crypto/crypto_ml_dsa.h"
#include "crypto/crypto_pqc.h"
#include "crypto/crypto_rsa.h"
#include "crypto/crypto_util.h"
#include "env-inl.h"
Expand Down Expand Up @@ -200,7 +200,37 @@ bool ExportJWKAsymmetricKey(Environment* env,
case EVP_PKEY_ML_DSA_65:
// Fall through
case EVP_PKEY_ML_DSA_87:
return ExportJwkMlDsaKey(env, key, target);
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_128F:
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_128S:
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_192F:
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_192S:
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_256F:
// Fall through
case EVP_PKEY_SLH_DSA_SHA2_256S:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_128F:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_128S:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_192F:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_192S:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_256F:
// Fall through
case EVP_PKEY_SLH_DSA_SHAKE_256S:
// Fall through
case EVP_PKEY_ML_KEM_512:
// Fall through
case EVP_PKEY_ML_KEM_768:
// Fall through
case EVP_PKEY_ML_KEM_1024:
return ExportJwkPqcKey(env, key, target);
#endif
}
THROW_ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(env);
Expand Down Expand Up @@ -723,7 +753,7 @@ static KeyObjectData ImportJWKFromArgs(Environment* env, Local<Object> jwk) {
return ImportJWKEdKey(env, jwk);
} else if (*kty_string == std::string_view("AKP")) {
#if OPENSSL_WITH_PQC
return ImportJWKAkpKey(env, jwk);
return ImportJWKPqcKey(env, jwk);
#else
THROW_ERR_INVALID_ARG_VALUE(env, "Unsupported key type");
return {};
Expand Down
Loading
Loading