summaryrefslogtreecommitdiff
path: root/cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-09-05 22:31:50 -0700
committerGitHub <noreply@github.com>2023-09-06 11:01:50 +0530
commit9befa566ec3ef4594fd7ffb2cbdf5b34d9705e16 (patch)
treeb70936cb5bb1e1f73a84ccf3dc9f5edfe085f7a3 /cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts
parenta0af53fea134f712408fa2d2d20078dd8ca7d0e6 (diff)
fix(ext/node): implement AES GCM cipher (#20368)
Adds support for AES-GCM 128/256 bit keys in `node:crypto` and `setAAD()`, `setAuthTag()` and `getAuthTag()` Uses https://github.com/littledivy/aead-gcm-stream Fixes https://github.com/denoland/deno/issues/19836 https://github.com/denoland/deno/issues/20353
Diffstat (limited to 'cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts')
-rw-r--r--cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts103
1 files changed, 103 insertions, 0 deletions
diff --git a/cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts b/cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts
new file mode 100644
index 000000000..e1ef44058
--- /dev/null
+++ b/cli/tests/unit_node/crypto/crypto_cipher_gcm_test.ts
@@ -0,0 +1,103 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+import crypto from "node:crypto";
+import { Buffer } from "node:buffer";
+import testVectors128 from "./gcmEncryptExtIV128.json" assert { type: "json" };
+import testVectors256 from "./gcmEncryptExtIV256.json" assert { type: "json" };
+import { assertEquals } from "../../../../test_util/std/testing/asserts.ts";
+
+const aesGcm = (bits: string, key: Uint8Array) => {
+ const ALGO = bits == "128" ? `aes-128-gcm` : `aes-256-gcm`;
+
+ // encrypt returns base64-encoded ciphertext
+ const encrypt = (
+ iv: Uint8Array,
+ str: string,
+ aad: Uint8Array,
+ ): [string, Buffer] => {
+ const cipher = crypto.createCipheriv(ALGO, key, iv);
+ cipher.setAAD(aad);
+ let enc = cipher.update(str, "base64", "base64");
+ enc += cipher.final("base64");
+ return [enc, cipher.getAuthTag()];
+ };
+
+ const decrypt = (
+ enc: string,
+ iv: Uint8Array,
+ aad: Uint8Array,
+ authTag: Uint8Array,
+ ) => {
+ const decipher = crypto.createDecipheriv(ALGO, key, iv);
+ decipher.setAuthTag(authTag);
+ decipher.setAAD(aad);
+ let str = decipher.update(enc, "base64", "base64");
+ str += decipher.final("base64");
+
+ return str;
+ };
+
+ return {
+ encrypt,
+ decrypt,
+ };
+};
+
+type TestVector = {
+ key: Uint8Array;
+ nonce: Uint8Array;
+ aad: Uint8Array;
+ plaintext: string;
+ ciphertext: string;
+ tag: Uint8Array;
+};
+
+for (
+ // NIST CAVS vectors
+ const [bits, vectors] of Object.entries({
+ // <https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES>
+ //
+ // From: `gcmEncryptExtIV128.rsp`
+ 128: testVectors128,
+ // <https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES>
+ //
+ // From: `gcmEncryptExtIV256.rsp`
+ 256: testVectors256,
+ })
+) {
+ for (let i = 0; i < vectors.length; i++) {
+ const rawTest = vectors[i];
+ const test: TestVector = {
+ key: new Uint8Array(rawTest.key),
+ nonce: new Uint8Array(rawTest.nonce),
+ aad: new Uint8Array(rawTest.aad),
+ plaintext: Buffer.from(rawTest.plaintext).toString("base64"),
+ ciphertext: Buffer.from(rawTest.ciphertext).toString("base64"),
+ tag: new Uint8Array(rawTest.tag),
+ };
+
+ Deno.test({
+ name: `aes-${bits}-gcm encrypt ${i + 1}/${vectors.length}`,
+ fn() {
+ const cipher = aesGcm(bits, test.key);
+ const [enc, tag] = cipher.encrypt(test.nonce, test.plaintext, test.aad);
+ assertEquals(enc, test.ciphertext);
+ assertEquals(new Uint8Array(tag), test.tag);
+ },
+ });
+
+ Deno.test({
+ name: `aes-${bits}-gcm decrypt ${i + 1}/${vectors.length}`,
+ fn() {
+ const cipher = aesGcm(bits, test.key);
+ const plaintext = cipher.decrypt(
+ test.ciphertext,
+ test.nonce,
+ test.aad,
+ test.tag,
+ );
+ assertEquals(plaintext, test.plaintext);
+ },
+ });
+ }
+}