From 119550e87263e22018b51b8a701ca62fe257aeba Mon Sep 17 00:00:00 2001 From: Alexandr Kitaev Date: Tue, 25 Aug 2026 18:53:38 +0300 Subject: [PATCH 1/3] `pkcs5`: `gcm_*` -> `aead_*` --- Cargo.lock | 1 + pkcs5/Cargo.toml | 1 + pkcs5/src/pbes2/encryption.rs | 74 ++++++++++++++++------------------- 3 files changed, 35 insertions(+), 41 deletions(-) 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..1d5f980ec 100644 --- a/pkcs5/Cargo.toml +++ b/pkcs5/Cargo.toml @@ -16,6 +16,7 @@ edition = "2024" rust-version = "1.85" [dependencies] +aead = { version = "0.6", default-features = false } der = { version = "0.8", features = ["oid"] } spki = "0.8" 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), From 49370345ae4069184ab7a02acd3a3a223afbb761 Mon Sep 17 00:00:00 2001 From: Alexandr Kitaev Date: Tue, 25 Aug 2026 19:41:22 +0300 Subject: [PATCH 2/3] fix: add feature-gate for `aead` --- pkcs5/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkcs5/Cargo.toml b/pkcs5/Cargo.toml index 1d5f980ec..86ada3152 100644 --- a/pkcs5/Cargo.toml +++ b/pkcs5/Cargo.toml @@ -16,7 +16,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -aead = { version = "0.6", default-features = false } +aead = { version = "0.6", default-features = false, optional = true } der = { version = "0.8", features = ["oid"] } spki = "0.8" @@ -41,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"] From 1655045ea04ec92e86cc27b3c66d1c5ef3432a09 Mon Sep 17 00:00:00 2001 From: Alexandr Kitaev Date: Tue, 25 Aug 2026 19:44:54 +0300 Subject: [PATCH 3/3] fix: move aead under the optional dependencies block --- pkcs5/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkcs5/Cargo.toml b/pkcs5/Cargo.toml index 86ada3152..cc5342665 100644 --- a/pkcs5/Cargo.toml +++ b/pkcs5/Cargo.toml @@ -16,11 +16,11 @@ edition = "2024" rust-version = "1.85" [dependencies] -aead = { version = "0.6", default-features = false, optional = true } 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"] }