diff options
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.ts | 103 |
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); + }, + }); + } +} |