Repository: denoland/deno
Pull request: fix(ext/node): add key/IV length validation for aes-128-cbc and ecb cipher modes

Validate key and IV lengths for aes-128-cbc, aes-128-ecb, aes-192-ecb, and aes-256-ecb before constructing ciphers, matching the pattern already used by aes-256-cbc, ctr, and gcm modes.

Changed files:
filename: ext/node_crypto/cipher.rs
patch: @@ -221,11 +221,32 @@ impl Cipher {
     use Cipher::*;
     Ok(match algorithm_name {
       "aes128" | "aes-128-cbc" => {
+        if key.len() != 16 {
+          return Err(CipherError::InvalidKeyLength);
+        }
+        if iv.len() != 16 {
+          return Err(CipherError::InvalidInitializationVector);
+        }
         Aes128Cbc(Box::new(cbc::Encryptor::new(key.into(), iv.into())))
       }
-      "aes-128-ecb" => Aes128Ecb(Box::new(ecb::Encryptor::new(key.into()))),
-      "aes-192-ecb" => Aes192Ecb(Box::new(ecb::Encryptor::new(key.into()))),
-      "aes-256-ecb" => Aes256Ecb(Box::new(ecb::Encryptor::new(key.into()))),
+      "aes-128-ecb" => {
+        if key.len() != 16 {
+          return Err(CipherError::InvalidKeyLength);
+        }
+        Aes128Ecb(Box::new(ecb::Encryptor::new(key.into())))
+      }
+      "aes-192-ecb" => {
+        if key.len() != 24 {
+          return Err(CipherError::InvalidKeyLength);
+        }
+        Aes192Ecb(Box::new(ecb::Encryptor::new(key.into())))
+      }
+      "aes-256-ecb" => {
+        if key.len() != 32 {
+          return Err(CipherError::InvalidKeyLength);
+        }
+        Aes256Ecb(Box::new(ecb::Encryptor::new(key.into())))
+      }
       "aes-128-gcm" => {
         if key.len() != aes::Aes128::key_size() {
           return Err(CipherError::InvalidKeyLength);
@@ -593,11 +614,32 @@ impl Decipher {
     use Decipher::*;
     Ok(match algorithm_name {
       "aes-128-cbc" => {
+        if key.len() != 16 {
+          return Err(DecipherError::InvalidKeyLength);
+        }
+        if iv.len() != 16 {
+          return Err(DecipherError::InvalidInitializationVector);
+        }
         Aes128Cbc(Box::new(cbc::Decryptor::new(key.into(), iv.into())))
       }
-      "aes-128-ecb" => Aes128Ecb(Box::new(ecb::Decryptor::new(key.into()))),
-      "aes-192-ecb" => Aes192Ecb(Box::new(ecb::Decryptor::new(key.into()))),
-      "aes-256-ecb" => Aes256Ecb(Box::new(ecb::Decryptor::new(key.into()))),
+      "aes-128-ecb" => {
+        if key.len() != 16 {
+          return Err(DecipherError::InvalidKeyLength);
+        }
+        Aes128Ecb(Box::new(ecb::Decryptor::new(key.into())))
+      }
+      "aes-192-ecb" => {
+        if key.len() != 24 {
+          return Err(DecipherError::InvalidKeyLength);
+        }
+        Aes192Ecb(Box::new(ecb::Decryptor::new(key.into())))
+      }
+      "aes-256-ecb" => {
+        if key.len() != 32 {
+          return Err(DecipherError::InvalidKeyLength);
+        }
+        Aes256Ecb(Box::new(ecb::Decryptor::new(key.into())))
+      }
       "aes-128-gcm" => {
         if key.len() != aes::Aes128::key_size() {
           return Err(DecipherError::InvalidKeyLength);

filename: tests/unit_node/crypto/crypto_cipher_test.ts
patch: @@ -318,10 +318,17 @@ Deno.test({
       Iv,
     }
     const table = [
+      ["aes128", 15, 16, Invalid.Key],
+      ["aes-128-cbc", 15, 16, Invalid.Key],
+      ["aes128", 16, 15, Invalid.Iv],
+      ["aes-128-cbc", 16, 15, Invalid.Iv],
       ["aes256", 31, 16, Invalid.Key],
       ["aes-256-cbc", 31, 16, Invalid.Key],
       ["aes256", 32, 15, Invalid.Iv],
       ["aes-256-cbc", 32, 15, Invalid.Iv],
+      ["aes-128-ecb", 15, 0, Invalid.Key],
+      ["aes-192-ecb", 16, 0, Invalid.Key],
+      ["aes-256-ecb", 16, 0, Invalid.Key],
       ["aes-128-ctr", 32, 16, Invalid.Key],
       ["aes-128-ctr", 16, 32, Invalid.Iv],
       ["aes-192-ctr", 16, 16, Invalid.Key],
@@ -366,10 +373,15 @@ Deno.test({
       Iv,
     }
     const table = [
+      ["aes-128-cbc", 15, 16, Invalid.Key],
+      ["aes-128-cbc", 16, 15, Invalid.Iv],
       ["aes256", 31, 16, Invalid.Key],
       ["aes-256-cbc", 31, 16, Invalid.Key],
       ["aes256", 32, 15, Invalid.Iv],
       ["aes-256-cbc", 32, 15, Invalid.Iv],
+      ["aes-128-ecb", 15, 0, Invalid.Key],
+      ["aes-192-ecb", 16, 0, Invalid.Key],
+      ["aes-256-ecb", 16, 0, Invalid.Key],
       ["aes-128-ctr", 32, 16, Invalid.Key],
       ["aes-128-ctr", 16, 32, Invalid.Iv],
       ["aes-192-ctr", 16, 16, Invalid.Key],