summaryrefslogtreecommitdiff
path: root/ext/crypto/00_crypto.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r--ext/crypto/00_crypto.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index 0e5a511e5..2cb7a3bb2 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -61,6 +61,11 @@
RsaPssParams: {},
EcdsaParams: { hash: "HashAlgorithmIdentifier" },
HmacImportParams: { hash: "HashAlgorithmIdentifier" },
+ HkdfParams: {
+ hash: "HashAlgorithmIdentifier",
+ salt: "BufferSource",
+ info: "BufferSource",
+ },
Pbkdf2Params: { hash: "HashAlgorithmIdentifier", salt: "BufferSource" },
RsaOaepParams: { label: "BufferSource" },
};
@@ -97,9 +102,11 @@
},
"importKey": {
"HMAC": "HmacImportParams",
+ "HKDF": null,
"PBKDF2": null,
},
"deriveBits": {
+ "HKDF": "HkdfParams",
"PBKDF2": "Pbkdf2Params",
},
"encrypt": {
@@ -893,6 +900,51 @@
// TODO(@littledivy): RSASSA-PKCS1-v1_5
// TODO(@littledivy): RSA-PSS
// TODO(@littledivy): ECDSA
+ case "HKDF": {
+ if (format !== "raw") {
+ throw new DOMException("Format not supported", "NotSupportedError");
+ }
+
+ // 1.
+ if (
+ ArrayPrototypeFind(
+ keyUsages,
+ (u) => !ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u),
+ ) !== undefined
+ ) {
+ throw new DOMException("Invalid key usages", "SyntaxError");
+ }
+
+ // 2.
+ if (extractable !== false) {
+ throw new DOMException(
+ "Key must not be extractable",
+ "SyntaxError",
+ );
+ }
+
+ // 3.
+ const handle = {};
+ WeakMapPrototypeSet(KEY_STORE, handle, {
+ type: "raw",
+ data: keyData,
+ });
+
+ // 4-8.
+ const algorithm = {
+ name: "HKDF",
+ };
+ const key = constructKey(
+ "secret",
+ false,
+ usageIntersection(keyUsages, recognisedUsages),
+ algorithm,
+ handle,
+ );
+
+ // 9.
+ return key;
+ }
case "PBKDF2": {
// 1.
if (format !== "raw") {
@@ -1604,6 +1656,51 @@
return buf.buffer;
}
+ case "HKDF": {
+ // 1.
+ if (length === null || length === 0 || length % 8 !== 0) {
+ throw new DOMException("Invalid length", "OperationError");
+ }
+
+ const handle = baseKey[_handle];
+ const keyDerivationKey = WeakMapPrototypeGet(KEY_STORE, handle);
+
+ if (ArrayBufferIsView(normalizedAlgorithm.salt)) {
+ normalizedAlgorithm.salt = new Uint8Array(
+ normalizedAlgorithm.salt.buffer,
+ normalizedAlgorithm.salt.byteOffset,
+ normalizedAlgorithm.salt.byteLength,
+ );
+ } else {
+ normalizedAlgorithm.salt = new Uint8Array(normalizedAlgorithm.salt);
+ }
+ normalizedAlgorithm.salt = TypedArrayPrototypeSlice(
+ normalizedAlgorithm.salt,
+ );
+
+ if (ArrayBufferIsView(normalizedAlgorithm.info)) {
+ normalizedAlgorithm.info = new Uint8Array(
+ normalizedAlgorithm.info.buffer,
+ normalizedAlgorithm.info.byteOffset,
+ normalizedAlgorithm.info.byteLength,
+ );
+ } else {
+ normalizedAlgorithm.info = new Uint8Array(normalizedAlgorithm.info);
+ }
+ normalizedAlgorithm.info = TypedArrayPrototypeSlice(
+ normalizedAlgorithm.info,
+ );
+
+ const buf = await core.opAsync("op_crypto_derive_bits", {
+ key: keyDerivationKey,
+ algorithm: "HKDF",
+ hash: normalizedAlgorithm.hash.name,
+ info: normalizedAlgorithm.info,
+ length,
+ }, normalizedAlgorithm.salt);
+
+ return buf.buffer;
+ }
default:
throw new DOMException("Not implemented", "NotSupportedError");
}