dcrypt_api/
types.rs

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