summaryrefslogtreecommitdiff
path: root/ext/node/ops/crypto/cipher.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2024-08-08 06:04:10 -0700
committerGitHub <noreply@github.com>2024-08-08 18:34:10 +0530
commit0d1beed2e3633d71d5e288e0382b85be361ec13d (patch)
treeed02258b19695bff1ab3ccaeafd78786406bb832 /ext/node/ops/crypto/cipher.rs
parent2f6da40bd609ebda8f30d748427d325d80e58274 (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.rs123
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(())
+ }
}
}
}