diff --git a/Cargo.lock b/Cargo.lock index d97b04d4aa40d1..ba81c1ee3ad5e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "aead-gcm-stream" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a09ecb526d53de2842cc876ee5c9b51161ee60399edeca4cf74892a01b48177" +checksum = "4947a169074c7e038fa43051d1c4e073f4488b0e4b0a30658f1e1a1b06449ce8" dependencies = [ "aead", "aes", diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 800b8f591c526f..ce97149545d2a6 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.1" +aead-gcm-stream = "0.3" 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 ca13fdcd8fa5a0..94bd5780eb409f 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -137,16 +137,22 @@ 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" => { - let mut cipher = - aead_gcm_stream::AesGcm::::new(key.into()); - cipher.init(iv.try_into()?); + if iv.len() != 12 { + return Err(type_error("IV length must be 12 bytes")); + } + + let cipher = + aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes128Gcm(Box::new(cipher)) } "aes-256-gcm" => { - let mut cipher = - aead_gcm_stream::AesGcm::::new(key.into()); - cipher.init(iv.try_into()?); + if iv.len() != 12 { + return Err(type_error("IV length must be 12 bytes")); + } + + let cipher = + aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes256Gcm(Box::new(cipher)) } @@ -320,16 +326,22 @@ 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" => { - let mut decipher = - aead_gcm_stream::AesGcm::::new(key.into()); - decipher.init(iv.try_into()?); + if iv.len() != 12 { + return Err(type_error("IV length must be 12 bytes")); + } + + let decipher = + aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes128Gcm(Box::new(decipher)) } "aes-256-gcm" => { - let mut decipher = - aead_gcm_stream::AesGcm::::new(key.into()); - decipher.init(iv.try_into()?); + if iv.len() != 12 { + return Err(type_error("IV length must be 12 bytes")); + } + + let decipher = + aead_gcm_stream::AesGcm::::new(key.into(), iv); Aes256Gcm(Box::new(decipher)) } diff --git a/tests/unit_node/crypto/crypto_cipher_gcm_test.ts b/tests/unit_node/crypto/crypto_cipher_gcm_test.ts index e87ae23f017380..b379a43696bf0b 100644 --- a/tests/unit_node/crypto/crypto_cipher_gcm_test.ts +++ b/tests/unit_node/crypto/crypto_cipher_gcm_test.ts @@ -101,3 +101,21 @@ for ( }); } } + +Deno.test({ + name: "aes-128-gcm encrypt multiple", + fn() { + const key = Buffer.alloc(16); + const nonce = Buffer.alloc(12); + + const gcm = crypto.createCipheriv("aes-128-gcm", key, nonce); + + assertEquals(gcm.update("hello", "utf8", "hex"), "6bedb6a20f"); + assertEquals(gcm.update("world", "utf8", "hex"), "c1cce09f4c"); + gcm.final(); + assertEquals( + gcm.getAuthTag().toString("hex"), + "bf6d20a38e0c828bea3de63b7ff1dfbd", + ); + }, +});