dcrypt_api/
types.rs

1//! Core types with security guarantees for the DCRYPT library
2//!
3//! This module provides fundamental type definitions that enforce
4//! compile-time and runtime guarantees for cryptographic operations.
5
6use crate::{Error, Result, Serialize};
7use core::fmt;
8use core::ops::{Deref, DerefMut};
9use dcrypt_internal::constant_time::ct_eq;
10use zeroize::{Zeroize, ZeroizeOnDrop};
11
12/// A fixed-size array of bytes that is securely zeroed when dropped
13///
14/// This type provides:
15/// - Compile-time size guarantees via const generics
16/// - Secure zeroing when dropped
17/// - Constant-time equality comparison
18/// - Debug implementation that hides the actual bytes
19#[derive(Clone, Zeroize, ZeroizeOnDrop)]
20pub struct SecretBytes<const N: usize> {
21    data: [u8; N],
22}
23
24impl<const N: usize> SecretBytes<N> {
25    /// Create a new instance from an existing array
26    pub fn new(data: [u8; N]) -> Self {
27        Self { data }
28    }
29
30    /// Create from a slice, if it has the correct length
31    pub fn from_slice(slice: &[u8]) -> Result<Self> {
32        if slice.len() != N {
33            return Err(Error::InvalidLength {
34                context: "SecretBytes::from_slice",
35                expected: N,
36                actual: slice.len(),
37            });
38        }
39
40        let mut data = [0u8; N];
41        data.copy_from_slice(slice);
42
43        Ok(Self { data })
44    }
45
46    /// Create an instance filled with zeros
47    pub fn zeroed() -> Self {
48        Self { data: [0u8; N] }
49    }
50
51    /// Generate a random instance
52    pub fn random<R: rand::RngCore + rand::CryptoRng>(rng: &mut R) -> Self {
53        let mut data = [0u8; N];
54        rng.fill_bytes(&mut data);
55        Self { data }
56    }
57
58    /// Get the length of the contained data
59    pub fn len(&self) -> usize {
60        N
61    }
62
63    /// Check if the container is empty
64    pub fn is_empty(&self) -> bool {
65        N == 0
66    }
67}
68
69impl<const N: usize> AsRef<[u8]> for SecretBytes<N> {
70    fn as_ref(&self) -> &[u8] {
71        &self.data
72    }
73}
74
75impl<const N: usize> AsMut<[u8]> for SecretBytes<N> {
76    fn as_mut(&mut self) -> &mut [u8] {
77        &mut self.data
78    }
79}
80
81impl<const N: usize> Deref for SecretBytes<N> {
82    type Target = [u8; N];
83
84    fn deref(&self) -> &Self::Target {
85        &self.data
86    }
87}
88
89impl<const N: usize> DerefMut for SecretBytes<N> {
90    fn deref_mut(&mut self) -> &mut Self::Target {
91        &mut self.data
92    }
93}
94
95impl<const N: usize> PartialEq for SecretBytes<N> {
96    fn eq(&self, other: &Self) -> bool {
97        ct_eq(self.data, other.data)
98    }
99}
100
101impl<const N: usize> Eq for SecretBytes<N> {}
102
103impl<const N: usize> fmt::Debug for SecretBytes<N> {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        write!(f, "SecretBytes<{}>[REDACTED]", N)
106    }
107}
108
109impl<const N: usize> Serialize for SecretBytes<N> {
110    fn to_bytes(&self) -> Result<Vec<u8>> {
111        Ok(self.data.to_vec())
112    }
113
114    fn from_bytes(bytes: &[u8]) -> Result<Self> {
115        Self::from_slice(bytes)
116    }
117}
118
119/// A variable-length vector of bytes that is securely zeroed when dropped
120#[derive(Clone, Zeroize, ZeroizeOnDrop)]
121pub struct SecretVec {
122    data: Vec<u8>,
123}
124
125impl SecretVec {
126    /// Create a new instance from an existing vector
127    pub fn new(data: Vec<u8>) -> Self {
128        Self { data }
129    }
130
131    /// Create by copying from a slice
132    pub fn from_slice(slice: &[u8]) -> Self {
133        Self {
134            data: slice.to_vec(),
135        }
136    }
137
138    /// Create filled with zeros
139    pub fn zeroed(len: usize) -> Self {
140        Self {
141            data: vec![0u8; len],
142        }
143    }
144
145    /// Generate a random instance
146    pub fn random<R: rand::RngCore + rand::CryptoRng>(rng: &mut R, len: usize) -> Self {
147        let mut data = vec![0u8; len];
148        rng.fill_bytes(&mut data);
149        Self { data }
150    }
151
152    /// Get the length of the contained data
153    pub fn len(&self) -> usize {
154        self.data.len()
155    }
156
157    /// Check if the container is empty
158    pub fn is_empty(&self) -> bool {
159        self.data.is_empty()
160    }
161}
162
163impl AsRef<[u8]> for SecretVec {
164    fn as_ref(&self) -> &[u8] {
165        &self.data
166    }
167}
168
169impl AsMut<[u8]> for SecretVec {
170    fn as_mut(&mut self) -> &mut [u8] {
171        &mut self.data
172    }
173}
174
175impl Deref for SecretVec {
176    type Target = Vec<u8>;
177
178    fn deref(&self) -> &Self::Target {
179        &self.data
180    }
181}
182
183impl DerefMut for SecretVec {
184    fn deref_mut(&mut self) -> &mut Self::Target {
185        &mut self.data
186    }
187}
188
189impl PartialEq for SecretVec {
190    fn eq(&self, other: &Self) -> bool {
191        ct_eq(&self.data, &other.data)
192    }
193}
194
195impl Eq for SecretVec {}
196
197impl fmt::Debug for SecretVec {
198    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199        write!(f, "SecretVec({})[REDACTED]", self.data.len())
200    }
201}
202
203impl Serialize for SecretVec {
204    fn to_bytes(&self) -> Result<Vec<u8>> {
205        Ok(self.data.clone())
206    }
207
208    fn from_bytes(bytes: &[u8]) -> Result<Self> {
209        Ok(Self::from_slice(bytes))
210    }
211}
212
213/// Base key type that provides secure memory handling
214///
215/// Enhanced version of the original Key type with additional security features
216#[derive(Clone, Zeroize, ZeroizeOnDrop)]
217pub struct Key {
218    data: Vec<u8>,
219}
220
221impl Key {
222    /// Create a new key from a byte array
223    pub fn new(bytes: &[u8]) -> Self {
224        Self {
225            data: bytes.to_vec(),
226        }
227    }
228
229    /// Create a new key with zeros
230    pub fn new_zeros(len: usize) -> Self {
231        Self {
232            data: vec![0u8; len],
233        }
234    }
235
236    /// Get the length of the key
237    pub fn len(&self) -> usize {
238        self.data.len()
239    }
240
241    /// Check if the key is empty
242    pub fn is_empty(&self) -> bool {
243        self.data.is_empty()
244    }
245}
246
247impl AsRef<[u8]> for Key {
248    fn as_ref(&self) -> &[u8] {
249        &self.data
250    }
251}
252
253impl AsMut<[u8]> for Key {
254    fn as_mut(&mut self) -> &mut [u8] {
255        &mut self.data
256    }
257}
258
259impl Serialize for Key {
260    fn to_bytes(&self) -> Result<Vec<u8>> {
261        Ok(self.data.clone())
262    }
263
264    fn from_bytes(bytes: &[u8]) -> Result<Self> {
265        Ok(Self::new(bytes))
266    }
267}
268
269/// Wrapper for public key data
270#[derive(Clone)]
271pub struct PublicKey {
272    data: Vec<u8>,
273}
274
275impl PublicKey {
276    /// Create a new public key from a byte array
277    pub fn new(bytes: &[u8]) -> Self {
278        Self {
279            data: bytes.to_vec(),
280        }
281    }
282
283    /// Get the length of the key
284    pub fn len(&self) -> usize {
285        self.data.len()
286    }
287
288    /// Check if the key is empty
289    pub fn is_empty(&self) -> bool {
290        self.data.is_empty()
291    }
292}
293
294impl Zeroize for PublicKey {
295    fn zeroize(&mut self) {
296        self.data.zeroize();
297    }
298}
299
300impl AsRef<[u8]> for PublicKey {
301    fn as_ref(&self) -> &[u8] {
302        &self.data
303    }
304}
305
306impl AsMut<[u8]> for PublicKey {
307    fn as_mut(&mut self) -> &mut [u8] {
308        &mut self.data
309    }
310}
311
312impl Serialize for PublicKey {
313    fn to_bytes(&self) -> Result<Vec<u8>> {
314        Ok(self.data.clone())
315    }
316
317    fn from_bytes(bytes: &[u8]) -> Result<Self> {
318        Ok(Self::new(bytes))
319    }
320}
321
322/// Wrapper for ciphertext data
323#[derive(Clone)]
324pub struct Ciphertext {
325    data: Vec<u8>,
326}
327
328impl Ciphertext {
329    /// Create a new ciphertext from a byte array
330    pub fn new(bytes: &[u8]) -> Self {
331        Self {
332            data: bytes.to_vec(),
333        }
334    }
335
336    /// Get the length of the ciphertext
337    pub fn len(&self) -> usize {
338        self.data.len()
339    }
340
341    /// Check if the ciphertext is empty
342    pub fn is_empty(&self) -> bool {
343        self.data.is_empty()
344    }
345}
346
347impl AsRef<[u8]> for Ciphertext {
348    fn as_ref(&self) -> &[u8] {
349        &self.data
350    }
351}
352
353impl AsMut<[u8]> for Ciphertext {
354    fn as_mut(&mut self) -> &mut [u8] {
355        &mut self.data
356    }
357}
358
359impl Serialize for Ciphertext {
360    fn to_bytes(&self) -> Result<Vec<u8>> {
361        Ok(self.data.clone())
362    }
363
364    fn from_bytes(bytes: &[u8]) -> Result<Self> {
365        Ok(Self::new(bytes))
366    }
367}