react-native-quick-crypto 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/CMakeLists.txt +16 -0
- package/cpp/argon2/HybridArgon2.cpp +103 -0
- package/cpp/argon2/HybridArgon2.hpp +32 -0
- package/cpp/certificate/HybridCertificate.cpp +42 -0
- package/cpp/certificate/HybridCertificate.hpp +16 -0
- package/cpp/cipher/CCMCipher.cpp +4 -1
- package/cpp/cipher/ChaCha20Cipher.cpp +3 -1
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +5 -5
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/HybridCipher.cpp +68 -1
- package/cpp/cipher/HybridCipher.hpp +6 -0
- package/cpp/cipher/HybridRsaCipher.cpp +0 -13
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/XSalsa20Cipher.cpp +4 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +1 -2
- package/cpp/dh/HybridDhKeyPair.cpp +179 -0
- package/cpp/dh/HybridDhKeyPair.hpp +37 -0
- package/cpp/dsa/HybridDsaKeyPair.cpp +128 -0
- package/cpp/dsa/HybridDsaKeyPair.hpp +32 -0
- package/cpp/ecdh/HybridECDH.cpp +42 -120
- package/cpp/ecdh/HybridECDH.hpp +1 -0
- package/cpp/keys/HybridKeyObjectHandle.cpp +150 -128
- package/cpp/keys/HybridKeyObjectHandle.hpp +6 -3
- package/cpp/keys/KeyObjectData.hpp +2 -0
- package/cpp/kmac/HybridKmac.cpp +83 -0
- package/cpp/kmac/HybridKmac.hpp +31 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.cpp +11 -20
- package/cpp/mldsa/HybridMlDsaKeyPair.hpp +4 -2
- package/cpp/mlkem/HybridMlKemKeyPair.cpp +319 -0
- package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
- package/cpp/prime/HybridPrime.cpp +81 -0
- package/cpp/prime/HybridPrime.hpp +20 -0
- package/cpp/sign/SignUtils.hpp +9 -26
- package/cpp/utils/QuickCryptoUtils.cpp +44 -0
- package/cpp/utils/QuickCryptoUtils.hpp +39 -0
- package/cpp/x509/HybridX509Certificate.cpp +174 -0
- package/cpp/x509/HybridX509Certificate.hpp +51 -0
- package/lib/commonjs/argon2.js +39 -0
- package/lib/commonjs/argon2.js.map +1 -0
- package/lib/commonjs/certificate.js +35 -0
- package/lib/commonjs/certificate.js.map +1 -0
- package/lib/commonjs/cipher.js +23 -2
- package/lib/commonjs/cipher.js.map +1 -1
- package/lib/commonjs/dhKeyPair.js +109 -0
- package/lib/commonjs/dhKeyPair.js.map +1 -0
- package/lib/commonjs/dsa.js +92 -0
- package/lib/commonjs/dsa.js.map +1 -0
- package/lib/commonjs/ec.js +18 -18
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/ecdh.js +37 -0
- package/lib/commonjs/ecdh.js.map +1 -1
- package/lib/commonjs/ed.js +9 -9
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/hash.js +17 -12
- package/lib/commonjs/hash.js.map +1 -1
- package/lib/commonjs/hkdf.js.map +1 -1
- package/lib/commonjs/index.js +57 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +11 -9
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/generateKeyPair.js +11 -0
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
- package/lib/commonjs/keys/index.js +24 -0
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/signVerify.js +0 -2
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/mlkem.js +219 -0
- package/lib/commonjs/mlkem.js.map +1 -0
- package/lib/commonjs/pbkdf2.js +18 -1
- package/lib/commonjs/pbkdf2.js.map +1 -1
- package/lib/commonjs/prime.js +84 -0
- package/lib/commonjs/prime.js.map +1 -0
- package/lib/commonjs/rsa.js +7 -7
- package/lib/commonjs/rsa.js.map +1 -1
- package/lib/commonjs/specs/argon2.nitro.js +6 -0
- package/lib/commonjs/specs/argon2.nitro.js.map +1 -0
- package/lib/commonjs/specs/certificate.nitro.js +6 -0
- package/lib/commonjs/specs/certificate.nitro.js.map +1 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/kmac.nitro.js +6 -0
- package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/prime.nitro.js +6 -0
- package/lib/commonjs/specs/prime.nitro.js.map +1 -0
- package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
- package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +385 -114
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/conversion.js +3 -3
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/hashnames.js +31 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/x509certificate.js +189 -0
- package/lib/commonjs/x509certificate.js.map +1 -0
- package/lib/module/argon2.js +34 -0
- package/lib/module/argon2.js.map +1 -0
- package/lib/module/certificate.js +30 -0
- package/lib/module/certificate.js.map +1 -0
- package/lib/module/cipher.js +23 -3
- package/lib/module/cipher.js.map +1 -1
- package/lib/module/dhKeyPair.js +102 -0
- package/lib/module/dhKeyPair.js.map +1 -0
- package/lib/module/dsa.js +85 -0
- package/lib/module/dsa.js.map +1 -0
- package/lib/module/ec.js +6 -6
- package/lib/module/ec.js.map +1 -1
- package/lib/module/ecdh.js +37 -0
- package/lib/module/ecdh.js.map +1 -1
- package/lib/module/ed.js +1 -1
- package/lib/module/ed.js.map +1 -1
- package/lib/module/hash.js +17 -12
- package/lib/module/hash.js.map +1 -1
- package/lib/module/hkdf.js.map +1 -1
- package/lib/module/index.js +15 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +11 -9
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/generateKeyPair.js +11 -0
- package/lib/module/keys/generateKeyPair.js.map +1 -1
- package/lib/module/keys/index.js +25 -1
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/signVerify.js +0 -2
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/mlkem.js +211 -0
- package/lib/module/mlkem.js.map +1 -0
- package/lib/module/pbkdf2.js +18 -1
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/module/prime.js +77 -0
- package/lib/module/prime.js.map +1 -0
- package/lib/module/rsa.js +1 -1
- package/lib/module/rsa.js.map +1 -1
- package/lib/module/specs/argon2.nitro.js +4 -0
- package/lib/module/specs/argon2.nitro.js.map +1 -0
- package/lib/module/specs/certificate.nitro.js +4 -0
- package/lib/module/specs/certificate.nitro.js.map +1 -0
- package/lib/module/specs/dhKeyPair.nitro.js +4 -0
- package/lib/module/specs/dhKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/dsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/dsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/kmac.nitro.js +4 -0
- package/lib/module/specs/kmac.nitro.js.map +1 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/prime.nitro.js +4 -0
- package/lib/module/specs/prime.nitro.js.map +1 -0
- package/lib/module/specs/x509certificate.nitro.js +4 -0
- package/lib/module/specs/x509certificate.nitro.js.map +1 -0
- package/lib/module/subtle.js +386 -116
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/conversion.js +3 -4
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/hashnames.js +31 -0
- package/lib/module/utils/hashnames.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/x509certificate.js +184 -0
- package/lib/module/x509certificate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/argon2.d.ts +16 -0
- package/lib/typescript/argon2.d.ts.map +1 -0
- package/lib/typescript/certificate.d.ts +8 -0
- package/lib/typescript/certificate.d.ts.map +1 -0
- package/lib/typescript/cipher.d.ts +15 -0
- package/lib/typescript/cipher.d.ts.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts +19 -0
- package/lib/typescript/dhKeyPair.d.ts.map +1 -0
- package/lib/typescript/dsa.d.ts +19 -0
- package/lib/typescript/dsa.d.ts.map +1 -0
- package/lib/typescript/ec.d.ts +1 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/ecdh.d.ts +3 -0
- package/lib/typescript/ecdh.d.ts.map +1 -1
- package/lib/typescript/ed.d.ts +1 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/hash.d.ts.map +1 -1
- package/lib/typescript/hkdf.d.ts +2 -6
- package/lib/typescript/hkdf.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +32 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +7 -5
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +2 -2
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/mlkem.d.ts +30 -0
- package/lib/typescript/mlkem.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +2 -2
- package/lib/typescript/pbkdf2.d.ts.map +1 -1
- package/lib/typescript/prime.d.ts +19 -0
- package/lib/typescript/prime.d.ts.map +1 -0
- package/lib/typescript/rsa.d.ts +1 -1
- package/lib/typescript/rsa.d.ts.map +1 -1
- package/lib/typescript/specs/argon2.nitro.d.ts +9 -0
- package/lib/typescript/specs/argon2.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/certificate.nitro.d.ts +10 -0
- package/lib/typescript/specs/certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/cipher.nitro.d.ts +9 -0
- package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts +14 -0
- package/lib/typescript/specs/dhKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts +13 -0
- package/lib/typescript/specs/dsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts +1 -0
- package/lib/typescript/specs/ecdh.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/prime.nitro.d.ts +11 -0
- package/lib/typescript/specs/prime.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +12 -0
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/hashnames.d.ts +1 -1
- package/lib/typescript/utils/hashnames.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +25 -9
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/x509certificate.d.ts +64 -0
- package/lib/typescript/x509certificate.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +8 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +80 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +80 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
- package/nitrogen/generated/shared/c++/CipherInfo.hpp +104 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridArgon2Spec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridCertificateSpec.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +4 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.cpp +27 -0
- package/nitrogen/generated/shared/c++/HybridDhKeyPairSpec.hpp +69 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridDsaKeyPairSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridECDHSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridPrimeSpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
- package/package.json +4 -1
- package/src/argon2.ts +83 -0
- package/src/certificate.ts +41 -0
- package/src/cipher.ts +41 -3
- package/src/dhKeyPair.ts +156 -0
- package/src/dsa.ts +129 -0
- package/src/ec.ts +9 -9
- package/src/ecdh.ts +59 -0
- package/src/ed.ts +2 -2
- package/src/hash.ts +34 -11
- package/src/hkdf.ts +2 -7
- package/src/index.ts +16 -0
- package/src/keys/classes.ts +26 -14
- package/src/keys/generateKeyPair.ts +14 -0
- package/src/keys/index.ts +37 -2
- package/src/keys/signVerify.ts +0 -5
- package/src/mlkem.ts +350 -0
- package/src/pbkdf2.ts +34 -5
- package/src/prime.ts +134 -0
- package/src/rsa.ts +1 -1
- package/src/specs/argon2.nitro.ts +29 -0
- package/src/specs/certificate.nitro.ts +8 -0
- package/src/specs/cipher.nitro.ts +14 -0
- package/src/specs/dhKeyPair.nitro.ts +14 -0
- package/src/specs/dsaKeyPair.nitro.ts +13 -0
- package/src/specs/ecdh.nitro.ts +1 -0
- package/src/specs/keyObjectHandle.nitro.ts +5 -0
- package/src/specs/kmac.nitro.ts +12 -0
- package/src/specs/mlKemKeyPair.nitro.ts +32 -0
- package/src/specs/prime.nitro.ts +18 -0
- package/src/specs/x509certificate.nitro.ts +38 -0
- package/src/subtle.ts +821 -136
- package/src/utils/conversion.ts +10 -4
- package/src/utils/hashnames.ts +33 -2
- package/src/utils/types.ts +64 -8
- package/src/x509certificate.ts +277 -0
package/lib/commonjs/subtle.js
CHANGED
|
@@ -10,6 +10,7 @@ var _safeBuffer = require("safe-buffer");
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
11
|
var _keys = require("./keys");
|
|
12
12
|
var _conversion = require("./utils/conversion");
|
|
13
|
+
var _argon = require("./argon2");
|
|
13
14
|
var _errors = require("./utils/errors");
|
|
14
15
|
var _hashnames = require("./utils/hashnames");
|
|
15
16
|
var _validation = require("./utils/validation");
|
|
@@ -20,16 +21,13 @@ var _ec = require("./ec");
|
|
|
20
21
|
var _rsa = require("./rsa");
|
|
21
22
|
var _random = require("./random");
|
|
22
23
|
var _hmac = require("./hmac");
|
|
24
|
+
var _timingSafeEqual = require("./utils/timingSafeEqual");
|
|
23
25
|
var _signVerify = require("./keys/signVerify");
|
|
24
26
|
var _ed = require("./ed");
|
|
25
27
|
var _mldsa = require("./mldsa");
|
|
28
|
+
var _mlkem = require("./mlkem");
|
|
26
29
|
var _hkdf = require("./hkdf");
|
|
27
30
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
28
|
-
// import { pbkdf2DeriveBits } from './pbkdf2';
|
|
29
|
-
// import { aesCipher, aesGenerateKey, aesImportKey, getAlgorithmName } from './aes';
|
|
30
|
-
// import { rsaCipher, rsaExportKey, rsaImportKey, rsaKeyGenerate } from './rsa';
|
|
31
|
-
// import { normalizeAlgorithm, type Operation } from './algorithms';
|
|
32
|
-
// import { hmacImportKey } from './mac';
|
|
33
31
|
// Temporary enums that need to be defined
|
|
34
32
|
var KWebCryptoKeyFormat = /*#__PURE__*/function (KWebCryptoKeyFormat) {
|
|
35
33
|
KWebCryptoKeyFormat[KWebCryptoKeyFormat["kWebCryptoKeyFormatRaw"] = 0] = "kWebCryptoKeyFormatRaw";
|
|
@@ -75,15 +73,15 @@ function getAlgorithmName(name, length) {
|
|
|
75
73
|
// Placeholder implementations for missing functions
|
|
76
74
|
function ecExportKey(key, format) {
|
|
77
75
|
const keyObject = key.keyObject;
|
|
78
|
-
if (format === KWebCryptoKeyFormat.
|
|
79
|
-
|
|
76
|
+
if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw) {
|
|
77
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(keyObject.handle.exportKey());
|
|
78
|
+
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
|
|
80
79
|
const exported = keyObject.export({
|
|
81
80
|
format: 'der',
|
|
82
81
|
type: 'spki'
|
|
83
82
|
});
|
|
84
83
|
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
85
84
|
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
|
|
86
|
-
// Export private key in PKCS8 format
|
|
87
85
|
const exported = keyObject.export({
|
|
88
86
|
format: 'der',
|
|
89
87
|
type: 'pkcs8'
|
|
@@ -492,6 +490,100 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
|
492
490
|
};
|
|
493
491
|
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
494
492
|
}
|
|
493
|
+
async function kmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
494
|
+
const {
|
|
495
|
+
name
|
|
496
|
+
} = algorithm;
|
|
497
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
498
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
499
|
+
}
|
|
500
|
+
const defaultLength = name === 'KMAC128' ? 128 : 256;
|
|
501
|
+
const length = algorithm.length ?? defaultLength;
|
|
502
|
+
if (length === 0) {
|
|
503
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'OperationError');
|
|
504
|
+
}
|
|
505
|
+
const keyBytes = new Uint8Array(Math.ceil(length / 8));
|
|
506
|
+
(0, _random.getRandomValues)(keyBytes);
|
|
507
|
+
const keyObject = (0, _keys.createSecretKey)(keyBytes);
|
|
508
|
+
const keyAlgorithm = {
|
|
509
|
+
name: name,
|
|
510
|
+
length
|
|
511
|
+
};
|
|
512
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
513
|
+
}
|
|
514
|
+
function kmacSignVerify(key, data, algorithm, signature) {
|
|
515
|
+
const {
|
|
516
|
+
name
|
|
517
|
+
} = algorithm;
|
|
518
|
+
const defaultLength = name === 'KMAC128' ? 256 : 512;
|
|
519
|
+
const outputLengthBits = algorithm.length ?? defaultLength;
|
|
520
|
+
if (outputLengthBits % 8 !== 0) {
|
|
521
|
+
throw (0, _errors.lazyDOMException)('KMAC output length must be a multiple of 8', 'OperationError');
|
|
522
|
+
}
|
|
523
|
+
const outputLengthBytes = outputLengthBits / 8;
|
|
524
|
+
const keyData = key.keyObject.export();
|
|
525
|
+
const kmac = _reactNativeNitroModules.NitroModules.createHybridObject('Kmac');
|
|
526
|
+
let customizationBuffer;
|
|
527
|
+
if (algorithm.customization !== undefined) {
|
|
528
|
+
customizationBuffer = (0, _conversion.bufferLikeToArrayBuffer)(algorithm.customization);
|
|
529
|
+
}
|
|
530
|
+
kmac.createKmac(name, (0, _conversion.bufferLikeToArrayBuffer)(keyData), outputLengthBytes, customizationBuffer);
|
|
531
|
+
kmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
532
|
+
const computed = kmac.digest();
|
|
533
|
+
if (signature === undefined) {
|
|
534
|
+
return computed;
|
|
535
|
+
}
|
|
536
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
537
|
+
if (computed.byteLength !== sigBuffer.byteLength) {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computed), new Uint8Array(sigBuffer));
|
|
541
|
+
}
|
|
542
|
+
async function kmacImportKey(algorithm, format, data, extractable, keyUsages) {
|
|
543
|
+
const {
|
|
544
|
+
name
|
|
545
|
+
} = algorithm;
|
|
546
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
547
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
548
|
+
}
|
|
549
|
+
let keyObject;
|
|
550
|
+
if (format === 'jwk') {
|
|
551
|
+
const jwk = data;
|
|
552
|
+
if (!jwk || typeof jwk !== 'object') {
|
|
553
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
554
|
+
}
|
|
555
|
+
if (jwk.kty !== 'oct') {
|
|
556
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK format for KMAC key', 'DataError');
|
|
557
|
+
}
|
|
558
|
+
const expectedAlg = name === 'KMAC128' ? 'K128' : 'K256';
|
|
559
|
+
if (jwk.alg !== undefined && jwk.alg !== expectedAlg) {
|
|
560
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" does not match the requested algorithm', 'DataError');
|
|
561
|
+
}
|
|
562
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
563
|
+
const keyType = handle.initJwk(jwk, undefined);
|
|
564
|
+
if (keyType === undefined || keyType !== 0) {
|
|
565
|
+
throw (0, _errors.lazyDOMException)('Failed to import KMAC JWK', 'DataError');
|
|
566
|
+
}
|
|
567
|
+
keyObject = new _keys.SecretKeyObject(handle);
|
|
568
|
+
} else if (format === 'raw' || format === 'raw-secret') {
|
|
569
|
+
keyObject = (0, _keys.createSecretKey)(data);
|
|
570
|
+
} else {
|
|
571
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
572
|
+
}
|
|
573
|
+
const exported = keyObject.export();
|
|
574
|
+
const keyLength = exported.byteLength * 8;
|
|
575
|
+
if (keyLength === 0) {
|
|
576
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'DataError');
|
|
577
|
+
}
|
|
578
|
+
if (algorithm.length !== undefined && algorithm.length !== keyLength) {
|
|
579
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'DataError');
|
|
580
|
+
}
|
|
581
|
+
const keyAlgorithm = {
|
|
582
|
+
name: name,
|
|
583
|
+
length: keyLength
|
|
584
|
+
};
|
|
585
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
586
|
+
}
|
|
495
587
|
function rsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
496
588
|
const {
|
|
497
589
|
name
|
|
@@ -729,28 +821,48 @@ function edImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
|
729
821
|
name
|
|
730
822
|
}, keyUsages, extractable);
|
|
731
823
|
}
|
|
824
|
+
function pqcImportKeyObject(format, data, name) {
|
|
825
|
+
if (format === 'spki') {
|
|
826
|
+
return _keys.KeyObject.createKeyObject('public', (0, _conversion.bufferLikeToArrayBuffer)(data), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
827
|
+
} else if (format === 'pkcs8') {
|
|
828
|
+
return _keys.KeyObject.createKeyObject('private', (0, _conversion.bufferLikeToArrayBuffer)(data), _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
829
|
+
} else if (format === 'raw') {
|
|
830
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
831
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), true)) {
|
|
832
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw public key`, 'DataError');
|
|
833
|
+
}
|
|
834
|
+
return new _keys.PublicKeyObject(handle);
|
|
835
|
+
} else if (format === 'raw-seed') {
|
|
836
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
837
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), false)) {
|
|
838
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw seed`, 'DataError');
|
|
839
|
+
}
|
|
840
|
+
return new _keys.PrivateKeyObject(handle);
|
|
841
|
+
}
|
|
842
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
843
|
+
}
|
|
732
844
|
function mldsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
733
845
|
const {
|
|
734
846
|
name
|
|
735
847
|
} = algorithm;
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
848
|
+
const isPublicFormat = format === 'spki' || format === 'raw';
|
|
849
|
+
if (hasAnyNotIn(keyUsages, isPublicFormat ? ['verify'] : ['sign'])) {
|
|
739
850
|
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
740
851
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
852
|
+
return new _keys.CryptoKey(pqcImportKeyObject(format, data, name), {
|
|
853
|
+
name
|
|
854
|
+
}, keyUsages, extractable);
|
|
855
|
+
}
|
|
856
|
+
function mlkemImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
857
|
+
const {
|
|
858
|
+
name
|
|
859
|
+
} = algorithm;
|
|
860
|
+
const isPublicFormat = format === 'spki' || format === 'raw';
|
|
861
|
+
const allowedUsages = isPublicFormat ? ['encapsulateBits', 'encapsulateKey'] : ['decapsulateBits', 'decapsulateKey'];
|
|
862
|
+
if (hasAnyNotIn(keyUsages, allowedUsages)) {
|
|
863
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
752
864
|
}
|
|
753
|
-
return new _keys.CryptoKey(
|
|
865
|
+
return new _keys.CryptoKey(pqcImportKeyObject(format, data, name), {
|
|
754
866
|
name
|
|
755
867
|
}, keyUsages, extractable);
|
|
756
868
|
}
|
|
@@ -794,6 +906,15 @@ const exportKeySpki = async key => {
|
|
|
794
906
|
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
795
907
|
}
|
|
796
908
|
break;
|
|
909
|
+
case 'ML-KEM-512':
|
|
910
|
+
// Fall through
|
|
911
|
+
case 'ML-KEM-768':
|
|
912
|
+
// Fall through
|
|
913
|
+
case 'ML-KEM-1024':
|
|
914
|
+
if (key.type === 'public') {
|
|
915
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
916
|
+
}
|
|
917
|
+
break;
|
|
797
918
|
}
|
|
798
919
|
throw new Error(`Unable to export a spki ${key.algorithm.name} ${key.type} key`);
|
|
799
920
|
};
|
|
@@ -837,6 +958,15 @@ const exportKeyPkcs8 = async key => {
|
|
|
837
958
|
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
838
959
|
}
|
|
839
960
|
break;
|
|
961
|
+
case 'ML-KEM-512':
|
|
962
|
+
// Fall through
|
|
963
|
+
case 'ML-KEM-768':
|
|
964
|
+
// Fall through
|
|
965
|
+
case 'ML-KEM-1024':
|
|
966
|
+
if (key.type === 'private') {
|
|
967
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
968
|
+
}
|
|
969
|
+
break;
|
|
840
970
|
}
|
|
841
971
|
throw new Error(`Unable to export a pkcs8 ${key.algorithm.name} ${key.type} key`);
|
|
842
972
|
};
|
|
@@ -857,7 +987,22 @@ const exportKeyRaw = key => {
|
|
|
857
987
|
// Fall through
|
|
858
988
|
case 'X448':
|
|
859
989
|
if (key.type === 'public') {
|
|
860
|
-
|
|
990
|
+
const exported = key.keyObject.handle.exportKey();
|
|
991
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
992
|
+
}
|
|
993
|
+
break;
|
|
994
|
+
case 'ML-KEM-512':
|
|
995
|
+
// Fall through
|
|
996
|
+
case 'ML-KEM-768':
|
|
997
|
+
// Fall through
|
|
998
|
+
case 'ML-KEM-1024':
|
|
999
|
+
// Fall through
|
|
1000
|
+
case 'ML-DSA-44':
|
|
1001
|
+
// Fall through
|
|
1002
|
+
case 'ML-DSA-65':
|
|
1003
|
+
// Fall through
|
|
1004
|
+
case 'ML-DSA-87':
|
|
1005
|
+
if (key.type === 'public') {
|
|
861
1006
|
const exported = key.keyObject.handle.exportKey();
|
|
862
1007
|
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
863
1008
|
}
|
|
@@ -875,6 +1020,10 @@ const exportKeyRaw = key => {
|
|
|
875
1020
|
case 'ChaCha20-Poly1305':
|
|
876
1021
|
// Fall through
|
|
877
1022
|
case 'HMAC':
|
|
1023
|
+
// Fall through
|
|
1024
|
+
case 'KMAC128':
|
|
1025
|
+
// Fall through
|
|
1026
|
+
case 'KMAC256':
|
|
878
1027
|
{
|
|
879
1028
|
const exported = key.keyObject.export();
|
|
880
1029
|
// Convert Buffer to ArrayBuffer
|
|
@@ -901,6 +1050,12 @@ const exportKeyJWK = key => {
|
|
|
901
1050
|
case 'HMAC':
|
|
902
1051
|
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkHmac);
|
|
903
1052
|
return jwk;
|
|
1053
|
+
case 'KMAC128':
|
|
1054
|
+
jwk.alg = 'K128';
|
|
1055
|
+
return jwk;
|
|
1056
|
+
case 'KMAC256':
|
|
1057
|
+
jwk.alg = 'K256';
|
|
1058
|
+
return jwk;
|
|
904
1059
|
case 'ECDSA':
|
|
905
1060
|
// Fall through
|
|
906
1061
|
case 'ECDH':
|
|
@@ -988,6 +1143,37 @@ const checkCryptoKeyPairUsages = pair => {
|
|
|
988
1143
|
}
|
|
989
1144
|
throw (0, _errors.lazyDOMException)('Usages cannot be empty when creating a key.', 'SyntaxError');
|
|
990
1145
|
};
|
|
1146
|
+
function argon2DeriveBits(algorithm, baseKey, length) {
|
|
1147
|
+
if (length === 0 || length % 8 !== 0) {
|
|
1148
|
+
throw (0, _errors.lazyDOMException)('Invalid Argon2 derived key length', 'OperationError');
|
|
1149
|
+
}
|
|
1150
|
+
if (length < 32) {
|
|
1151
|
+
throw (0, _errors.lazyDOMException)('Argon2 derived key length must be at least 32 bits', 'OperationError');
|
|
1152
|
+
}
|
|
1153
|
+
const {
|
|
1154
|
+
nonce,
|
|
1155
|
+
parallelism,
|
|
1156
|
+
memory,
|
|
1157
|
+
passes,
|
|
1158
|
+
secretValue,
|
|
1159
|
+
associatedData
|
|
1160
|
+
} = algorithm;
|
|
1161
|
+
const tagLength = length / 8;
|
|
1162
|
+
const message = baseKey.keyObject.export();
|
|
1163
|
+
const algName = algorithm.name.toLowerCase();
|
|
1164
|
+
const result = (0, _argon.argon2Sync)(algName, {
|
|
1165
|
+
message,
|
|
1166
|
+
nonce: nonce ?? new Uint8Array(0),
|
|
1167
|
+
parallelism: parallelism ?? 1,
|
|
1168
|
+
tagLength,
|
|
1169
|
+
memory: memory ?? 65536,
|
|
1170
|
+
passes: passes ?? 3,
|
|
1171
|
+
secret: secretValue,
|
|
1172
|
+
associatedData,
|
|
1173
|
+
version: algorithm.version
|
|
1174
|
+
});
|
|
1175
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(result);
|
|
1176
|
+
}
|
|
991
1177
|
|
|
992
1178
|
// Type guard to check if result is CryptoKeyPair
|
|
993
1179
|
function isCryptoKeyPair(result) {
|
|
@@ -1008,20 +1194,12 @@ function hmacSignVerify(key, data, signature) {
|
|
|
1008
1194
|
// Sign operation - return the HMAC as ArrayBuffer
|
|
1009
1195
|
return computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
1010
1196
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const computedBytes = new Uint8Array(computed.buffer, computed.byteOffset, computed.byteLength);
|
|
1015
|
-
if (computedBytes.length !== sigBytes.length) {
|
|
1197
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
1198
|
+
const computedBuffer = computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
1199
|
+
if (computedBuffer.byteLength !== sigBuffer.byteLength) {
|
|
1016
1200
|
return false;
|
|
1017
1201
|
}
|
|
1018
|
-
|
|
1019
|
-
// Constant-time comparison to prevent timing attacks
|
|
1020
|
-
let result = 0;
|
|
1021
|
-
for (let i = 0; i < computedBytes.length; i++) {
|
|
1022
|
-
result |= computedBytes[i] ^ sigBytes[i];
|
|
1023
|
-
}
|
|
1024
|
-
return result === 0;
|
|
1202
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computedBuffer), new Uint8Array(sigBuffer));
|
|
1025
1203
|
}
|
|
1026
1204
|
function rsaSignVerify(key, data, padding, signature, saltLength) {
|
|
1027
1205
|
// Get hash algorithm from key
|
|
@@ -1124,6 +1302,9 @@ const signVerify = (algorithm, key, data, signature) => {
|
|
|
1124
1302
|
case 'ML-DSA-65':
|
|
1125
1303
|
case 'ML-DSA-87':
|
|
1126
1304
|
return mldsaSignVerify(key, data, signature);
|
|
1305
|
+
case 'KMAC128':
|
|
1306
|
+
case 'KMAC256':
|
|
1307
|
+
return kmacSignVerify(key, data, algorithm, signature);
|
|
1127
1308
|
}
|
|
1128
1309
|
throw (0, _errors.lazyDOMException)(`Unrecognized algorithm name '${algorithm.name}' for '${usage}'`, 'NotSupportedError');
|
|
1129
1310
|
};
|
|
@@ -1149,7 +1330,53 @@ const cipherOrWrap = async (mode, algorithm, key, data, op) => {
|
|
|
1149
1330
|
return chaCha20Poly1305Cipher(mode, key, data, algorithm);
|
|
1150
1331
|
}
|
|
1151
1332
|
};
|
|
1333
|
+
const SUPPORTED_ALGORITHMS = {
|
|
1334
|
+
encrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
1335
|
+
decrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
1336
|
+
sign: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1337
|
+
verify: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1338
|
+
digest: new Set(['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'cSHAKE128', 'cSHAKE256']),
|
|
1339
|
+
generateKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1340
|
+
importKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'HKDF', 'PBKDF2', 'Argon2d', 'Argon2i', 'Argon2id', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1341
|
+
exportKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1342
|
+
deriveBits: new Set(['PBKDF2', 'HKDF', 'ECDH', 'X25519', 'X448', 'Argon2d', 'Argon2i', 'Argon2id']),
|
|
1343
|
+
wrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
1344
|
+
unwrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
1345
|
+
encapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1346
|
+
decapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1347
|
+
encapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1348
|
+
decapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024'])
|
|
1349
|
+
};
|
|
1350
|
+
const ASYMMETRIC_ALGORITHMS = new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']);
|
|
1152
1351
|
class Subtle {
|
|
1352
|
+
static supports(operation, algorithm, _lengthOrAdditionalAlgorithm) {
|
|
1353
|
+
let normalizedAlgorithm;
|
|
1354
|
+
try {
|
|
1355
|
+
normalizedAlgorithm = normalizeAlgorithm(algorithm, operation === 'getPublicKey' ? 'exportKey' : operation);
|
|
1356
|
+
} catch {
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
const name = normalizedAlgorithm.name;
|
|
1360
|
+
if (operation === 'getPublicKey') {
|
|
1361
|
+
return ASYMMETRIC_ALGORITHMS.has(name);
|
|
1362
|
+
}
|
|
1363
|
+
if (operation === 'deriveKey') {
|
|
1364
|
+
// deriveKey decomposes to deriveBits + importKey of additional algorithm
|
|
1365
|
+
if (!SUPPORTED_ALGORITHMS.deriveBits?.has(name)) return false;
|
|
1366
|
+
if (_lengthOrAdditionalAlgorithm != null) {
|
|
1367
|
+
try {
|
|
1368
|
+
const additionalAlg = normalizeAlgorithm(_lengthOrAdditionalAlgorithm, 'importKey');
|
|
1369
|
+
return SUPPORTED_ALGORITHMS.importKey?.has(additionalAlg.name) ?? false;
|
|
1370
|
+
} catch {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return true;
|
|
1375
|
+
}
|
|
1376
|
+
const supported = SUPPORTED_ALGORITHMS[operation];
|
|
1377
|
+
if (!supported) return false;
|
|
1378
|
+
return supported.has(name);
|
|
1379
|
+
}
|
|
1153
1380
|
async decrypt(algorithm, key, data) {
|
|
1154
1381
|
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decrypt');
|
|
1155
1382
|
return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherDecrypt, normalizedAlgorithm, key, (0, _conversion.bufferLikeToArrayBuffer)(data), 'decrypt');
|
|
@@ -1175,6 +1402,10 @@ class Subtle {
|
|
|
1175
1402
|
return (0, _ec.ecDeriveBits)(algorithm, baseKey, length);
|
|
1176
1403
|
case 'HKDF':
|
|
1177
1404
|
return (0, _hkdf.hkdfDeriveBits)(algorithm, baseKey, length);
|
|
1405
|
+
case 'Argon2d':
|
|
1406
|
+
case 'Argon2i':
|
|
1407
|
+
case 'Argon2id':
|
|
1408
|
+
return argon2DeriveBits(algorithm, baseKey, length);
|
|
1178
1409
|
}
|
|
1179
1410
|
throw new Error(`'subtle.deriveBits()' for ${algorithm.name} is not implemented.`);
|
|
1180
1411
|
}
|
|
@@ -1205,6 +1436,11 @@ class Subtle {
|
|
|
1205
1436
|
case 'HKDF':
|
|
1206
1437
|
derivedBits = (0, _hkdf.hkdfDeriveBits)(algorithm, baseKey, length);
|
|
1207
1438
|
break;
|
|
1439
|
+
case 'Argon2d':
|
|
1440
|
+
case 'Argon2i':
|
|
1441
|
+
case 'Argon2id':
|
|
1442
|
+
derivedBits = argon2DeriveBits(algorithm, baseKey, length);
|
|
1443
|
+
break;
|
|
1208
1444
|
default:
|
|
1209
1445
|
throw new Error(`'subtle.deriveKey()' for ${algorithm.name} is not implemented.`);
|
|
1210
1446
|
}
|
|
@@ -1218,7 +1454,19 @@ class Subtle {
|
|
|
1218
1454
|
}
|
|
1219
1455
|
async exportKey(format, key) {
|
|
1220
1456
|
if (!key.extractable) throw new Error('key is not extractable');
|
|
1221
|
-
if (format === 'raw-
|
|
1457
|
+
if (format === 'raw-seed') {
|
|
1458
|
+
const pqcAlgos = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'];
|
|
1459
|
+
if (!pqcAlgos.includes(key.algorithm.name)) {
|
|
1460
|
+
throw (0, _errors.lazyDOMException)('raw-seed export only supported for PQC keys', 'NotSupportedError');
|
|
1461
|
+
}
|
|
1462
|
+
if (key.type !== 'private') {
|
|
1463
|
+
throw (0, _errors.lazyDOMException)('raw-seed export requires a private key', 'InvalidAccessError');
|
|
1464
|
+
}
|
|
1465
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey());
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// Note: 'raw-seed' is handled above; do NOT normalize it here
|
|
1469
|
+
if (format === 'raw-secret' || format === 'raw-public') format = 'raw';
|
|
1222
1470
|
switch (format) {
|
|
1223
1471
|
case 'spki':
|
|
1224
1472
|
return await exportKeySpki(key);
|
|
@@ -1343,6 +1591,11 @@ class Subtle {
|
|
|
1343
1591
|
case 'HMAC':
|
|
1344
1592
|
result = await hmacGenerateKey(algorithm, extractable, keyUsages);
|
|
1345
1593
|
break;
|
|
1594
|
+
case 'KMAC128':
|
|
1595
|
+
// Fall through
|
|
1596
|
+
case 'KMAC256':
|
|
1597
|
+
result = await kmacGenerateKey(algorithm, extractable, keyUsages);
|
|
1598
|
+
break;
|
|
1346
1599
|
case 'Ed25519':
|
|
1347
1600
|
// Fall through
|
|
1348
1601
|
case 'Ed448':
|
|
@@ -1363,14 +1616,33 @@ class Subtle {
|
|
|
1363
1616
|
result = await (0, _ed.x_generateKeyPairWebCrypto)(algorithm.name.toLowerCase(), extractable, keyUsages);
|
|
1364
1617
|
checkCryptoKeyPairUsages(result);
|
|
1365
1618
|
break;
|
|
1619
|
+
case 'ML-KEM-512':
|
|
1620
|
+
// Fall through
|
|
1621
|
+
case 'ML-KEM-768':
|
|
1622
|
+
// Fall through
|
|
1623
|
+
case 'ML-KEM-1024':
|
|
1624
|
+
result = await (0, _mlkem.mlkem_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
|
|
1625
|
+
checkCryptoKeyPairUsages(result);
|
|
1626
|
+
break;
|
|
1366
1627
|
default:
|
|
1367
1628
|
throw new Error(`'subtle.generateKey()' is not implemented for ${algorithm.name}.
|
|
1368
1629
|
Unrecognized algorithm name`);
|
|
1369
1630
|
}
|
|
1370
1631
|
return result;
|
|
1371
1632
|
}
|
|
1633
|
+
async getPublicKey(key, keyUsages) {
|
|
1634
|
+
if (key.type === 'secret') {
|
|
1635
|
+
throw (0, _errors.lazyDOMException)('key must be a private key', 'NotSupportedError');
|
|
1636
|
+
}
|
|
1637
|
+
if (key.type !== 'private') {
|
|
1638
|
+
throw (0, _errors.lazyDOMException)('key must be a private key', 'InvalidAccessError');
|
|
1639
|
+
}
|
|
1640
|
+
const publicKeyObject = (0, _keys.createPublicKey)(key.keyObject);
|
|
1641
|
+
return publicKeyObject.toCryptoKey(key.algorithm, true, keyUsages);
|
|
1642
|
+
}
|
|
1372
1643
|
async importKey(format, data, algorithm, extractable, keyUsages) {
|
|
1373
|
-
|
|
1644
|
+
// Note: 'raw-seed' is NOT normalized — PQC import functions handle it directly
|
|
1645
|
+
if (format === 'raw-secret' || format === 'raw-public') format = 'raw';
|
|
1374
1646
|
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'importKey');
|
|
1375
1647
|
let result;
|
|
1376
1648
|
switch (normalizedAlgorithm.name) {
|
|
@@ -1389,6 +1661,11 @@ class Subtle {
|
|
|
1389
1661
|
case 'HMAC':
|
|
1390
1662
|
result = await hmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1391
1663
|
break;
|
|
1664
|
+
case 'KMAC128':
|
|
1665
|
+
// Fall through
|
|
1666
|
+
case 'KMAC256':
|
|
1667
|
+
result = await kmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1668
|
+
break;
|
|
1392
1669
|
case 'AES-CTR':
|
|
1393
1670
|
// Fall through
|
|
1394
1671
|
case 'AES-CBC':
|
|
@@ -1403,6 +1680,9 @@ class Subtle {
|
|
|
1403
1680
|
result = await aesImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1404
1681
|
break;
|
|
1405
1682
|
case 'PBKDF2':
|
|
1683
|
+
case 'Argon2d':
|
|
1684
|
+
case 'Argon2i':
|
|
1685
|
+
case 'Argon2id':
|
|
1406
1686
|
result = await importGenericSecretKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1407
1687
|
break;
|
|
1408
1688
|
case 'HKDF':
|
|
@@ -1424,6 +1704,13 @@ class Subtle {
|
|
|
1424
1704
|
case 'ML-DSA-87':
|
|
1425
1705
|
result = mldsaImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
1426
1706
|
break;
|
|
1707
|
+
case 'ML-KEM-512':
|
|
1708
|
+
// Fall through
|
|
1709
|
+
case 'ML-KEM-768':
|
|
1710
|
+
// Fall through
|
|
1711
|
+
case 'ML-KEM-1024':
|
|
1712
|
+
result = mlkemImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
1713
|
+
break;
|
|
1427
1714
|
default:
|
|
1428
1715
|
throw new Error(`"subtle.importKey()" is not implemented for ${normalizedAlgorithm.name}`);
|
|
1429
1716
|
}
|
|
@@ -1433,85 +1720,65 @@ class Subtle {
|
|
|
1433
1720
|
return result;
|
|
1434
1721
|
}
|
|
1435
1722
|
async sign(algorithm, key, data) {
|
|
1436
|
-
|
|
1437
|
-
if (normalizedAlgorithm.name === 'HMAC') {
|
|
1438
|
-
// Validate key usage
|
|
1439
|
-
if (!key.usages.includes('sign')) {
|
|
1440
|
-
throw (0, _errors.lazyDOMException)('Key does not have sign usage', 'InvalidAccessError');
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
// Get hash algorithm from key or algorithm params
|
|
1444
|
-
// Hash can be either a string or an object with name property
|
|
1445
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1446
|
-
const alg = normalizedAlgorithm;
|
|
1447
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1448
|
-
const keyAlg = key.algorithm;
|
|
1449
|
-
let hashAlgorithm = 'SHA-256';
|
|
1450
|
-
if (typeof alg.hash === 'string') {
|
|
1451
|
-
hashAlgorithm = alg.hash;
|
|
1452
|
-
} else if (alg.hash?.name) {
|
|
1453
|
-
hashAlgorithm = alg.hash.name;
|
|
1454
|
-
} else if (typeof keyAlg.hash === 'string') {
|
|
1455
|
-
hashAlgorithm = keyAlg.hash;
|
|
1456
|
-
} else if (keyAlg.hash?.name) {
|
|
1457
|
-
hashAlgorithm = keyAlg.hash.name;
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
// Create HMAC and sign
|
|
1461
|
-
const keyData = key.keyObject.export();
|
|
1462
|
-
const hmac = (0, _hmac.createHmac)(hashAlgorithm, keyData);
|
|
1463
|
-
hmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
1464
|
-
return (0, _conversion.bufferLikeToArrayBuffer)(hmac.digest());
|
|
1465
|
-
}
|
|
1466
|
-
return signVerify(normalizedAlgorithm, key, data);
|
|
1723
|
+
return signVerify(normalizeAlgorithm(algorithm, 'sign'), key, data);
|
|
1467
1724
|
}
|
|
1468
1725
|
async verify(algorithm, key, signature, data) {
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
// Get hash algorithm
|
|
1477
|
-
// Hash can be either a string or an object with name property
|
|
1478
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1479
|
-
const alg = normalizedAlgorithm;
|
|
1480
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1481
|
-
const keyAlg = key.algorithm;
|
|
1482
|
-
let hashAlgorithm = 'SHA-256';
|
|
1483
|
-
if (typeof alg.hash === 'string') {
|
|
1484
|
-
hashAlgorithm = alg.hash;
|
|
1485
|
-
} else if (alg.hash?.name) {
|
|
1486
|
-
hashAlgorithm = alg.hash.name;
|
|
1487
|
-
} else if (typeof keyAlg.hash === 'string') {
|
|
1488
|
-
hashAlgorithm = keyAlg.hash;
|
|
1489
|
-
} else if (keyAlg.hash?.name) {
|
|
1490
|
-
hashAlgorithm = keyAlg.hash.name;
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
// Create HMAC and compute expected signature
|
|
1494
|
-
const keyData = key.keyObject.export();
|
|
1495
|
-
const hmac = (0, _hmac.createHmac)(hashAlgorithm, keyData);
|
|
1496
|
-
const dataBuffer = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1497
|
-
hmac.update(dataBuffer);
|
|
1498
|
-
const expectedDigest = hmac.digest();
|
|
1499
|
-
const expected = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(expectedDigest));
|
|
1500
|
-
|
|
1501
|
-
// Constant-time comparison
|
|
1502
|
-
const signatureArray = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(signature));
|
|
1503
|
-
if (expected.length !== signatureArray.length) {
|
|
1504
|
-
return false;
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
// Manual constant-time comparison
|
|
1508
|
-
let result = 0;
|
|
1509
|
-
for (let i = 0; i < expected.length; i++) {
|
|
1510
|
-
result |= expected[i] ^ signatureArray[i];
|
|
1511
|
-
}
|
|
1512
|
-
return result === 0;
|
|
1726
|
+
return signVerify(normalizeAlgorithm(algorithm, 'verify'), key, data, signature);
|
|
1727
|
+
}
|
|
1728
|
+
_encapsulateCore(algorithm, key) {
|
|
1729
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encapsulateBits');
|
|
1730
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
1731
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
1513
1732
|
}
|
|
1514
|
-
|
|
1733
|
+
const variant = normalizedAlgorithm.name;
|
|
1734
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
1735
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1736
|
+
mlkem.setPublicKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1737
|
+
return mlkem.encapsulateSync();
|
|
1738
|
+
}
|
|
1739
|
+
_decapsulateCore(algorithm, key, ciphertext) {
|
|
1740
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decapsulateBits');
|
|
1741
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
1742
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
1743
|
+
}
|
|
1744
|
+
const variant = normalizedAlgorithm.name;
|
|
1745
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
1746
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1747
|
+
mlkem.setPrivateKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1748
|
+
return mlkem.decapsulateSync((0, _conversion.bufferLikeToArrayBuffer)(ciphertext));
|
|
1749
|
+
}
|
|
1750
|
+
async encapsulateBits(algorithm, key) {
|
|
1751
|
+
if (!key.usages.includes('encapsulateBits')) {
|
|
1752
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateBits usage', 'InvalidAccessError');
|
|
1753
|
+
}
|
|
1754
|
+
return this._encapsulateCore(algorithm, key);
|
|
1755
|
+
}
|
|
1756
|
+
async encapsulateKey(algorithm, key, sharedKeyAlgorithm, extractable, usages) {
|
|
1757
|
+
if (!key.usages.includes('encapsulateKey')) {
|
|
1758
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateKey usage', 'InvalidAccessError');
|
|
1759
|
+
}
|
|
1760
|
+
const {
|
|
1761
|
+
sharedKey,
|
|
1762
|
+
ciphertext
|
|
1763
|
+
} = this._encapsulateCore(algorithm, key);
|
|
1764
|
+
const importedKey = await this.importKey('raw', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
1765
|
+
return {
|
|
1766
|
+
key: importedKey,
|
|
1767
|
+
ciphertext
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
async decapsulateBits(algorithm, key, ciphertext) {
|
|
1771
|
+
if (!key.usages.includes('decapsulateBits')) {
|
|
1772
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateBits usage', 'InvalidAccessError');
|
|
1773
|
+
}
|
|
1774
|
+
return this._decapsulateCore(algorithm, key, ciphertext);
|
|
1775
|
+
}
|
|
1776
|
+
async decapsulateKey(algorithm, key, ciphertext, sharedKeyAlgorithm, extractable, usages) {
|
|
1777
|
+
if (!key.usages.includes('decapsulateKey')) {
|
|
1778
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateKey usage', 'InvalidAccessError');
|
|
1779
|
+
}
|
|
1780
|
+
const sharedKey = this._decapsulateCore(algorithm, key, ciphertext);
|
|
1781
|
+
return this.importKey('raw', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
1515
1782
|
}
|
|
1516
1783
|
}
|
|
1517
1784
|
exports.Subtle = Subtle;
|
|
@@ -1531,6 +1798,10 @@ function getKeyLength(algorithm) {
|
|
|
1531
1798
|
const hmacAlg = algorithm;
|
|
1532
1799
|
return hmacAlg.length || 256;
|
|
1533
1800
|
}
|
|
1801
|
+
case 'KMAC128':
|
|
1802
|
+
return algorithm.length || 128;
|
|
1803
|
+
case 'KMAC256':
|
|
1804
|
+
return algorithm.length || 256;
|
|
1534
1805
|
default:
|
|
1535
1806
|
throw (0, _errors.lazyDOMException)(`Cannot determine key length for ${name}`, 'NotSupportedError');
|
|
1536
1807
|
}
|