From c45d0dadb32144201dc181211e56b6bddecccded Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Fri, 27 Dec 2024 17:46:01 +0900 Subject: [PATCH] fix(ext/node): add support of any length IV for aes-(128|256)-gcm ciphers (#27476) --- Cargo.lock | 4 +- ext/node/Cargo.toml | 2 +- ext/node/ops/crypto/cipher.rs | 16 - .../crypto/crypto_cipher_gcm_test.ts | 20 + .../unit_node/crypto/gcmEncryptExtIV128.json | 317 ++++++++++++++++ .../unit_node/crypto/gcmEncryptExtIV256.json | 349 ++++++++++++++++++ 6 files changed, 689 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bb0cfb18e..5e86a7647c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "aead-gcm-stream" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4947a169074c7e038fa43051d1c4e073f4488b0e4b0a30658f1e1a1b06449ce8" +checksum = "e70c8dec860340effb00f6945c49c0daaa6dac963602750db862eabb74bf7886" dependencies = [ "aead", "aes", diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 60e7c96a08..50e72dfcbe 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -17,7 +17,7 @@ path = "lib.rs" sync_fs = ["deno_package_json/sync", "node_resolver/sync"] [dependencies] -aead-gcm-stream = "0.3" +aead-gcm-stream = "0.4" aes.workspace = true async-trait.workspace = true base64.workspace = true diff --git a/ext/node/ops/crypto/cipher.rs b/ext/node/ops/crypto/cipher.rs index 16e32a34af..7f5b108a04 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -179,20 +179,12 @@ impl Cipher { "aes-192-ecb" => Aes192Ecb(Box::new(ecb::Encryptor::new(key.into()))), "aes-256-ecb" => Aes256Ecb(Box::new(ecb::Encryptor::new(key.into()))), "aes-128-gcm" => { - if iv.len() != 12 { - return Err(CipherError::InvalidIvLength); - } - let cipher = aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes128Gcm(Box::new(cipher)) } "aes-256-gcm" => { - if iv.len() != 12 { - return Err(CipherError::InvalidIvLength); - } - let cipher = aead_gcm_stream::AesGcm::::new(key.into(), iv); @@ -395,20 +387,12 @@ impl Decipher { "aes-192-ecb" => Aes192Ecb(Box::new(ecb::Decryptor::new(key.into()))), "aes-256-ecb" => Aes256Ecb(Box::new(ecb::Decryptor::new(key.into()))), "aes-128-gcm" => { - if iv.len() != 12 { - return Err(DecipherError::InvalidIvLength); - } - let decipher = aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes128Gcm(Box::new(decipher)) } "aes-256-gcm" => { - if iv.len() != 12 { - return Err(DecipherError::InvalidIvLength); - } - let decipher = aead_gcm_stream::AesGcm::::new(key.into(), iv); diff --git a/tests/unit_node/crypto/crypto_cipher_gcm_test.ts b/tests/unit_node/crypto/crypto_cipher_gcm_test.ts index b379a43696..16f6f56a9c 100644 --- a/tests/unit_node/crypto/crypto_cipher_gcm_test.ts +++ b/tests/unit_node/crypto/crypto_cipher_gcm_test.ts @@ -119,3 +119,23 @@ Deno.test({ ); }, }); + +// Issue #27441 +// https://github.com/denoland/deno/issues/27441 +Deno.test({ + name: "aes-256-gcm supports IV of non standard length", + fn() { + const decipher = crypto.createDecipheriv( + "aes-256-gcm", + Buffer.from("eYLEiLFQnpjYksWTiKpwv2sKhw+WJb5Fo/aY2YqXswc=", "base64"), + Buffer.from("k5oP3kb8tTbZaL3PxbFWN8ToOb8vfv2b1EuPz1LbmYU=", "base64"), // 256 bits IV + ); + const decrypted = decipher.update( + "s0/KBsFec29XLrGbAnLiNA==", + "base64", + "utf-8", + ); + assertEquals(decrypted, "this is a secret"); + decipher.final(); + }, +}); diff --git a/tests/unit_node/crypto/gcmEncryptExtIV128.json b/tests/unit_node/crypto/gcmEncryptExtIV128.json index 64896642d4..f0b4bca1f1 100644 --- a/tests/unit_node/crypto/gcmEncryptExtIV128.json +++ b/tests/unit_node/crypto/gcmEncryptExtIV128.json @@ -51373,5 +51373,322 @@ 102, 238 ] + }, + { + "key": [ + 131, + 249, + 217, + 125, + 74, + 183, + 89, + 253, + 220, + 195, + 239, + 84, + 160, + 226, + 168, + 236 + ], + "nonce": [ + 207 + ], + "aad": [ + 109, + 212, + 158, + 174, + 180, + 16, + 61, + 172, + 143, + 151, + 227, + 35, + 73, + 70, + 221, + 45 + ], + "plaintext": [ + 119, + 230, + 50, + 156, + 249, + 66, + 79, + 113, + 200, + 8, + 223, + 145, + 112, + 191, + 210, + 152 + ], + "ciphertext": [ + 80, + 222, + 134, + 167, + 169, + 42, + 138, + 94, + 163, + 61, + 181, + 105, + 107, + 150, + 205, + 119 + ], + "tag": [ + 170, + 24, + 30, + 132, + 188, + 139, + 75, + 245, + 166, + 137, + 39, + 196, + 9, + 212, + 34, + 203 + ] + }, + { + "key": [ + 202, + 145, + 226, + 65, + 68, + 9, + 164, + 57, + 176, + 101, + 115, + 215, + 114, + 249, + 10, + 251 + ], + "nonce": [ + 23, + 112, + 8, + 249, + 32, + 160, + 97, + 105, + 204, + 223, + 117, + 58, + 51, + 133, + 83, + 254, + 253, + 70, + 132, + 88, + 105, + 201, + 36, + 77, + 164, + 73, + 151, + 248, + 61, + 76, + 232, + 5, + 161, + 135, + 7, + 200, + 77, + 17, + 79, + 156, + 104, + 66, + 123, + 34, + 132, + 21, + 145, + 230, + 202, + 236, + 245, + 195, + 231, + 42, + 37, + 22, + 122, + 168, + 96, + 197, + 27, + 220, + 26, + 165, + 109, + 205, + 105, + 242, + 154, + 47, + 53, + 231, + 10, + 50, + 43, + 158, + 186, + 9, + 42, + 152, + 214, + 106, + 149, + 107, + 77, + 41, + 67, + 131, + 160, + 235, + 171, + 38, + 247, + 196, + 223, + 26, + 93, + 64, + 96, + 223, + 196, + 90, + 20, + 21, + 81, + 0, + 234, + 125, + 158, + 50, + 222, + 187, + 101, + 55, + 64, + 107, + 117, + 114, + 145, + 113, + 5, + 5, + 20, + 46, + 118, + 89, + 252, + 119 + ], + "aad": [ + 191, + 235, + 21, + 252, + 247, + 177, + 95, + 14, + 20, + 192, + 68, + 57, + 182, + 121, + 80, + 189 + ], + "plaintext": [ + 40, + 0, + 62, + 48, + 196, + 164, + 202, + 158, + 65, + 170, + 254, + 250, + 193, + 225, + 195, + 222 + ], + "ciphertext": [ + 0, + 228, + 114, + 151, + 31, + 58, + 119, + 112, + 170, + 113, + 88, + 253, + 146, + 241, + 123, + 183 + ], + "tag": [ + 22, + 102, + 27, + 133, + 235, + 81, + 100, + 108, + 148, + 207, + 43, + 228, + 228, + 45, + 122, + 142 + ] } ] diff --git a/tests/unit_node/crypto/gcmEncryptExtIV256.json b/tests/unit_node/crypto/gcmEncryptExtIV256.json index cb8ba30869..808c47ec6e 100644 --- a/tests/unit_node/crypto/gcmEncryptExtIV256.json +++ b/tests/unit_node/crypto/gcmEncryptExtIV256.json @@ -57373,5 +57373,354 @@ 246, 57 ] + }, + { + "key": [ + 187, + 70, + 53, + 215, + 102, + 221, + 14, + 74, + 112, + 25, + 209, + 114, + 76, + 115, + 110, + 31, + 44, + 1, + 106, + 249, + 226, + 158, + 125, + 58, + 162, + 192, + 222, + 35, + 231, + 128, + 175, + 38 + ], + "nonce": [ + 171 + ], + "aad": [ + 15, + 133, + 199, + 219, + 235, + 103, + 75, + 122, + 112, + 195, + 81, + 37, + 211, + 97, + 147, + 80 + ], + "plaintext": [ + 208, + 92, + 232, + 120, + 217, + 70, + 98, + 209, + 82, + 11, + 24, + 75, + 75, + 239, + 60, + 69 + ], + "ciphertext": [ + 81, + 186, + 162, + 106, + 106, + 113, + 156, + 22, + 0, + 100, + 95, + 243, + 191, + 223, + 165, + 59 + ], + "tag": [ + 107, + 213, + 78, + 81, + 132, + 235, + 48, + 9, + 52, + 179, + 146, + 195, + 43, + 124, + 26, + 110 + ] + }, + { + "key": [ + 252, + 188, + 126, + 182, + 39, + 22, + 220, + 127, + 121, + 43, + 97, + 148, + 210, + 109, + 109, + 86, + 158, + 174, + 224, + 122, + 157, + 60, + 55, + 202, + 66, + 133, + 64, + 144, + 102, + 30, + 24, + 69 + ], + "nonce": [ + 76, + 140, + 70, + 36, + 39, + 155, + 35, + 180, + 149, + 199, + 136, + 132, + 76, + 118, + 210, + 37, + 235, + 242, + 56, + 38, + 89, + 156, + 62, + 28, + 244, + 219, + 29, + 162, + 214, + 90, + 127, + 117, + 68, + 216, + 232, + 111, + 204, + 51, + 251, + 17, + 61, + 49, + 116, + 184, + 199, + 144, + 49, + 34, + 203, + 89, + 103, + 246, + 16, + 115, + 130, + 204, + 90, + 198, + 231, + 160, + 228, + 202, + 79, + 8, + 222, + 62, + 145, + 29, + 72, + 62, + 104, + 37, + 61, + 63, + 136, + 108, + 254, + 52, + 155, + 249, + 50, + 153, + 162, + 142, + 102, + 91, + 192, + 150, + 165, + 28, + 232, + 76, + 230, + 148, + 11, + 52, + 160, + 55, + 114, + 36, + 131, + 185, + 106, + 123, + 37, + 80, + 127, + 90, + 4, + 100, + 60, + 103, + 48, + 250, + 170, + 182, + 24, + 230, + 35, + 26, + 114, + 119, + 20, + 214, + 243, + 102, + 250, + 155 + ], + "aad": [ + 60, + 24, + 42, + 241, + 156, + 70, + 255, + 74, + 203, + 218, + 206, + 207, + 112, + 180, + 47, + 181 + ], + "plaintext": [ + 34, + 20, + 79, + 193, + 47, + 123, + 197, + 82, + 43, + 136, + 183, + 108, + 141, + 237, + 28, + 118 + ], + "ciphertext": [ + 200, + 217, + 129, + 7, + 192, + 203, + 60, + 15, + 210, + 24, + 154, + 233, + 114, + 128, + 213, + 98 + ], + "tag": [ + 41, + 6, + 119, + 35, + 48, + 236, + 217, + 163, + 184, + 168, + 40, + 118, + 164, + 235, + 222, + 234 + ] } ]