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}