wolf_crypto/aes/
mod.rs

1//! Advanced Encryption Standard (AES)
2// macro_rules! impl_aes_new {
3//     ($self:ident, $lt:lifetime, $nl:lifetime, $nonce_ty:ty) => {
4//         pub fn new(key: &$lt $crate::aes::Key, nonce: &$nl $nonce_ty) -> Result<$self, ()> {
5//             let key_ptr = $crate::ptr::MutPtr::new(key as *const _ as *mut $crate::aes::Key);
6//             let iv_ptr = $crate::ptr::MutPtr::new(nonce as *const _ as *mut u8);
7//
8//             unsafe {
9//                 let mut aes: AesLL = core::mem::zeroed();
10//                 let aes_ptr = $crate::ptr::MutPtr::new(core::ptr::addr_of_mut!(aes));
11//                 $crate::aes::init_aes(aes_ptr, $self::MODE, key_ptr, iv_ptr)
12//                     .unit_err($self::with_aes(aes))
13//             }
14//         }
15//     };
16// }
17
18hidden! {
19    pub mod ctr;
20}
21
22pub use { crate::aes::ctr::AesCtr };
23
24#[cfg(test)]
25pub mod test_utils;
26
27use wolf_crypto_sys::{
28    Aes as AesLL,
29    wc_AesInit,
30    INVALID_DEVID, AES_ENCRYPTION,
31};
32
33use zeroize::Zeroize;
34use core::mem::MaybeUninit;
35use crate::opaque_res::Res;
36
37/// Represents different AES key sizes.
38///
39/// AES (Advanced Encryption Standard) supports three key sizes:
40/// - 128-bit (16 bytes)
41/// - 192-bit (24 bytes)
42/// - 256-bit (32 bytes)
43///
44/// This enum allows for type-safe handling of these different key sizes.
45#[cfg_attr(test, derive(Debug, Clone, PartialEq))]
46pub enum Key {
47    /// 256-bit AES key (32 bytes)
48    Aes256([u8; 32]),
49    /// 192-bit AES key (24 bytes)
50    Aes192([u8; 24]),
51    /// 128-bit AES key (16 bytes)
52    Aes128([u8; 16])
53}
54
55impl Key {
56    /// Returns the capacity (size in bytes) of the key.
57    ///
58    /// # Returns
59    ///
60    /// - `32` for Aes256
61    /// - `24` for Aes192
62    /// - `16` for Aes128
63    #[inline]
64    pub const fn capacity(&self) -> usize {
65        match self {
66            Self::Aes256(_) => 32,
67            Self::Aes192(_) => 24,
68            Self::Aes128(_) => 16
69        }
70    }
71
72    /// Returns a reference to the key as a byte slice.
73    #[inline]
74    pub const fn as_slice(&self) -> &[u8] {
75        match self {
76            Self::Aes256(buf) => buf.as_slice(),
77            Self::Aes192(buf) => buf.as_slice(),
78            Self::Aes128(buf) => buf.as_slice()
79        }
80    }
81
82    /// Returns a mutable reference to the key as a byte slice.
83    #[inline]
84    pub fn as_mut_slice(&mut self) -> &mut [u8] {
85        match self {
86            Self::Aes256(buf) => buf.as_mut_slice(),
87            Self::Aes192(buf) => buf.as_mut_slice(),
88            Self::Aes128(buf) => buf.as_mut_slice()
89        }
90    }
91
92    /// Zeros out the key for security purposes.
93    ///
94    /// This method uses the `zeroize` crate to ensure that the key material
95    /// is securely erased from memory.
96    ///
97    /// This is called in the `Key` drop implementation.
98    #[inline]
99    pub fn zero(&mut self) {
100        self.as_mut_slice().zeroize();
101    }
102}
103
104impl Zeroize for Key {
105    fn zeroize(&mut self) {
106        self.zero();
107    }
108}
109
110impl Drop for Key {
111    /// Zeroes the underlying key material.
112    fn drop(&mut self) {
113        self.zero();
114    }
115}
116
117impl From<[u8; 32]> for Key {
118    #[inline]
119    fn from(value: [u8; 32]) -> Self {
120        Self::Aes256(value)
121    }
122}
123
124impl From<[u8; 24]> for Key {
125    #[inline]
126    fn from(value: [u8; 24]) -> Self {
127        Self::Aes192(value)
128    }
129}
130
131impl From<[u8; 16]> for Key {
132    #[inline]
133    fn from(value: [u8; 16]) -> Self {
134        Self::Aes128(value)
135    }
136}
137
138#[repr(transparent)]
139pub(crate) struct AesM {
140    mode: core::ffi::c_uint
141}
142
143impl AesM {
144    pub const ENCRYPT: Self = Self { mode: AES_ENCRYPTION };
145    // pub const DECRYPT: Self = Self { mode: AES_DECRYPTION };
146
147    #[inline]
148    pub const fn mode(&self) -> core::ffi::c_uint {
149        self.mode
150    }
151}
152
153#[cfg_attr(not(debug_assertions), inline(always))]
154pub(crate) unsafe fn init_aes(mut aes: MaybeUninit<AesLL>) -> (MaybeUninit<AesLL>, Res) {
155    let mut res = Res::new();
156    res.ensure_0(wc_AesInit(aes.as_mut_ptr(), core::ptr::null_mut(), INVALID_DEVID));
157    (aes, res)
158}