From 8ed0c72b29a38a1ba8e3e0185c39005b75156da9 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 21 Aug 2025 11:09:06 +0200 Subject: [PATCH] crypto: support ML-KEM in Web Cryptography --- deps/ncrypto/ncrypto.cc | 17 +- doc/api/webcrypto.md | 354 +++++++++++++--- lib/internal/crypto/keys.js | 10 +- lib/internal/crypto/ml_dsa.js | 11 +- lib/internal/crypto/ml_kem.js | 287 +++++++++++++ lib/internal/crypto/util.js | 30 ++ lib/internal/crypto/webcrypto.js | 386 +++++++++++++++++- lib/internal/crypto/webidl.js | 4 + src/crypto/crypto_keys.cc | 65 ++- src/crypto/crypto_keys.h | 9 +- test/fixtures/crypto/ml-kem.js | 49 +++ .../webcrypto/supports-modern-algorithms.mjs | 50 ++- .../test-webcrypto-encap-decap-ml-kem.js | 264 ++++++++++++ .../test-webcrypto-export-import-ml-dsa.js | 2 +- .../test-webcrypto-export-import-ml-kem.js | 315 ++++++++++++++ test/parallel/test-webcrypto-keygen.js | 45 ++ test/parallel/test-webcrypto-supports.mjs | 51 +++ tools/doc/type-parser.mjs | 2 + 18 files changed, 1851 insertions(+), 100 deletions(-) create mode 100644 lib/internal/crypto/ml_kem.js create mode 100644 test/fixtures/crypto/ml-kem.js create mode 100644 test/parallel/test-webcrypto-encap-decap-ml-kem.js create mode 100644 test/parallel/test-webcrypto-export-import-ml-kem.js diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 4b7a5bf5f28685..55395e31de09d1 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -2162,21 +2162,34 @@ DataPointer EVPKeyPointer::rawPublicKey() const { #if OPENSSL_WITH_PQC DataPointer EVPKeyPointer::rawSeed() const { if (!pkey_) return {}; + + // Determine seed length and parameter name based on key type + size_t seed_len; + const char* param_name; + switch (id()) { case EVP_PKEY_ML_DSA_44: case EVP_PKEY_ML_DSA_65: case EVP_PKEY_ML_DSA_87: + seed_len = 32; // ML-DSA uses 32-byte seeds + param_name = OSSL_PKEY_PARAM_ML_DSA_SEED; + break; + case EVP_PKEY_ML_KEM_512: + case EVP_PKEY_ML_KEM_768: + case EVP_PKEY_ML_KEM_1024: + seed_len = 64; // ML-KEM uses 64-byte seeds + param_name = OSSL_PKEY_PARAM_ML_KEM_SEED; break; default: unreachable(); } - size_t seed_len = 32; if (auto data = DataPointer::Alloc(seed_len)) { const Buffer buf = data; size_t len = data.size(); + if (EVP_PKEY_get_octet_string_param( - get(), OSSL_PKEY_PARAM_ML_DSA_SEED, buf.data, len, &seed_len) != 1) + get(), param_name, buf.data, len, &seed_len) != 1) return {}; return data; } diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 4eade7ec621962..565d7eb8198f6a 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2,6 +2,9 @@ + +> Stability: 1.1 - Active development + +* `decapsulationAlgorithm` {string|Algorithm} +* `decapsulationKey` {CryptoKey} +* `ciphertext` {ArrayBuffer|TypedArray|DataView|Buffer} +* Returns: {Promise} Fulfills with {ArrayBuffer} upon success. + +The algorithms currently supported include: + +* `'ML-KEM-512'`[^modern-algos] +* `'ML-KEM-768'`[^modern-algos] +* `'ML-KEM-1024'`[^modern-algos] + +### `subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)` + + + +> Stability: 1.1 - Active development + +* `decapsulationAlgorithm` {string|Algorithm} +* `decapsulationKey` {CryptoKey} +* `ciphertext` {ArrayBuffer|TypedArray|DataView|Buffer} +* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams} +* `extractable` {boolean} +* `usages` {string\[]} See [Key usages][]. +* Returns: {Promise} Fulfills with {CryptoKey} upon success. + +The algorithms currently supported include: + +* `'ML-KEM-512'`[^modern-algos] +* `'ML-KEM-768'`[^modern-algos] +* `'ML-KEM-1024'`[^modern-algos] + ### `subtle.decrypt(algorithm, key, data)` + +> Stability: 1.1 - Active development + +* `encapsulationAlgorithm` {string|Algorithm} +* `encapsulationKey` {CryptoKey} +* Returns: {Promise} Fulfills with {EncapsulatedBits} upon success. + +The algorithms currently supported include: + +* `'ML-KEM-512'`[^modern-algos] +* `'ML-KEM-768'`[^modern-algos] +* `'ML-KEM-1024'`[^modern-algos] + +### `subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages)` + + + +> Stability: 1.1 - Active development + +* `encapsulationAlgorithm` {string|Algorithm} +* `encapsulationKey` {CryptoKey} +* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams} +* `extractable` {boolean} +* `usages` {string\[]} See [Key usages][]. +* Returns: {Promise} Fulfills with {EncapsulatedKey} upon success. + +The algorithms currently supported include: + +* `'ML-KEM-512'`[^modern-algos] +* `'ML-KEM-768'`[^modern-algos] +* `'ML-KEM-1024'`[^modern-algos] + ### `subtle.encrypt(algorithm, key, data)` + +#### `encapsulatedBits.ciphertext` + + + +* Type: {ArrayBuffer} + +#### `encapsulatedBits.sharedKey` + + + +* Type: {ArrayBuffer} + +### Class: `EncapsulatedKey` + + + +#### `encapsulatedKey.ciphertext` + + + +* Type: {ArrayBuffer} + +#### `encapsulatedKey.sharedKey` + + + +* Type: {CryptoKey} + ### Class: `HkdfParams`