Enable expanded AES key schedule zeroization

Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
Alexey
2026-07-11 21:43:01 +03:00
parent ea296bbdc8
commit 8c65cd868c
+18 -12
View File
@@ -4,12 +4,12 @@
//! //!
//! ## Zeroize policy //! ## Zeroize policy
//! //!
//! - `AesCbc` stores raw key/IV bytes and zeroizes them on drop. //! - `AesCbc` stores raw key/IV bytes and zeroizes them on drop. Temporary
//! - `AesCtr` wraps an opaque `Aes256Ctr` cipher from the `ctr` crate. //! expanded key schedules are also zeroized by the RustCrypto backend.
//! The expanded key schedule lives inside that type and cannot be //! - `AesCtr` uses the RustCrypto `zeroize` contract to clear its expanded
//! zeroized from outside. Callers that hold raw key material (e.g. //! key schedule, counter, and buffered keystream on drop.
//! `HandshakeSuccess`, `ObfuscationParams`) are responsible for //! - Callers that hold raw key material (e.g. `HandshakeSuccess`,
//! zeroizing their own copies. //! `ObfuscationParams`) remain responsible for zeroizing their own copies.
#![allow(dead_code)] #![allow(dead_code)]
@@ -19,24 +19,28 @@ use ctr::{
Ctr128BE, Ctr128BE,
cipher::{KeyIvInit, StreamCipher}, cipher::{KeyIvInit, StreamCipher},
}; };
use zeroize::Zeroize; use zeroize::{Zeroize, ZeroizeOnDrop};
type Aes256Ctr = Ctr128BE<Aes256>; type Aes256Ctr = Ctr128BE<Aes256>;
static_assertions::assert_impl_all!(Aes256: ZeroizeOnDrop);
static_assertions::assert_impl_all!(Aes256Ctr: ZeroizeOnDrop);
// ============= AES-256-CTR ============= // ============= AES-256-CTR =============
/// AES-256-CTR encryptor/decryptor /// AES-256-CTR encryptor/decryptor
/// ///
/// CTR mode is symmetric — encryption and decryption are the same operation. /// CTR mode is symmetric — encryption and decryption are the same operation.
/// ///
/// **Zeroize note:** The inner `Aes256Ctr` cipher state (expanded key schedule /// **Zeroize note:** The inner `Aes256Ctr` zeroizes its expanded key schedule,
/// + counter) is opaque and cannot be zeroized. If you need to protect key /// counter, and buffered keystream on drop. Callers remain responsible for
/// material, zeroize the `[u8; 32]` key and `u128` IV at the call site /// zeroizing their own raw key and IV copies.
/// before dropping them.
pub struct AesCtr { pub struct AesCtr {
cipher: Aes256Ctr, cipher: Aes256Ctr,
} }
impl ZeroizeOnDrop for AesCtr {}
impl AesCtr { impl AesCtr {
/// Create new AES-CTR cipher with key and IV /// Create new AES-CTR cipher with key and IV
pub fn new(key: &[u8; 32], iv: u128) -> Self { pub fn new(key: &[u8; 32], iv: u128) -> Self {
@@ -92,7 +96,7 @@ impl AesCtr {
/// are different operations. This implementation handles CBC chaining /// are different operations. This implementation handles CBC chaining
/// correctly across multiple blocks. /// correctly across multiple blocks.
/// ///
/// Key and IV are zeroized on drop. /// Key, IV, and temporary expanded key schedules are zeroized on drop.
pub struct AesCbc { pub struct AesCbc {
key: [u8; 32], key: [u8; 32],
iv: [u8; 16], iv: [u8; 16],
@@ -105,6 +109,8 @@ impl Drop for AesCbc {
} }
} }
impl ZeroizeOnDrop for AesCbc {}
impl AesCbc { impl AesCbc {
/// AES block size /// AES block size
const BLOCK_SIZE: usize = 16; const BLOCK_SIZE: usize = 16;