diff options
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r-- | ext/crypto/00_crypto.js | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 1f49d1849..81c475ad7 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -133,6 +133,7 @@ "decrypt": { "RSA-OAEP": "RsaOaepParams", "AES-CBC": "AesCbcParams", + "AES-GCM": "AesGcmParams", "AES-CTR": "AesCtrParams", }, "get key length": { @@ -631,6 +632,66 @@ // 4. return cipherText.buffer; } + case "AES-GCM": { + normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv); + + // 1. + if (normalizedAlgorithm.tagLength === undefined) { + normalizedAlgorithm.tagLength = 128; + } else if ( + !ArrayPrototypeIncludes( + [32, 64, 96, 104, 112, 120, 128], + normalizedAlgorithm.tagLength, + ) + ) { + throw new DOMException( + "Invalid tag length", + "OperationError", + ); + } + + // 2. + if (data.byteLength < normalizedAlgorithm.tagLength / 8) { + throw new DOMException( + "Tag length overflows ciphertext", + "OperationError", + ); + } + + // 3. We only support 96-bit nonce for now. + if (normalizedAlgorithm.iv.byteLength !== 12) { + throw new DOMException( + "Initialization vector length not supported", + "NotSupportedError", + ); + } + + // 4. + if (normalizedAlgorithm.additionalData !== undefined) { + if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) { + throw new DOMException( + "Additional data too large", + "OperationError", + ); + } + normalizedAlgorithm.additionalData = copyBuffer( + normalizedAlgorithm.additionalData, + ); + } + + // 5-8. + const plaintext = await core.opAsync("op_crypto_decrypt", { + key: keyData, + algorithm: "AES-GCM", + length: key[_algorithm].length, + iv: normalizedAlgorithm.iv, + additionalData: normalizedAlgorithm.additionalData, + tagLength: normalizedAlgorithm.tagLength, + }, data); + + // 9. + return plaintext.buffer; + } default: throw new DOMException("Not implemented", "NotSupportedError"); } |