Skip to content

Commit 61c3bcd

Browse files
panvatargos
authored andcommitted
crypto: support ML-KEM KeyObject
PR-URL: #59461 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
1 parent 3780911 commit 61c3bcd

21 files changed

+665
-3
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111
#include <cstring>
1212
#if OPENSSL_VERSION_MAJOR >= 3
1313
#include <openssl/provider.h>
14+
#endif
15+
#if OPENSSL_WITH_PQC
16+
struct PQCMapping {
17+
const char* name;
18+
int nid;
19+
};
20+
21+
constexpr static PQCMapping pqc_mappings[] = {
22+
{"ML-DSA-44", EVP_PKEY_ML_DSA_44},
23+
{"ML-DSA-65", EVP_PKEY_ML_DSA_65},
24+
{"ML-DSA-87", EVP_PKEY_ML_DSA_87},
25+
{"ML-KEM-512", EVP_PKEY_ML_KEM_512},
26+
{"ML-KEM-768", EVP_PKEY_ML_KEM_768},
27+
{"ML-KEM-1024", EVP_PKEY_ML_KEM_1024},
28+
};
29+
1430
#endif
1531

1632
// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e.
@@ -1969,11 +1985,21 @@ int EVPKeyPointer::id(const EVP_PKEY* key) {
19691985
if (key == nullptr) return 0;
19701986
int type = EVP_PKEY_id(key);
19711987
#if OPENSSL_WITH_PQC
1988+
// EVP_PKEY_id returns -1 when EVP_PKEY_* is only implemented in a provider
1989+
// which is the case for all post-quantum NIST algorithms
1990+
// one suggested way would be to use a chain of `EVP_PKEY_is_a`
19721991
// https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
1992+
// or, this way there are less calls to the OpenSSL provider, just
1993+
// getting the name once
19731994
if (type == -1) {
1974-
if (EVP_PKEY_is_a(key, "ML-DSA-44")) return EVP_PKEY_ML_DSA_44;
1975-
if (EVP_PKEY_is_a(key, "ML-DSA-65")) return EVP_PKEY_ML_DSA_65;
1976-
if (EVP_PKEY_is_a(key, "ML-DSA-87")) return EVP_PKEY_ML_DSA_87;
1995+
const char* type_name = EVP_PKEY_get0_type_name(key);
1996+
if (type_name == nullptr) return -1;
1997+
1998+
for (const auto& mapping : pqc_mappings) {
1999+
if (strcmp(type_name, mapping.name) == 0) {
2000+
return mapping.nid;
2001+
}
2002+
}
19772003
}
19782004
#endif
19792005
return type;

deps/ncrypto/ncrypto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
// Define OPENSSL_WITH_PQC for post-quantum cryptography support
3232
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
3333
#define OPENSSL_WITH_PQC 1
34+
#define EVP_PKEY_ML_KEM_512 NID_ML_KEM_512
35+
#define EVP_PKEY_ML_KEM_768 NID_ML_KEM_768
36+
#define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024
3437
#include <openssl/core_names.h>
3538
#endif
3639

doc/api/crypto.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,9 @@ Other key details might be exposed via this API using additional attributes.
20242024
<!-- YAML
20252025
added: v11.6.0
20262026
changes:
2027+
- version: REPLACEME
2028+
pr-url: https://github.com/nodejs/node/pull/59461
2029+
description: Add support for ML-KEM keys.
20272030
- version: v24.6.0
20282031
pr-url: https://github.com/nodejs/node/pull/59259
20292032
description: Add support for ML-DSA keys.
@@ -2064,6 +2067,9 @@ types are:
20642067
* `'ml-dsa-44'`[^openssl35] (OID 2.16.840.1.101.3.4.3.17)
20652068
* `'ml-dsa-65'`[^openssl35] (OID 2.16.840.1.101.3.4.3.18)
20662069
* `'ml-dsa-87'`[^openssl35] (OID 2.16.840.1.101.3.4.3.19)
2070+
* `'ml-kem-512'`[^openssl35] (OID 2.16.840.1.101.3.4.4.1)
2071+
* `'ml-kem-768'`[^openssl35] (OID 2.16.840.1.101.3.4.4.2)
2072+
* `'ml-kem-1024'`[^openssl35] (OID 2.16.840.1.101.3.4.4.3)
20672073

20682074
This property is `undefined` for unrecognized `KeyObject` types and symmetric
20692075
keys.
@@ -3663,6 +3669,9 @@ underlying hash function. See [`crypto.createHmac()`][] for more information.
36633669
<!-- YAML
36643670
added: v10.12.0
36653671
changes:
3672+
- version: REPLACEME
3673+
pr-url: https://github.com/nodejs/node/pull/59461
3674+
description: Add support for ML-KEM key pairs.
36663675
- version: v24.6.0
36673676
pr-url: https://github.com/nodejs/node/pull/59259
36683677
description: Add support for ML-DSA key pairs.
@@ -3786,6 +3795,9 @@ a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
37863795
<!-- YAML
37873796
added: v10.12.0
37883797
changes:
3798+
- version: REPLACEME
3799+
pr-url: https://github.com/nodejs/node/pull/59461
3800+
description: Add support for ML-KEM key pairs.
37893801
- version: v24.6.0
37903802
pr-url: https://github.com/nodejs/node/pull/59259
37913803
description: Add support for ML-DSA key pairs.

lib/internal/crypto/keygen.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ const {
2222
EVP_PKEY_ML_DSA_44,
2323
EVP_PKEY_ML_DSA_65,
2424
EVP_PKEY_ML_DSA_87,
25+
EVP_PKEY_ML_KEM_1024,
26+
EVP_PKEY_ML_KEM_512,
27+
EVP_PKEY_ML_KEM_768,
2528
EVP_PKEY_X25519,
2629
EVP_PKEY_X448,
2730
OPENSSL_EC_NAMED_CURVE,
@@ -173,6 +176,9 @@ const ids = {
173176
'ml-dsa-44': EVP_PKEY_ML_DSA_44,
174177
'ml-dsa-65': EVP_PKEY_ML_DSA_65,
175178
'ml-dsa-87': EVP_PKEY_ML_DSA_87,
179+
'ml-kem-512': EVP_PKEY_ML_KEM_512,
180+
'ml-kem-768': EVP_PKEY_ML_KEM_768,
181+
'ml-kem-1024': EVP_PKEY_ML_KEM_1024,
176182
};
177183

178184
function createJob(mode, type, options) {
@@ -294,6 +300,9 @@ function createJob(mode, type, options) {
294300
case 'ml-dsa-44':
295301
case 'ml-dsa-65':
296302
case 'ml-dsa-87':
303+
case 'ml-kem-512':
304+
case 'ml-kem-768':
305+
case 'ml-kem-1024':
297306
{
298307
if (ids[type] === undefined) {
299308
throw new ERR_INVALID_ARG_VALUE('type', type, 'must be a supported key type');

src/crypto/crypto_keys.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,12 @@ Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
978978
return env()->crypto_ml_dsa_65_string();
979979
case EVP_PKEY_ML_DSA_87:
980980
return env()->crypto_ml_dsa_87_string();
981+
case EVP_PKEY_ML_KEM_512:
982+
return env()->crypto_ml_kem_512_string();
983+
case EVP_PKEY_ML_KEM_768:
984+
return env()->crypto_ml_kem_768_string();
985+
case EVP_PKEY_ML_KEM_1024:
986+
return env()->crypto_ml_kem_1024_string();
981987
#endif
982988
default:
983989
return Undefined(env()->isolate());
@@ -1258,6 +1264,9 @@ void Initialize(Environment* env, Local<Object> target) {
12581264
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_44);
12591265
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_65);
12601266
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_87);
1267+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_512);
1268+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_768);
1269+
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_1024);
12611270
#endif
12621271
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
12631272
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);

src/env_properties.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@
118118
V(crypto_ml_dsa_44_string, "ml-dsa-44") \
119119
V(crypto_ml_dsa_65_string, "ml-dsa-65") \
120120
V(crypto_ml_dsa_87_string, "ml-dsa-87") \
121+
V(crypto_ml_kem_512_string, "ml-kem-512") \
122+
V(crypto_ml_kem_768_string, "ml-kem-768") \
123+
V(crypto_ml_kem_1024_string, "ml-kem-1024") \
121124
V(crypto_x25519_string, "x25519") \
122125
V(crypto_x448_string, "x448") \
123126
V(crypto_rsa_string, "rsa") \

test/fixtures/keys/Makefile

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,18 @@ all: \
110110
ml_dsa_87_private_seed_only.pem \
111111
ml_dsa_87_private_priv_only.pem \
112112
ml_dsa_87_public.pem \
113+
ml_kem_512_private.pem \
114+
ml_kem_512_private_seed_only.pem \
115+
ml_kem_512_private_priv_only.pem \
116+
ml_kem_512_public.pem \
117+
ml_kem_768_private.pem \
118+
ml_kem_768_private_seed_only.pem \
119+
ml_kem_768_private_priv_only.pem \
120+
ml_kem_768_public.pem \
121+
ml_kem_1024_private.pem \
122+
ml_kem_1024_private_seed_only.pem \
123+
ml_kem_1024_private_priv_only.pem \
124+
ml_kem_1024_public.pem \
113125

114126
#
115127
# Create Certificate Authority: ca1
@@ -903,6 +915,42 @@ ml_dsa_87_private_priv_only.pem: ml_dsa_87_private.pem
903915
ml_dsa_87_public.pem: ml_dsa_87_private.pem
904916
openssl pkey -in ml_dsa_87_private.pem -pubout -out ml_dsa_87_public.pem
905917

918+
ml_kem_512_private.pem:
919+
openssl genpkey -algorithm ml-kem-512 -out ml_kem_512_private.pem
920+
921+
ml_kem_512_private_seed_only.pem: ml_kem_512_private.pem
922+
openssl pkey -in ml_kem_512_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_512_private_seed_only.pem
923+
924+
ml_kem_512_private_priv_only.pem: ml_kem_512_private.pem
925+
openssl pkey -in ml_kem_512_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_512_private_priv_only.pem
926+
927+
ml_kem_512_public.pem: ml_kem_512_private.pem
928+
openssl pkey -in ml_kem_512_private.pem -pubout -out ml_kem_512_public.pem
929+
930+
ml_kem_768_private.pem:
931+
openssl genpkey -algorithm ml-kem-768 -out ml_kem_768_private.pem
932+
933+
ml_kem_768_private_seed_only.pem: ml_kem_768_private.pem
934+
openssl pkey -in ml_kem_768_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_768_private_seed_only.pem
935+
936+
ml_kem_768_private_priv_only.pem: ml_kem_768_private.pem
937+
openssl pkey -in ml_kem_768_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_768_private_priv_only.pem
938+
939+
ml_kem_768_public.pem: ml_kem_768_private.pem
940+
openssl pkey -in ml_kem_768_private.pem -pubout -out ml_kem_768_public.pem
941+
942+
ml_kem_1024_private.pem:
943+
openssl genpkey -algorithm ml-kem-1024 -out ml_kem_1024_private.pem
944+
945+
ml_kem_1024_private_seed_only.pem: ml_kem_1024_private.pem
946+
openssl pkey -in ml_kem_1024_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_1024_private_seed_only.pem
947+
948+
ml_kem_1024_private_priv_only.pem: ml_kem_1024_private.pem
949+
openssl pkey -in ml_kem_1024_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_1024_private_priv_only.pem
950+
951+
ml_kem_1024_public.pem: ml_kem_1024_private.pem
952+
openssl pkey -in ml_kem_1024_private.pem -pubout -out ml_kem_1024_public.pem
953+
906954
x448_private.pem:
907955
openssl genpkey -algorithm x448 -out x448_private.pem
908956

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
70+
SAs=
71+
-----END PRIVATE KEY-----
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
68+
AJV/u5KhD/rnJLoLOu0eNGt4p3Oh6Mg5ttxICw==
69+
-----END PRIVATE KEY-----
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MFQCAQAwCwYJYIZIAWUDBAQDBEKAQF8HoLJVBnDJ87tXNTXHLMkZgWjm1khEiBjv
3+
n7XHI+TLwMIywwCVf7uSoQ/65yS6CzrtHjRreKdzoejIObbcSAs=
4+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)