1use 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#[cfg(all(not(feature = "std"), feature = "alloc"))]
19use alloc::{vec, vec::Vec};
20#[cfg(feature = "std")]
21use std::vec::Vec;
22
23#[derive(Clone, Zeroize, ZeroizeOnDrop)]
25pub struct SecretBytes<const N: usize> {
26 data: [u8; N],
27}
28
29impl<const N: usize> SecretBytes<N> {
30 pub fn new(data: [u8; N]) -> Self {
31 Self { data }
32 }
33 pub fn from_slice(slice: &[u8]) -> Result<Self> {
34 if slice.len() != N {
35 return Err(Error::InvalidLength {
36 context: "SecretBytes::from_slice",
37 expected: N,
38 actual: slice.len(),
39 });
40 }
41 let mut data = [0u8; N];
42 data.copy_from_slice(slice);
43 Ok(Self { data })
44 }
45 pub fn zeroed() -> Self {
46 Self { data: [0u8; N] }
47 }
48 pub fn random<R: rand::RngCore + rand::CryptoRng>(rng: &mut R) -> Self {
49 let mut data = [0u8; N];
50 rng.fill_bytes(&mut data);
51 Self { data }
52 }
53 pub fn len(&self) -> usize {
54 N
55 }
56 pub fn is_empty(&self) -> bool {
57 N == 0
58 }
59}
60
61impl<const N: usize> AsRef<[u8]> for SecretBytes<N> {
62 fn as_ref(&self) -> &[u8] {
63 &self.data
64 }
65}
66
67impl<const N: usize> AsMut<[u8]> for SecretBytes<N> {
68 fn as_mut(&mut self) -> &mut [u8] {
69 &mut self.data
70 }
71}
72
73impl<const N: usize> Deref for SecretBytes<N> {
74 type Target = [u8; N];
75 fn deref(&self) -> &Self::Target {
76 &self.data
77 }
78}
79
80impl<const N: usize> DerefMut for SecretBytes<N> {
81 fn deref_mut(&mut self) -> &mut Self::Target {
82 &mut self.data
83 }
84}
85
86impl<const N: usize> PartialEq for SecretBytes<N> {
87 fn eq(&self, other: &Self) -> bool {
88 ct_eq(self.data, other.data)
89 }
90}
91
92impl<const N: usize> Eq for SecretBytes<N> {}
93
94impl<const N: usize> fmt::Debug for SecretBytes<N> {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "SecretBytes<{}>[REDACTED]", N)
97 }
98}
99
100impl<const N: usize> SerializeSecret for SecretBytes<N> {
101 fn from_bytes(bytes: &[u8]) -> Result<Self> {
102 Self::from_slice(bytes)
103 }
104 fn to_bytes_zeroizing(&self) -> Zeroizing<Vec<u8>> {
105 Zeroizing::new(self.data.to_vec())
106 }
107}
108
109#[derive(Zeroize, ZeroizeOnDrop)]
111pub struct SecretVec {
112 data: Vec<u8>,
113}
114
115impl SecretVec {
116 pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
124 let mut data = data.into();
125 Self::zeroize_spare_capacity(&mut data);
128 Self { data }
129 }
130
131 pub fn from_slice(slice: &[u8]) -> Self {
132 Self::new(slice.to_vec())
133 }
134 pub fn zeroed(len: usize) -> Self {
135 Self::new(vec![0u8; len])
136 }
137 pub fn random<R: rand::RngCore + rand::CryptoRng>(rng: &mut R, len: usize) -> Self {
138 let mut data = vec![0u8; len];
139 rng.fill_bytes(&mut data);
140 Self::new(data)
141 }
142 pub fn len(&self) -> usize {
143 self.data.len()
144 }
145 pub fn is_empty(&self) -> bool {
146 self.data.is_empty()
147 }
148
149 pub fn as_slice(&self) -> &[u8] {
151 &self.data
152 }
153
154 pub fn as_mut_slice(&mut self) -> &mut [u8] {
159 &mut self.data
160 }
161
162 pub fn capacity(&self) -> usize {
164 self.data.capacity()
165 }
166
167 pub fn extend_from_slice(&mut self, slice: &[u8]) {
170 self.ensure_additional_capacity(slice.len());
171 self.data.extend_from_slice(slice);
172 }
173
174 pub fn resize(&mut self, new_len: usize, value: u8) {
176 if new_len <= self.data.len() {
177 self.truncate(new_len);
178 return;
179 }
180
181 self.ensure_additional_capacity(new_len - self.data.len());
182 self.data.resize(new_len, value);
183 }
184
185 pub fn truncate(&mut self, len: usize) {
187 if len >= self.data.len() {
188 return;
189 }
190
191 self.data[len..].zeroize();
192 self.data.truncate(len);
193 }
194
195 pub fn clear(&mut self) {
197 self.data.zeroize();
198 }
199
200 pub fn push(&mut self, value: u8) {
202 self.ensure_additional_capacity(1);
203 self.data.push(value);
204 }
205
206 pub fn pop(&mut self) -> Option<u8> {
208 let value = self.data.last().copied()?;
209 let new_len = self.data.len() - 1;
210 self.data[new_len].zeroize();
211 self.data.truncate(new_len);
212 Some(value)
213 }
214
215 pub fn reserve(&mut self, additional: usize) {
218 self.ensure_additional_capacity(additional);
219 }
220
221 pub fn shrink_to_fit(&mut self) {
223 if self.data.capacity() > self.data.len() {
224 self.secure_reallocate(self.data.len());
225 }
226 }
227
228 fn ensure_additional_capacity(&mut self, additional: usize) {
229 let required = self
230 .data
231 .len()
232 .checked_add(additional)
233 .expect("SecretVec capacity overflow");
234
235 if required > self.data.capacity() {
236 self.secure_reallocate(required);
237 }
238 }
239
240 fn secure_reallocate(&mut self, capacity: usize) {
241 debug_assert!(capacity >= self.data.len());
242
243 let mut replacement = Vec::with_capacity(capacity);
244 replacement.extend_from_slice(&self.data);
245 Self::zeroize_spare_capacity(&mut replacement);
246
247 self.data.zeroize();
250 #[cfg(test)]
251 assert!(Self::allocation_is_zeroed(&self.data));
252 self.data = replacement;
253 }
254
255 fn zeroize_spare_capacity(data: &mut Vec<u8>) {
256 data.spare_capacity_mut().zeroize();
257 }
258
259 #[cfg(test)]
260 fn allocation_is_zeroed(data: &Vec<u8>) -> bool {
261 let allocation = unsafe { core::slice::from_raw_parts(data.as_ptr(), data.capacity()) };
264 allocation.iter().all(|byte| *byte == 0)
265 }
266}
267
268impl Clone for SecretVec {
269 fn clone(&self) -> Self {
270 Self::from_slice(&self.data)
271 }
272}
273
274impl From<Vec<u8>> for SecretVec {
275 fn from(data: Vec<u8>) -> Self {
276 Self::new(data)
277 }
278}
279
280impl AsRef<[u8]> for SecretVec {
281 fn as_ref(&self) -> &[u8] {
282 &self.data
283 }
284}
285
286impl AsMut<[u8]> for SecretVec {
287 fn as_mut(&mut self) -> &mut [u8] {
288 &mut self.data
289 }
290}
291
292impl Deref for SecretVec {
293 type Target = [u8];
294 fn deref(&self) -> &Self::Target {
295 &self.data
296 }
297}
298
299impl DerefMut for SecretVec {
300 fn deref_mut(&mut self) -> &mut Self::Target {
301 &mut self.data
302 }
303}
304
305impl PartialEq for SecretVec {
306 fn eq(&self, other: &Self) -> bool {
307 ct_eq(&self.data, &other.data)
308 }
309}
310
311impl Eq for SecretVec {}
312
313impl fmt::Debug for SecretVec {
314 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315 write!(f, "SecretVec({})[REDACTED]", self.data.len())
316 }
317}
318
319impl SerializeSecret for SecretVec {
320 fn from_bytes(bytes: &[u8]) -> Result<Self> {
321 Ok(Self::from_slice(bytes))
322 }
323 fn to_bytes_zeroizing(&self) -> Zeroizing<Vec<u8>> {
324 Zeroizing::new(self.data.clone())
325 }
326}
327
328#[cfg(test)]
329mod secret_vec_tests {
330 use super::SecretVec;
331
332 #[cfg(all(not(feature = "std"), feature = "alloc"))]
333 use alloc::{vec, vec::Vec};
334
335 fn assert_spare_capacity_is_zero(secret: &SecretVec) {
336 let spare = unsafe {
340 core::slice::from_raw_parts(
341 secret.data.as_ptr().add(secret.data.len()),
342 secret.data.capacity() - secret.data.len(),
343 )
344 };
345 assert!(spare.iter().all(|byte| *byte == 0));
346 }
347
348 #[test]
349 fn constructor_wipes_preexisting_unused_capacity() {
350 let mut raw = vec![0xA5; 64];
351 raw.truncate(4);
352 let secret = SecretVec::new(raw);
353
354 assert_eq!(secret.as_slice(), &[0xA5; 4]);
355 assert_spare_capacity_is_zero(&secret);
356 }
357
358 #[test]
359 fn shrinking_operations_wipe_removed_slots() {
360 let mut secret = SecretVec::from_slice(&[1, 2, 3, 4, 5, 6]);
361
362 secret.truncate(4);
363 assert_eq!(secret.as_slice(), &[1, 2, 3, 4]);
364 assert_spare_capacity_is_zero(&secret);
365
366 secret.resize(2, 0xFF);
367 assert_eq!(secret.as_slice(), &[1, 2]);
368 assert_spare_capacity_is_zero(&secret);
369
370 assert_eq!(secret.pop(), Some(2));
371 assert_eq!(secret.as_slice(), &[1]);
372 assert_spare_capacity_is_zero(&secret);
373
374 secret.clear();
375 assert!(secret.is_empty());
376 assert_spare_capacity_is_zero(&secret);
377 }
378
379 #[test]
380 fn growth_and_shrink_replace_allocations_securely() {
381 let mut raw = Vec::with_capacity(4);
382 raw.extend_from_slice(&[0x11; 4]);
383 let mut secret = SecretVec::new(raw);
384 let initial_capacity = secret.capacity();
385
386 secret.extend_from_slice(&[0x22, 0x33]);
389 assert!(secret.capacity() > initial_capacity);
390 assert_eq!(secret.as_slice(), &[0x11, 0x11, 0x11, 0x11, 0x22, 0x33]);
391 assert_spare_capacity_is_zero(&secret);
392
393 secret.reserve(32);
394 assert!(secret.capacity() >= secret.len() + 32);
395 assert_spare_capacity_is_zero(&secret);
396
397 secret.shrink_to_fit();
398 assert_eq!(secret.capacity(), secret.len());
399 assert_eq!(secret.as_slice(), &[0x11, 0x11, 0x11, 0x11, 0x22, 0x33]);
400 }
401}
402
403#[derive(Clone, Zeroize, ZeroizeOnDrop)]
405pub struct Key {
406 data: Vec<u8>,
407}
408
409impl Key {
410 pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
416 Self { data: data.into() }
417 }
418 pub fn new_zeros(len: usize) -> Self {
419 Self {
420 data: vec![0u8; len],
421 }
422 }
423 pub fn len(&self) -> usize {
424 self.data.len()
425 }
426 pub fn is_empty(&self) -> bool {
427 self.data.is_empty()
428 }
429}
430
431impl From<Vec<u8>> for Key {
432 fn from(data: Vec<u8>) -> Self {
433 Self::new(data)
434 }
435}
436
437impl AsRef<[u8]> for Key {
438 fn as_ref(&self) -> &[u8] {
439 &self.data
440 }
441}
442
443impl AsMut<[u8]> for Key {
444 fn as_mut(&mut self) -> &mut [u8] {
445 &mut self.data
446 }
447}
448
449impl SerializeSecret for Key {
450 fn from_bytes(bytes: &[u8]) -> Result<Self> {
451 Ok(Self::new(bytes))
452 }
453 fn to_bytes_zeroizing(&self) -> Zeroizing<Vec<u8>> {
454 Zeroizing::new(self.data.clone())
455 }
456}
457
458#[derive(Clone, Zeroize)]
460pub struct PublicKey {
461 data: Vec<u8>,
462}
463
464impl PublicKey {
465 pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
470 Self { data: data.into() }
471 }
472 pub fn len(&self) -> usize {
473 self.data.len()
474 }
475 pub fn is_empty(&self) -> bool {
476 self.data.is_empty()
477 }
478}
479
480impl From<Vec<u8>> for PublicKey {
481 fn from(data: Vec<u8>) -> Self {
482 Self::new(data)
483 }
484}
485
486impl AsRef<[u8]> for PublicKey {
487 fn as_ref(&self) -> &[u8] {
488 &self.data
489 }
490}
491
492impl AsMut<[u8]> for PublicKey {
493 fn as_mut(&mut self) -> &mut [u8] {
494 &mut self.data
495 }
496}
497
498impl Serialize for PublicKey {
499 fn to_bytes(&self) -> Vec<u8> {
500 self.data.clone()
501 }
502 fn from_bytes(bytes: &[u8]) -> Result<Self> {
503 Ok(Self::new(bytes))
504 }
505}
506
507#[derive(Clone)]
509pub struct Ciphertext {
510 data: Vec<u8>,
511}
512
513impl Ciphertext {
514 pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
520 Self { data: data.into() }
521 }
522 pub fn len(&self) -> usize {
523 self.data.len()
524 }
525 pub fn is_empty(&self) -> bool {
526 self.data.is_empty()
527 }
528}
529
530impl From<Vec<u8>> for Ciphertext {
531 fn from(data: Vec<u8>) -> Self {
532 Self::new(data)
533 }
534}
535
536impl AsRef<[u8]> for Ciphertext {
537 fn as_ref(&self) -> &[u8] {
538 &self.data
539 }
540}
541
542impl AsMut<[u8]> for Ciphertext {
543 fn as_mut(&mut self) -> &mut [u8] {
544 &mut self.data
545 }
546}
547
548impl Serialize for Ciphertext {
549 fn to_bytes(&self) -> Vec<u8> {
550 self.data.clone()
551 }
552 fn from_bytes(bytes: &[u8]) -> Result<Self> {
553 Ok(Self::new(bytes))
554 }
555}