Repository: denoland/deno
Pull request: fix(ext/node): decipherIv() range error on invalid final block length

Fixes https://github.com/denoland/deno/issues/28208

Changed files:
filename: ext/node/ops/crypto/cipher.rs
patch: @@ -424,6 +424,9 @@ pub enum DecipherError {
   #[class(range)]
   #[error("Invalid key length")]
   InvalidKeyLength,
+  #[class(range)]
+  #[error("Wrong final block length")]
+  InvalidFinalBlockLength,
   #[class(type)]
   #[error("Invalid initialization vector")]
   InvalidInitializationVector,
@@ -444,6 +447,14 @@ pub enum DecipherError {
   UnknownCipher(String),
 }
 
+macro_rules! assert_block_len {
+  ($input:expr, $len:expr) => {
+    if $input != $len {
+      return Err(DecipherError::InvalidFinalBlockLength);
+    }
+  };
+}
+
 impl Decipher {
   fn new(
     algorithm_name: &str,
@@ -604,7 +615,7 @@ impl Decipher {
 
     match (self, auto_pad) {
       (Aes128Cbc(decryptor), true) => {
-        assert!(input.len() == 16);
+        assert_block_len!(input.len(), 16);
         let _ = (*decryptor)
           .decrypt_padded_b2b_mut::<Pkcs7>(input, output)
           .map_err(|_| DecipherError::CannotUnpadInputData)?;
@@ -618,7 +629,7 @@ impl Decipher {
         Ok(())
       }
       (Aes128Ecb(decryptor), true) => {
-        assert!(input.len() == 16);
+        assert_block_len!(input.len(), 16);
         let _ = (*decryptor)
           .decrypt_padded_b2b_mut::<Pkcs7>(input, output)
           .map_err(|_| DecipherError::CannotUnpadInputData)?;
@@ -632,7 +643,7 @@ impl Decipher {
         Ok(())
       }
       (Aes192Ecb(decryptor), true) => {
-        assert!(input.len() == 16);
+        assert_block_len!(input.len(), 16);
         let _ = (*decryptor)
           .decrypt_padded_b2b_mut::<Pkcs7>(input, output)
           .map_err(|_| DecipherError::CannotUnpadInputData)?;
@@ -646,7 +657,7 @@ impl Decipher {
         Ok(())
       }
       (Aes256Ecb(decryptor), true) => {
-        assert!(input.len() == 16);
+        assert_block_len!(input.len(), 16);
         let _ = (*decryptor)
           .decrypt_padded_b2b_mut::<Pkcs7>(input, output)
           .map_err(|_| DecipherError::CannotUnpadInputData)?;
@@ -682,7 +693,7 @@ impl Decipher {
         Err(DecipherError::SetAutoPaddingFalseAes256GcmUnsupported)
       }
       (Aes256Cbc(decryptor), true) => {
-        assert!(input.len() == 16);
+        assert_block_len!(input.len(), 16);
         let _ = (*decryptor)
           .decrypt_padded_b2b_mut::<Pkcs7>(input, output)
           .map_err(|_| DecipherError::CannotUnpadInputData)?;

filename: tests/unit_node/crypto/crypto_cipher_test.ts
patch: @@ -447,3 +447,25 @@ Deno.test({
     }
   },
 });
+
+Deno.test({
+  name: "createDecipheriv - invalid final block len",
+  fn() {
+    const algorithm = "aes-256-cbc";
+    const key = Buffer.from(
+      "84dcdd964968734fdf0de4a2cba471c2e0a753930b841c014b1e77f456b5797b",
+      "hex",
+    );
+    const iv = Buffer.alloc(16, 0);
+
+    const decipher = crypto.createDecipheriv(algorithm, key, iv);
+    decipher.update(Buffer.alloc(12));
+    assertThrows(
+      () => {
+        decipher.final();
+      },
+      RangeError,
+      "Wrong final block length",
+    );
+  },
+});