diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/tests/unit/webcrypto_test.ts | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/cli/tests/unit/webcrypto_test.ts b/cli/tests/unit/webcrypto_test.ts index fec412937..c4958fbdf 100644 --- a/cli/tests/unit/webcrypto_test.ts +++ b/cli/tests/unit/webcrypto_test.ts @@ -1,4 +1,9 @@ -import { assert, assertEquals, assertRejects } from "./test_util.ts"; +import { + assert, + assertEquals, + assertNotEquals, + assertRejects, +} from "./test_util.ts"; // https://github.com/denoland/deno/issues/11664 Deno.test(async function testImportArrayBufferKey() { @@ -608,6 +613,110 @@ Deno.test(async function testAesCbcEncryptDecrypt() { assertEquals(new Uint8Array(decrypted), new Uint8Array([1, 2, 3, 4, 5, 6])); }); +Deno.test(async function testAesCtrEncryptDecrypt() { + async function aesCtrRoundTrip( + key: CryptoKey, + counter: Uint8Array, + length: number, + plainText: Uint8Array, + ) { + const cipherText = await crypto.subtle.encrypt( + { + name: "AES-CTR", + counter, + length, + }, + key, + plainText, + ); + + assert(cipherText instanceof ArrayBuffer); + assertEquals(cipherText.byteLength, plainText.byteLength); + assertNotEquals(new Uint8Array(cipherText), plainText); + + const decryptedText = await crypto.subtle.decrypt( + { + name: "AES-CTR", + counter, + length, + }, + key, + cipherText, + ); + + assert(decryptedText instanceof ArrayBuffer); + assertEquals(decryptedText.byteLength, plainText.byteLength); + assertEquals(new Uint8Array(decryptedText), plainText); + } + for (const keySize of [128, 192, 256]) { + const key = await crypto.subtle.generateKey( + { name: "AES-CTR", length: keySize }, + true, + ["encrypt", "decrypt"], + ) as CryptoKey; + + // test normal operation + for (const length of [128 /*, 64, 128 */]) { + const counter = await crypto.getRandomValues(new Uint8Array(16)); + + await aesCtrRoundTrip( + key, + counter, + length, + new Uint8Array([1, 2, 3, 4, 5, 6]), + ); + } + + // test counter-wrapping + for (const length of [32, 64, 128]) { + const plaintext1 = await crypto.getRandomValues(new Uint8Array(32)); + const counter = new Uint8Array(16); + + // fixed upper part + for (let off = 0; off < 16 - (length / 8); ++off) { + counter[off] = off; + } + const ciphertext1 = await crypto.subtle.encrypt( + { + name: "AES-CTR", + counter, + length, + }, + key, + plaintext1, + ); + + // Set lower [length] counter bits to all '1's + for (let off = 16 - (length / 8); off < 16; ++off) { + counter[off] = 0xff; + } + + // = [ 1 block of 0x00 + plaintext1 ] + const plaintext2 = new Uint8Array(48); + plaintext2.set(plaintext1, 16); + + const ciphertext2 = await crypto.subtle.encrypt( + { + name: "AES-CTR", + counter, + length, + }, + key, + plaintext2, + ); + + // If counter wrapped, 2nd block of ciphertext2 should be equal to 1st block of ciphertext1 + // since ciphertext1 used counter = 0x00...00 + // and ciphertext2 used counter = 0xFF..FF which should wrap to 0x00..00 without affecting + // higher bits + assertEquals( + new Uint8Array(ciphertext1), + new Uint8Array(ciphertext2).slice(16), + ); + } + } +}); + // TODO(@littledivy): Enable WPT when we have importKey support Deno.test(async function testECDH() { const namedCurve = "P-256"; |