wolf_crypto/mac/poly1305/key.rs
1//! Key management for the `Poly1305` MAC.
2//!
3//! This defines the key structures, traits, and associated functionalities required
4//! for securely managing and utilizing cryptographic keys.
5//!
6//! # Key Structures
7//!
8//! - `Key`: Represents a 32-byte secret key used for MAC computations.
9//! - `KeyRef`: A reference to a `Key`, allowing for efficient key handling without ownership.
10//!
11//! # Traits
12//!
13//! - `GenericKey`: A sealed trait for generic key types, providing a method to access the key's
14//! byte pointer.
15
16use core::array::TryFromSliceError;
17use zeroize::Zeroize;
18use crate::sealed::Sealed;
19
20/// The size of the Poly1305 key in bytes.
21pub const KEY_SIZE: usize = KEY_SIZE_U32 as usize;
22
23/// The size of the Poly1305 key as a `u32`.
24pub const KEY_SIZE_U32: u32 = 32;
25
26
27/// A sealed trait for generic key types used in Poly1305.
28///
29/// This trait is sealed and cannot be implemented outside of this crate.
30pub trait GenericKey : Sealed {
31 #[doc(hidden)]
32 fn ptr(&self) -> *const u8;
33}
34
35/// Represents a 32-byte secret key for `Poly1305` and `ChaCha20Poly1305`.
36///
37/// This struct ensures that the key material is securely managed and zeroed from memory when
38/// dropped.
39#[repr(transparent)]
40#[derive(Clone)]
41pub struct Key {
42 inner: [u8; KEY_SIZE]
43}
44
45arb_key! { struct Key::new([u8; 32]) }
46
47impl Key {
48 /// Creates a new `Key` from a 32-byte array.
49 ///
50 /// # Arguments
51 ///
52 /// * `inner` - A 32-byte array containing the key material.
53 ///
54 /// # Example
55 ///
56 /// ```rust
57 /// use wolf_crypto::mac::poly1305::Key;
58 ///
59 /// let key = Key::new([0u8; 32]);
60 /// # drop(key);
61 /// ```
62 pub const fn new(inner: [u8; KEY_SIZE]) -> Self {
63 Self { inner }
64 }
65
66 /// Returns a reference to the key as a `KeyRef`.
67 ///
68 /// # Returns
69 ///
70 /// * `KeyRef` - A reference to the key material.
71 ///
72 /// # Example
73 ///
74 /// ```rust
75 /// use wolf_crypto::mac::poly1305::{Key, KeyRef};
76 ///
77 /// let key = Key::new([0u8; 32]);
78 /// let key_ref: KeyRef = key.as_ref();
79 /// # drop(key_ref); drop(key);
80 /// ```
81 pub const fn as_ref(&self) -> KeyRef {
82 KeyRef::new(&self.inner)
83 }
84}
85
86impl Zeroize for Key {
87 /// Zeroes the key material in memory.
88 ///
89 /// This method securely erases the key from memory to prevent leakage.
90 #[inline]
91 fn zeroize(&mut self) {
92 self.inner.zeroize();
93 }
94}
95
96opaque_dbg! { Key }
97impl Sealed for Key {}
98impl GenericKey for Key {
99 #[doc(hidden)]
100 #[inline]
101 fn ptr(&self) -> *const u8 {
102 self.inner.as_ptr()
103 }
104}
105
106impl From<[u8; KEY_SIZE]> for Key {
107 /// Converts a 32-byte array into a `Key`.
108 ///
109 /// # Arguments
110 ///
111 /// * `value` - A 32-byte array containing the key material.
112 ///
113 /// # Example
114 ///
115 /// ```rust
116 /// use wolf_crypto::mac::poly1305::Key;
117 ///
118 /// let key_bytes = [1u8; 32];
119 /// let key: Key = key_bytes.into();
120 /// # drop(key);
121 /// ```
122 #[inline]
123 fn from(value: [u8; KEY_SIZE]) -> Self {
124 Self::new(value, )
125 }
126}
127
128impl Drop for Key {
129 /// Drops the `Key`, ensuring that the key material is zeroed from memory.
130 #[inline]
131 fn drop(&mut self) {
132 self.zeroize();
133 }
134}
135
136/// A reference to a [`Key`], allowing for efficient key handling without ownership.
137#[repr(transparent)]
138pub struct KeyRef<'r> {
139 inner: &'r [u8; KEY_SIZE]
140}
141
142impl<'r> KeyRef<'r> {
143 /// Creates a new `KeyRef` from a reference to a 32-byte array.
144 ///
145 /// # Arguments
146 ///
147 /// * `inner` - A reference to a 32-byte array containing the key material.
148 ///
149 /// # Example
150 ///
151 /// ```rust
152 /// use wolf_crypto::mac::poly1305::{Key, KeyRef};
153 ///
154 /// let key_bytes = [2u8; 32];
155 /// let key = Key::new(key_bytes,);
156 /// let key_ref: KeyRef = key.as_ref();
157 /// # drop(key_ref); drop(key);
158 /// ```
159 pub const fn new(inner: &'r [u8; KEY_SIZE]) -> Self {
160 Self { inner }
161 }
162
163 /// Creates a copy of the key as a [`Key`].
164 ///
165 /// # Returns
166 ///
167 /// A new [`Key`] instance containing the same key material.
168 ///
169 /// # Example
170 ///
171 /// ```rust
172 /// use wolf_crypto::mac::poly1305::{Key, KeyRef};
173 ///
174 /// let key_ref: KeyRef = (&[7u8; 32]).into();
175 /// let owned_key = key_ref.copy();
176 /// # drop(key_ref); drop(owned_key);
177 /// ```
178 pub const fn copy(&self) -> Key {
179 Key::new(*self.inner, )
180 }
181}
182
183opaque_dbg! { KeyRef<'r> }
184
185impl<'r> Sealed for KeyRef<'r> {}
186impl<'r> GenericKey for KeyRef<'r> {
187 #[doc(hidden)]
188 #[inline]
189 fn ptr(&self) -> *const u8 {
190 self.inner.as_ptr()
191 }
192}
193
194impl<'r> From<&'r [u8; KEY_SIZE]> for KeyRef<'r> {
195 /// Converts a reference to a 32-byte array into a `KeyRef`.
196 ///
197 /// # Arguments
198 ///
199 /// * `value` - A reference to a 32-byte array containing the key material.
200 ///
201 /// # Example
202 ///
203 /// ```rust
204 /// use wolf_crypto::mac::poly1305::{Key, KeyRef};
205 ///
206 /// let key_ref = KeyRef::from(&[2u8; 32]);
207 /// # drop(key_ref);
208 /// ```
209 #[inline]
210 fn from(value: &'r [u8; KEY_SIZE]) -> Self {
211 Self::new(value)
212 }
213}
214
215impl<'r> TryFrom<&'r [u8]> for KeyRef<'r> {
216 type Error = TryFromSliceError;
217
218 /// Attempts to convert a slice of bytes into a `KeyRef`.
219 ///
220 /// # Arguments
221 ///
222 /// * `value` - A slice of bytes to convert.
223 ///
224 /// # Errors
225 ///
226 /// Returns `TryFromSliceError` if the slice length is not exactly 32 bytes.
227 ///
228 /// # Example
229 ///
230 /// ```rust
231 /// use wolf_crypto::mac::poly1305::KeyRef;
232 ///
233 /// let key_slice = &[5u8; 32];
234 /// let key_ref = KeyRef::try_from(key_slice).unwrap();
235 /// ```
236 #[inline]
237 fn try_from(value: &'r [u8]) -> Result<Self, Self::Error> {
238 value.try_into().map(Self::new)
239 }
240}