Skip to content

Commit e755754

Browse files
panvaanonrig
authored andcommitted
crypto: support ML-KEM KeyObject
PR-URL: nodejs/node#59461 Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ethan Arrowood <[email protected]>
1 parent a83bd0f commit e755754

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

include/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

src/ncrypto.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@
1919
#include <cstring>
2020
#if OPENSSL_VERSION_MAJOR >= 3
2121
#include <openssl/provider.h>
22+
#endif
23+
#if OPENSSL_WITH_PQC
24+
struct PQCMapping {
25+
const char* name;
26+
int nid;
27+
};
28+
29+
constexpr static PQCMapping pqc_mappings[] = {
30+
{"ML-DSA-44", EVP_PKEY_ML_DSA_44},
31+
{"ML-DSA-65", EVP_PKEY_ML_DSA_65},
32+
{"ML-DSA-87", EVP_PKEY_ML_DSA_87},
33+
{"ML-KEM-512", EVP_PKEY_ML_KEM_512},
34+
{"ML-KEM-768", EVP_PKEY_ML_KEM_768},
35+
{"ML-KEM-1024", EVP_PKEY_ML_KEM_1024},
36+
};
37+
2238
#endif
2339

2440
// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e.
@@ -2119,11 +2135,21 @@ int EVPKeyPointer::id(const EVP_PKEY* key) {
21192135
if (key == nullptr) return 0;
21202136
int type = EVP_PKEY_id(key);
21212137
#if OPENSSL_WITH_PQC
2138+
// EVP_PKEY_id returns -1 when EVP_PKEY_* is only implemented in a provider
2139+
// which is the case for all post-quantum NIST algorithms
2140+
// one suggested way would be to use a chain of `EVP_PKEY_is_a`
21222141
// https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
2142+
// or, this way there are less calls to the OpenSSL provider, just
2143+
// getting the name once
21232144
if (type == -1) {
2124-
if (EVP_PKEY_is_a(key, "ML-DSA-44")) return EVP_PKEY_ML_DSA_44;
2125-
if (EVP_PKEY_is_a(key, "ML-DSA-65")) return EVP_PKEY_ML_DSA_65;
2126-
if (EVP_PKEY_is_a(key, "ML-DSA-87")) return EVP_PKEY_ML_DSA_87;
2145+
const char* type_name = EVP_PKEY_get0_type_name(key);
2146+
if (type_name == nullptr) return -1;
2147+
2148+
for (const auto& mapping : pqc_mappings) {
2149+
if (strcmp(type_name, mapping.name) == 0) {
2150+
return mapping.nid;
2151+
}
2152+
}
21272153
}
21282154
#endif
21292155
return type;

0 commit comments

Comments
 (0)