diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-08-08 06:04:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-08 18:34:10 +0530 |
commit | 0d1beed2e3633d71d5e288e0382b85be361ec13d (patch) | |
tree | ed02258b19695bff1ab3ccaeafd78786406bb832 /ext/node/ops/crypto/cipher.rs | |
parent | 2f6da40bd609ebda8f30d748427d325d80e58274 (diff) |
fix(ext/node): add `CipherIv.setAutoPadding()` (#24940)
Co-Authored-By: Luca Casonato <hello@lcas.dev>
Fixes https://github.com/denoland/deno/issues/21804
Ref https://github.com/denoland/deno/issues/20924
---------
Signed-off-by: Divy Srivastava <dj.srivastava23@gmail.com>
Co-authored-by: Luca Casonato <hello@lcas.dev>
Diffstat (limited to 'ext/node/ops/crypto/cipher.rs')
-rw-r--r-- | ext/node/ops/crypto/cipher.rs | 123 |
1 files changed, 104 insertions, 19 deletions
diff --git a/ext/node/ops/crypto/cipher.rs b/ext/node/ops/crypto/cipher.rs index 1072cc8c0..0c1218d31 100644 --- a/ext/node/ops/crypto/cipher.rs +++ b/ext/node/ops/crypto/cipher.rs @@ -7,6 +7,7 @@ use aes::cipher::KeyIvInit; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::Resource; +use digest::generic_array::GenericArray; use digest::KeyInit; use std::borrow::Cow; @@ -65,13 +66,14 @@ impl CipherContext { pub fn r#final( self, + auto_pad: bool, input: &[u8], output: &mut [u8], ) -> Result<Tag, AnyError> { Rc::try_unwrap(self.cipher) .map_err(|_| type_error("Cipher context is already in use"))? .into_inner() - .r#final(input, output) + .r#final(auto_pad, input, output) } } @@ -92,6 +94,7 @@ impl DecipherContext { pub fn r#final( self, + auto_pad: bool, input: &[u8], output: &mut [u8], auth_tag: &[u8], @@ -99,7 +102,7 @@ impl DecipherContext { Rc::try_unwrap(self.decipher) .map_err(|_| type_error("Decipher context is already in use"))? .into_inner() - .r#final(input, output, auth_tag) + .r#final(auto_pad, input, output, auth_tag) } } @@ -209,42 +212,82 @@ impl Cipher { } /// r#final encrypts the last block of the input data. - fn r#final(self, input: &[u8], output: &mut [u8]) -> Result<Tag, AnyError> { + fn r#final( + self, + auto_pad: bool, + input: &[u8], + output: &mut [u8], + ) -> Result<Tag, AnyError> { assert!(input.len() < 16); use Cipher::*; - match self { - Aes128Cbc(encryptor) => { + match (self, auto_pad) { + (Aes128Cbc(encryptor), true) => { let _ = (*encryptor) .encrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot pad the input data"))?; Ok(None) } - Aes128Ecb(encryptor) => { + (Aes128Cbc(mut encryptor), false) => { + encryptor.encrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(None) + } + (Aes128Ecb(encryptor), true) => { let _ = (*encryptor) .encrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot pad the input data"))?; Ok(None) } - Aes192Ecb(encryptor) => { + (Aes128Ecb(mut encryptor), false) => { + encryptor.encrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(None) + } + (Aes192Ecb(encryptor), true) => { let _ = (*encryptor) .encrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot pad the input data"))?; Ok(None) } - Aes256Ecb(encryptor) => { + (Aes192Ecb(mut encryptor), false) => { + encryptor.encrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(None) + } + (Aes256Ecb(encryptor), true) => { let _ = (*encryptor) .encrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot pad the input data"))?; Ok(None) } - Aes128Gcm(cipher) => Ok(Some(cipher.finish().to_vec())), - Aes256Gcm(cipher) => Ok(Some(cipher.finish().to_vec())), - Aes256Cbc(encryptor) => { + (Aes256Ecb(mut encryptor), false) => { + encryptor.encrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(None) + } + (Aes128Gcm(cipher), _) => Ok(Some(cipher.finish().to_vec())), + (Aes256Gcm(cipher), _) => Ok(Some(cipher.finish().to_vec())), + (Aes256Cbc(encryptor), true) => { let _ = (*encryptor) .encrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot pad the input data"))?; Ok(None) } + (Aes256Cbc(mut encryptor), false) => { + encryptor.encrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(None) + } } } } @@ -345,41 +388,70 @@ impl Decipher { /// r#final decrypts the last block of the input data. fn r#final( self, + auto_pad: bool, input: &[u8], output: &mut [u8], auth_tag: &[u8], ) -> Result<(), AnyError> { use Decipher::*; - match self { - Aes128Cbc(decryptor) => { + match (self, auto_pad) { + (Aes128Cbc(decryptor), true) => { assert!(input.len() == 16); let _ = (*decryptor) .decrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot unpad the input data"))?; Ok(()) } - Aes128Ecb(decryptor) => { + (Aes128Cbc(mut decryptor), false) => { + decryptor.decrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(()) + } + (Aes128Ecb(decryptor), true) => { assert!(input.len() == 16); let _ = (*decryptor) .decrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot unpad the input data"))?; Ok(()) } - Aes192Ecb(decryptor) => { + (Aes128Ecb(mut decryptor), false) => { + decryptor.decrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(()) + } + (Aes192Ecb(decryptor), true) => { assert!(input.len() == 16); let _ = (*decryptor) .decrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot unpad the input data"))?; Ok(()) } - Aes256Ecb(decryptor) => { + (Aes192Ecb(mut decryptor), false) => { + decryptor.decrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(()) + } + (Aes256Ecb(decryptor), true) => { assert!(input.len() == 16); let _ = (*decryptor) .decrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot unpad the input data"))?; Ok(()) } - Aes128Gcm(decipher) => { + (Aes256Ecb(mut decryptor), false) => { + decryptor.decrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(()) + } + (Aes128Gcm(decipher), true) => { let tag = decipher.finish(); if tag.as_slice() == auth_tag { Ok(()) @@ -387,7 +459,10 @@ impl Decipher { Err(type_error("Failed to authenticate data")) } } - Aes256Gcm(decipher) => { + (Aes128Gcm(_), false) => Err(type_error( + "setAutoPadding(false) not supported for Aes256Gcm yet", + )), + (Aes256Gcm(decipher), true) => { let tag = decipher.finish(); if tag.as_slice() == auth_tag { Ok(()) @@ -395,13 +470,23 @@ impl Decipher { Err(type_error("Failed to authenticate data")) } } - Aes256Cbc(decryptor) => { + (Aes256Gcm(_), false) => Err(type_error( + "setAutoPadding(false) not supported for Aes256Gcm yet", + )), + (Aes256Cbc(decryptor), true) => { assert!(input.len() == 16); let _ = (*decryptor) .decrypt_padded_b2b_mut::<Pkcs7>(input, output) .map_err(|_| type_error("Cannot unpad the input data"))?; Ok(()) } + (Aes256Cbc(mut decryptor), false) => { + decryptor.decrypt_block_b2b_mut( + GenericArray::from_slice(input), + GenericArray::from_mut_slice(output), + ); + Ok(()) + } } } } |