diff --git a/Cargo.lock b/Cargo.lock index eb9acff68..4a2bbacf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1036,6 +1036,7 @@ dependencies = [ name = "pkcs5" version = "0.8.1" dependencies = [ + "aead", "aes", "aes-gcm", "cbc", diff --git a/pkcs5/Cargo.toml b/pkcs5/Cargo.toml index bb2338d6e..cc5342665 100644 --- a/pkcs5/Cargo.toml +++ b/pkcs5/Cargo.toml @@ -20,6 +20,7 @@ der = { version = "0.8", features = ["oid"] } spki = "0.8" # optional dependencies +aead = { version = "0.6", default-features = false, optional = true } cbc = { version = "0.2", optional = true } aes = { version = "0.9", optional = true, default-features = false } aes-gcm = { version = "0.11", optional = true, default-features = false, features = ["aes"] } @@ -40,7 +41,7 @@ alloc = [] 3des = ["dep:des", "pbes2"] des-insecure = ["dep:des", "pbes2"] getrandom = ["dep:getrandom", "rand_core"] -pbes2 = ["dep:aes", "dep:cbc", "dep:pbkdf2", "dep:scrypt", "dep:sha2", "dep:aes-gcm"] +pbes2 = ["dep:aes", "dep:cbc", "dep:pbkdf2", "dep:scrypt", "dep:sha2", "dep:aes-gcm", "dep:aead"] rand_core = ["dep:rand_core"] sha1-insecure = ["dep:sha1", "pbes2"] diff --git a/pkcs5/src/pbes2/encryption.rs b/pkcs5/src/pbes2/encryption.rs index 426f3d62f..866ceabf2 100644 --- a/pkcs5/src/pbes2/encryption.rs +++ b/pkcs5/src/pbes2/encryption.rs @@ -2,7 +2,7 @@ use super::{EncryptionScheme, Kdf, Parameters, Pbkdf2Params, Pbkdf2Prf, ScryptParams}; use crate::{Error, Result}; -use aes_gcm::{KeyInit as GcmKeyInit, Nonce, Tag, aead::AeadInOut}; +use aead::{AeadInOut, Nonce, array::typenum::Unsigned}; use cbc::cipher::{ BlockCipherDecrypt, BlockCipherEncrypt, BlockModeDecrypt, BlockModeEncrypt, KeyInit, KeyIvInit, block_padding::Pkcs7, @@ -20,6 +20,9 @@ use pbkdf2::{ }; use scrypt::scrypt; +type Aes128Gcm = aes_gcm::AesGcm; +type Aes256Gcm = aes_gcm::AesGcm; + /// Maximum size of a derived encryption key const MAX_KEY_LEN: usize = 32; @@ -48,61 +51,50 @@ fn cbc_decrypt<'a, C: BlockCipherDecrypt + KeyInit>( .map_err(|_| Error::DecryptFailed) } -fn gcm_encrypt( +fn aead_encrypt<'a, A>( es: EncryptionScheme, - key: EncryptionKey, - nonce: Nonce, - buffer: &mut [u8], + key: &EncryptionKey, + nonce: &Nonce, + buffer: &'a mut [u8], pos: usize, -) -> Result<&[u8]> +) -> Result<&'a [u8]> where - C: BlockSizeUser + GcmKeyInit + BlockCipherEncrypt, - aes_gcm::AesGcm: GcmKeyInit, - TagSize: aes_gcm::TagSize, - NonceSize: aes::cipher::array::ArraySize, + A: AeadInOut + KeyInit, { - if buffer.len() < TagSize::USIZE + pos { + if buffer.len() < A::TagSize::USIZE + pos { return Err(Error::EncryptFailed); } - let gcm = - as GcmKeyInit>::new_from_slice(key.as_slice()) - .map_err(|_| es.to_alg_params_invalid())?; - let tag = gcm - .encrypt_inout_detached(&nonce, &[], (&mut buffer[..pos]).into()) + + let aead = A::new_from_slice(key.as_slice()).map_err(|_| es.to_alg_params_invalid())?; + + let tag = aead + .encrypt_inout_detached(nonce, &[], (&mut buffer[..pos]).into()) .map_err(|_| Error::EncryptFailed)?; + buffer[pos..].copy_from_slice(tag.as_ref()); - Ok(&buffer[0..pos + TagSize::USIZE]) + Ok(&buffer[0..pos + A::TagSize::USIZE]) } -fn gcm_decrypt( +fn aead_decrypt<'a, A>( es: EncryptionScheme, - key: EncryptionKey, - nonce: Nonce, - buffer: &mut [u8], -) -> Result<&[u8]> + key: &EncryptionKey, + nonce: &Nonce, + buffer: &'a mut [u8], +) -> Result<&'a [u8]> where - C: BlockSizeUser + GcmKeyInit + BlockCipherEncrypt, - aes_gcm::AesGcm: GcmKeyInit, - TagSize: aes_gcm::TagSize, - NonceSize: aes::cipher::array::ArraySize, + A: AeadInOut + KeyInit, { let msg_len = buffer .len() - .checked_sub(TagSize::USIZE) + .checked_sub(A::TagSize::USIZE) .ok_or(Error::DecryptFailed)?; - let gcm = - as GcmKeyInit>::new_from_slice(key.as_slice()) - .map_err(|_| es.to_alg_params_invalid())?; + let aead = A::new_from_slice(key.as_slice()).map_err(|_| es.to_alg_params_invalid())?; - let tag = Tag::try_from(&buffer[msg_len..]).map_err(|_| Error::DecryptFailed)?; + let tag = aead::Tag::::try_from(&buffer[msg_len..]).map_err(|_| Error::DecryptFailed)?; - if gcm - .decrypt_inout_detached(&nonce, &[], (&mut buffer[..msg_len]).into(), &tag) - .is_err() - { - return Err(Error::DecryptFailed); - } + aead.decrypt_inout_detached(nonce, &[], (&mut buffer[..msg_len]).into(), &tag) + .map_err(|_| Error::DecryptFailed)?; Ok(&buffer[..msg_len]) } @@ -125,10 +117,10 @@ pub fn encrypt_in_place<'b>( EncryptionScheme::Aes192Cbc { iv } => cbc_encrypt::(es, key, &iv, buf, pos), EncryptionScheme::Aes256Cbc { iv } => cbc_encrypt::(es, key, &iv, buf, pos), EncryptionScheme::Aes128Gcm { nonce } => { - gcm_encrypt::(es, key, Nonce::from(nonce), buf, pos) + aead_encrypt::(es, &key, &Nonce::::from(nonce), buf, pos) } EncryptionScheme::Aes256Gcm { nonce } => { - gcm_encrypt::(es, key, Nonce::from(nonce), buf, pos) + aead_encrypt::(es, &key, &Nonce::::from(nonce), buf, pos) } #[cfg(feature = "3des")] EncryptionScheme::DesEde3Cbc { iv } => cbc_encrypt::(es, key, &iv, buf, pos), @@ -153,10 +145,10 @@ pub fn decrypt_in_place<'a>( EncryptionScheme::Aes192Cbc { iv } => cbc_decrypt::(es, key, &iv, buf), EncryptionScheme::Aes256Cbc { iv } => cbc_decrypt::(es, key, &iv, buf), EncryptionScheme::Aes128Gcm { nonce } => { - gcm_decrypt::(es, key, Nonce::from(nonce), buf) + aead_decrypt::(es, &key, &Nonce::::from(nonce), buf) } EncryptionScheme::Aes256Gcm { nonce } => { - gcm_decrypt::(es, key, Nonce::from(nonce), buf) + aead_decrypt::(es, &key, &Nonce::::from(nonce), buf) } #[cfg(feature = "3des")] EncryptionScheme::DesEde3Cbc { iv } => cbc_decrypt::(es, key, &iv, buf),