summaryrefslogtreecommitdiff
path: root/ext/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'ext/crypto')
-rw-r--r--ext/crypto/00_crypto.js78
-rw-r--r--ext/crypto/01_webidl.js13
-rw-r--r--ext/crypto/lib.rs12
3 files changed, 99 insertions, 4 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index ab6347d41..354654077 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -77,6 +77,10 @@
"RSA-PSS": "RsaHashedKeyGenParams",
"RSA-OAEP": "RsaHashedKeyGenParams",
"ECDSA": "EcKeyGenParams",
+ "AES-CTR": "AesKeyGenParams",
+ "AES-CBC": "AesKeyGenParams",
+ "AES-GCM": "AesKeyGenParams",
+ "AES-KW": "AesKeyGenParams",
"HMAC": "HmacKeyGenParams",
},
"sign": {
@@ -1415,10 +1419,40 @@
return { publicKey, privateKey };
}
// TODO(lucacasonato): ECDH
- // TODO(lucacasonato): AES-CTR
- // TODO(lucacasonato): AES-CBC
- // TODO(lucacasonato): AES-GCM
- // TODO(lucacasonato): AES-KW
+ case "AES-CTR":
+ case "AES-CBC":
+ case "AES-GCM": {
+ // 1.
+ if (
+ ArrayPrototypeFind(
+ usages,
+ (u) =>
+ !ArrayPrototypeIncludes([
+ "encrypt",
+ "decrypt",
+ "wrapKey",
+ "unwrapKey",
+ ], u),
+ ) !== undefined
+ ) {
+ throw new DOMException("Invalid key usages", "SyntaxError");
+ }
+
+ return generateKeyAES(normalizedAlgorithm, extractable, usages);
+ }
+ case "AES-KW": {
+ // 1.
+ if (
+ ArrayPrototypeFind(
+ usages,
+ (u) => !ArrayPrototypeIncludes(["wrapKey", "unwrapKey"], u),
+ ) !== undefined
+ ) {
+ throw new DOMException("Invalid key usages", "SyntaxError");
+ }
+
+ return generateKeyAES(normalizedAlgorithm, extractable, usages);
+ }
case "HMAC": {
// 1.
if (
@@ -1473,6 +1507,42 @@
}
}
+ async function generateKeyAES(normalizedAlgorithm, extractable, usages) {
+ // 2.
+ if (!ArrayPrototypeIncludes([128, 192, 256], normalizedAlgorithm.length)) {
+ throw new DOMException("Invalid key length", "OperationError");
+ }
+
+ // 3.
+ const keyData = await core.opAsync("op_crypto_generate_key", {
+ name: normalizedAlgorithm.name,
+ length: normalizedAlgorithm.length,
+ });
+ const handle = {};
+ WeakMapPrototypeSet(KEY_STORE, handle, {
+ type: "raw",
+ data: keyData,
+ });
+
+ // 6-8.
+ const algorithm = {
+ name: normalizedAlgorithm.name,
+ length: normalizedAlgorithm.length,
+ };
+
+ // 9-11.
+ const key = constructKey(
+ "secret",
+ extractable,
+ usages,
+ algorithm,
+ handle,
+ );
+
+ // 12.
+ return key;
+ }
+
async function deriveBits(normalizedAlgorithm, baseKey, length) {
switch (normalizedAlgorithm.name) {
case "PBKDF2": {
diff --git a/ext/crypto/01_webidl.js b/ext/crypto/01_webidl.js
index e781e4334..3ef3eb175 100644
--- a/ext/crypto/01_webidl.js
+++ b/ext/crypto/01_webidl.js
@@ -117,6 +117,19 @@
webidl.converters.EcKeyGenParams = webidl
.createDictionaryConverter("EcKeyGenParams", dictEcKeyGenParams);
+ const dictAesKeyGenParams = [
+ ...dictAlgorithm,
+ {
+ key: "length",
+ converter: (V, opts) =>
+ webidl.converters["unsigned short"](V, { ...opts, enforceRange: true }),
+ required: true,
+ },
+ ];
+
+ webidl.converters.AesKeyGenParams = webidl
+ .createDictionaryConverter("AesKeyGenParams", dictAesKeyGenParams);
+
const dictHmacKeyGenParams = [
...dictAlgorithm,
{
diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs
index b68bd7887..7c4010f53 100644
--- a/ext/crypto/lib.rs
+++ b/ext/crypto/lib.rs
@@ -180,6 +180,18 @@ pub async fn op_crypto_generate_key(
private_key
}
+ Algorithm::AesCtr
+ | Algorithm::AesCbc
+ | Algorithm::AesGcm
+ | Algorithm::AesKw => {
+ let length = args.length.ok_or_else(not_supported)?;
+ let mut key_data = vec![0u8; length];
+ let rng = RingRand::SystemRandom::new();
+ rng.fill(&mut key_data).map_err(|_| {
+ custom_error("DOMExceptionOperationError", "Key generation failed")
+ })?;
+ key_data
+ }
Algorithm::Hmac => {
let hash: HmacAlgorithm = args.hash.ok_or_else(not_supported)?.into();