summaryrefslogtreecommitdiff
path: root/ext/crypto/00_crypto.js
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2021-09-12 02:24:03 +0530
committerGitHub <noreply@github.com>2021-09-11 16:54:03 -0400
commit0cb22d4cba76cf86486db3d311a6a4c61b93d953 (patch)
tree41364e69b146a4bd413bd2e3e400e3f984a596df /ext/crypto/00_crypto.js
parent40c63d1255642b8d70d7b5ce5b85a50f6af8a00d (diff)
feat(ext/crypto): implement HKDF operations (#11865)
Co-authored-by: Luca Casonato <lucacasonato@yahoo.com>
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");
}