diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index d7a26edd4cfe49..c94f0725bd3d05 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -4413,6 +4413,96 @@ HMACCtxPointer HMACCtxPointer::New() { return HMACCtxPointer(HMAC_CTX_new()); } +#if OPENSSL_VERSION_MAJOR >= 3 +EVPMacPointer::EVPMacPointer(EVP_MAC* mac) : mac_(mac) {} + +EVPMacPointer::EVPMacPointer(EVPMacPointer&& other) noexcept + : mac_(std::move(other.mac_)) {} + +EVPMacPointer& EVPMacPointer::operator=(EVPMacPointer&& other) noexcept { + if (this == &other) return *this; + mac_ = std::move(other.mac_); + return *this; +} + +EVPMacPointer::~EVPMacPointer() { + mac_.reset(); +} + +void EVPMacPointer::reset(EVP_MAC* mac) { + mac_.reset(mac); +} + +EVP_MAC* EVPMacPointer::release() { + return mac_.release(); +} + +EVPMacPointer EVPMacPointer::Fetch(const char* algorithm) { + return EVPMacPointer(EVP_MAC_fetch(nullptr, algorithm, nullptr)); +} + +EVPMacCtxPointer::EVPMacCtxPointer(EVP_MAC_CTX* ctx) : ctx_(ctx) {} + +EVPMacCtxPointer::EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept + : ctx_(std::move(other.ctx_)) {} + +EVPMacCtxPointer& EVPMacCtxPointer::operator=( + EVPMacCtxPointer&& other) noexcept { + if (this == &other) return *this; + ctx_ = std::move(other.ctx_); + return *this; +} + +EVPMacCtxPointer::~EVPMacCtxPointer() { + ctx_.reset(); +} + +void EVPMacCtxPointer::reset(EVP_MAC_CTX* ctx) { + ctx_.reset(ctx); +} + +EVP_MAC_CTX* EVPMacCtxPointer::release() { + return ctx_.release(); +} + +bool EVPMacCtxPointer::init(const Buffer& key, + const OSSL_PARAM* params) { + if (!ctx_) return false; + return EVP_MAC_init(ctx_.get(), + static_cast(key.data), + key.len, + params) == 1; +} + +bool EVPMacCtxPointer::update(const Buffer& data) { + if (!ctx_) return false; + return EVP_MAC_update(ctx_.get(), + static_cast(data.data), + data.len) == 1; +} + +DataPointer EVPMacCtxPointer::final(size_t length) { + if (!ctx_) return {}; + auto buf = DataPointer::Alloc(length); + if (!buf) return {}; + + size_t result_len = length; + if (EVP_MAC_final(ctx_.get(), + static_cast(buf.get()), + &result_len, + length) != 1) { + return {}; + } + + return buf; +} + +EVPMacCtxPointer EVPMacCtxPointer::New(EVP_MAC* mac) { + if (!mac) return EVPMacCtxPointer(); + return EVPMacCtxPointer(EVP_MAC_CTX_new(mac)); +} +#endif // OPENSSL_VERSION_MAJOR >= 3 + DataPointer hashDigest(const Buffer& buf, const EVP_MD* md) { if (md == nullptr) return {}; diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 6c62aa28a50e5a..14f5c1170a81e5 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -229,6 +229,8 @@ class DataPointer; class DHPointer; class ECKeyPointer; class EVPKeyPointer; +class EVPMacCtxPointer; +class EVPMacPointer; class EVPMDCtxPointer; class SSLCtxPointer; class SSLPointer; @@ -1451,6 +1453,56 @@ class HMACCtxPointer final { DeleteFnPtr ctx_; }; +#if OPENSSL_VERSION_MAJOR >= 3 +class EVPMacPointer final { + public: + EVPMacPointer() = default; + explicit EVPMacPointer(EVP_MAC* mac); + EVPMacPointer(EVPMacPointer&& other) noexcept; + EVPMacPointer& operator=(EVPMacPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(EVPMacPointer) + ~EVPMacPointer(); + + inline bool operator==(std::nullptr_t) noexcept { return mac_ == nullptr; } + inline operator bool() const { return mac_ != nullptr; } + inline EVP_MAC* get() const { return mac_.get(); } + inline operator EVP_MAC*() const { return mac_.get(); } + void reset(EVP_MAC* mac = nullptr); + EVP_MAC* release(); + + static EVPMacPointer Fetch(const char* algorithm); + + private: + DeleteFnPtr mac_; +}; + +class EVPMacCtxPointer final { + public: + EVPMacCtxPointer() = default; + explicit EVPMacCtxPointer(EVP_MAC_CTX* ctx); + EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept; + EVPMacCtxPointer& operator=(EVPMacCtxPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(EVPMacCtxPointer) + ~EVPMacCtxPointer(); + + inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; } + inline operator bool() const { return ctx_ != nullptr; } + inline EVP_MAC_CTX* get() const { return ctx_.get(); } + inline operator EVP_MAC_CTX*() const { return ctx_.get(); } + void reset(EVP_MAC_CTX* ctx = nullptr); + EVP_MAC_CTX* release(); + + bool init(const Buffer& key, const OSSL_PARAM* params = nullptr); + bool update(const Buffer& data); + DataPointer final(size_t length); + + static EVPMacCtxPointer New(EVP_MAC* mac); + + private: + DeleteFnPtr ctx_; +}; +#endif // OPENSSL_VERSION_MAJOR >= 3 + #ifndef OPENSSL_NO_ENGINE class EnginePointer final { public: diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 19f496eaa9405d..d65db1e815042c 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2,6 +2,9 @@ -* Type: {KeyAlgorithm|RsaHashedKeyAlgorithm|EcKeyAlgorithm|AesKeyAlgorithm|HmacKeyAlgorithm} +* Type: {KeyAlgorithm|RsaHashedKeyAlgorithm|EcKeyAlgorithm|AesKeyAlgorithm|HmacKeyAlgorithm|KmacKeyAlgorithm} @@ -736,6 +745,8 @@ Valid key usages depend on the key algorithm (identified by | `'Ed448'`[^secure-curves] | | ✔ | | | | | `'HDKF'` | | | ✔ | | | | `'HMAC'` | | ✔ | | | | +| `'KMAC128'`[^modern-algos] | | ✔ | | | | +| `'KMAC256'`[^modern-algos] | | ✔ | | | | | `'ML-DSA-44'`[^modern-algos] | | ✔ | | | | | `'ML-DSA-65'`[^modern-algos] | | ✔ | | | | | `'ML-DSA-87'`[^modern-algos] | | ✔ | | | | @@ -831,7 +842,7 @@ added: v24.7.0 * `decapsulationAlgorithm` {string|Algorithm} * `decapsulationKey` {CryptoKey} * `ciphertext` {ArrayBuffer|TypedArray|DataView|Buffer} -* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams} +* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams|KmacImportParams} * `extractable` {boolean} * `usages` {string\[]} See [Key usages][]. * Returns: {Promise} Fulfills with {CryptoKey} upon success. @@ -946,7 +957,7 @@ changes: * `algorithm` {EcdhKeyDeriveParams|HkdfParams|Pbkdf2Params|Argon2Params} * `baseKey` {CryptoKey} -* `derivedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams} +* `derivedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams|KmacImportParams} * `extractable` {boolean} * `keyUsages` {string\[]} See [Key usages][]. * Returns: {Promise} Fulfills with a {CryptoKey} upon success. @@ -1037,7 +1048,7 @@ added: v24.7.0 * `encapsulationAlgorithm` {string|Algorithm} * `encapsulationKey` {CryptoKey} -* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams} +* `sharedKeyAlgorithm` {string|Algorithm|HmacImportParams|AesDerivedKeyParams|KmacImportParams} * `extractable` {boolean} * `usages` {string\[]} See [Key usages][]. * Returns: {Promise} Fulfills with {EncapsulatedKey} upon success. @@ -1085,6 +1096,9 @@ The algorithms currently supported include: -* `algorithm` {string|Algorithm|RsaHashedKeyGenParams|EcKeyGenParams|HmacKeyGenParams|AesKeyGenParams} +* `algorithm` {string|Algorithm|RsaHashedKeyGenParams|EcKeyGenParams|HmacKeyGenParams|AesKeyGenParams|KmacKeyGenParams} @@ -1217,12 +1236,17 @@ The {CryptoKey} (secret key) generating algorithms supported include: * `'AES-OCB'`[^modern-algos] * `'ChaCha20-Poly1305'`[^modern-algos] * `'HMAC'` +* `'KMAC128'`[^modern-algos] +* `'KMAC256'`[^modern-algos] ### `subtle.importKey(format, keyData, algorithm, extractable, keyUsages)` -* `algorithm` {string|Algorithm|RsaHashedImportParams|EcKeyImportParams|HmacImportParams} +* `algorithm` {string|Algorithm|RsaHashedImportParams|EcKeyImportParams|HmacImportParams|KmacImportParams} @@ -1283,6 +1307,8 @@ The algorithms currently supported include: | `'Ed448'`[^secure-curves] | ✔ | ✔ | ✔ | ✔ | | ✔ | | | `'HDKF'` | | | | ✔ | ✔ | | | | `'HMAC'` | | | ✔ | ✔ | ✔ | | | +| `'KMAC128'`[^modern-algos] | | | ✔ | | ✔ | | | +| `'KMAC256'`[^modern-algos] | | | ✔ | | ✔ | | | | `'ML-DSA-44'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ | | `'ML-DSA-65'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ | | `'ML-DSA-87'`[^modern-algos] | ✔ | ✔ | ✔ | | | ✔ | ✔ | @@ -1301,6 +1327,9 @@ The algorithms currently supported include: -* `algorithm` {string|Algorithm|RsaPssParams|EcdsaParams|Ed448Params|ContextParams} +* `algorithm` {string|Algorithm|RsaPssParams|EcdsaParams|Ed448Params|ContextParams|KmacParams} * `key` {CryptoKey} * `data` {ArrayBuffer|TypedArray|DataView|Buffer} * Returns: {Promise} Fulfills with an {ArrayBuffer} upon success. @@ -1331,6 +1360,8 @@ The algorithms currently supported include: * `'Ed25519'` * `'Ed448'`[^secure-curves] * `'HMAC'` +* `'KMAC128'`[^modern-algos] +* `'KMAC256'`[^modern-algos] * `'ML-DSA-44'`[^modern-algos] * `'ML-DSA-65'`[^modern-algos] * `'ML-DSA-87'`[^modern-algos] @@ -1358,7 +1389,7 @@ changes: * `unwrapAlgo` {string|Algorithm|RsaOaepParams|AesCtrParams|AesCbcParams|AeadParams} -* `unwrappedKeyAlgo` {string|Algorithm|RsaHashedImportParams|EcKeyImportParams|HmacImportParams} +* `unwrappedKeyAlgo` {string|Algorithm|RsaHashedImportParams|EcKeyImportParams|HmacImportParams|KmacImportParams} @@ -1398,6 +1429,8 @@ The unwrapped key algorithms supported include: * `'Ed25519'` * `'Ed448'`[^secure-curves] * `'HMAC'` +* `'KMAC128'`[^secure-curves] +* `'KMAC256'`[^secure-curves] * `'ML-DSA-44'`[^modern-algos] * `'ML-DSA-65'`[^modern-algos] * `'ML-DSA-87'`[^modern-algos] @@ -1415,6 +1448,9 @@ The unwrapped key algorithms supported include: + +#### `kmacImportParams.length` + + + +* Type: {number} + +The optional number of bits in the KMAC key. This is optional and should +be omitted for most cases. + +#### `kmacImportParams.name` + + + +* Type: {string} Must be `'KMAC128'` or `'KMAC256'`. + +### Class: `KmacKeyAlgorithm` + + + +#### `kmacKeyAlgorithm.length` + + + +* Type: {number} + +The length of the KMAC key in bits. + +#### `kmacKeyAlgorithm.name` + + + +* Type: {string} + +### Class: `KmacKeyGenParams` + + + +#### `kmacKeyGenParams.length` + + + +* Type: {number} + +The number of bits to generate for the KMAC key. If omitted, +the length will be determined by the KMAC algorithm used. +This is optional and should be omitted for most cases. + +#### `kmacKeyGenParams.name` + + + +* Type: {string} Must be `'KMAC128'` or `'KMAC256'`. + +### Class: `KmacParams` + + + +#### `kmacParams.algorithm` + + + +* Type: {string} Must be `'KMAC128'` or `'KMAC256'`. + +#### `kmacParams.customization` + + + +* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined} + +The `customization` member represents the optional customization string. + +#### `kmacParams.length` + + + +* Type: {number} + +The length of the output in bytes. This must be a positive integer. + ### Class: `Pbkdf2Params`