Skip to content

Commit d76db54

Browse files
panvanpaun
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 3ae1181 commit d76db54

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
@@ -20,6 +20,22 @@
2020
#include <cstring>
2121
#if OPENSSL_VERSION_MAJOR >= 3
2222
#include <openssl/provider.h>
23+
#endif
24+
#if OPENSSL_WITH_PQC
25+
struct PQCMapping {
26+
const char* name;
27+
int nid;
28+
};
29+
30+
constexpr static PQCMapping pqc_mappings[] = {
31+
{"ML-DSA-44", EVP_PKEY_ML_DSA_44},
32+
{"ML-DSA-65", EVP_PKEY_ML_DSA_65},
33+
{"ML-DSA-87", EVP_PKEY_ML_DSA_87},
34+
{"ML-KEM-512", EVP_PKEY_ML_KEM_512},
35+
{"ML-KEM-768", EVP_PKEY_ML_KEM_768},
36+
{"ML-KEM-1024", EVP_PKEY_ML_KEM_1024},
37+
};
38+
2339
#endif
2440

2541
// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e.
@@ -2067,11 +2083,21 @@ int EVPKeyPointer::id(const EVP_PKEY* key) {
20672083
if (key == nullptr) return 0;
20682084
int type = EVP_PKEY_id(key);
20692085
#if OPENSSL_WITH_PQC
2086+
// EVP_PKEY_id returns -1 when EVP_PKEY_* is only implemented in a provider
2087+
// which is the case for all post-quantum NIST algorithms
2088+
// one suggested way would be to use a chain of `EVP_PKEY_is_a`
20702089
// https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
2090+
// or, this way there are less calls to the OpenSSL provider, just
2091+
// getting the name once
20712092
if (type == -1) {
2072-
if (EVP_PKEY_is_a(key, "ML-DSA-44")) return EVP_PKEY_ML_DSA_44;
2073-
if (EVP_PKEY_is_a(key, "ML-DSA-65")) return EVP_PKEY_ML_DSA_65;
2074-
if (EVP_PKEY_is_a(key, "ML-DSA-87")) return EVP_PKEY_ML_DSA_87;
2093+
const char* type_name = EVP_PKEY_get0_type_name(key);
2094+
if (type_name == nullptr) return -1;
2095+
2096+
for (const auto& mapping : pqc_mappings) {
2097+
if (strcmp(type_name, mapping.name) == 0) {
2098+
return mapping.nid;
2099+
}
2100+
}
20752101
}
20762102
#endif
20772103
return type;

0 commit comments

Comments
 (0)