diff --git a/ext/node/ops/crypto/cipher.rs b/ext/node/ops/crypto/cipher.rs index 3d116c68e6..02e9777d88 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -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::(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::(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::(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::(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::(input, output) .map_err(|_| DecipherError::CannotUnpadInputData)?; diff --git a/tests/unit_node/crypto/crypto_cipher_test.ts b/tests/unit_node/crypto/crypto_cipher_test.ts index 64ff65078e..2c672fcdd5 100644 --- a/tests/unit_node/crypto/crypto_cipher_test.ts +++ b/tests/unit_node/crypto/crypto_cipher_test.ts @@ -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", + ); + }, +});