vitaminc_aead/
decrypt.rs

1use crate::{aad::IntoAad, cipher::Unspecified, Cipher, LocalCipherText};
2use vitaminc_protected::{Controlled, Protected};
3use zeroize::Zeroize;
4
5pub trait Decrypt: Sized {
6    type Encrypted;
7
8    fn decrypt<C>(encrypted: Self::Encrypted, cipher: &C) -> Result<Self, Unspecified>
9    where
10        C: Cipher,
11    {
12        Self::decrypt_with_aad(encrypted, cipher, ())
13    }
14
15    fn decrypt_with_aad<'a, C, A>(
16        encrypted: Self::Encrypted,
17        cipher: &C,
18        aad: A,
19    ) -> Result<Self, Unspecified>
20    where
21        C: Cipher,
22        A: IntoAad<'a>;
23}
24
25impl Decrypt for Vec<u8> {
26    type Encrypted = LocalCipherText;
27
28    fn decrypt_with_aad<'a, C, A>(
29        encrypted: Self::Encrypted,
30        cipher: &C,
31        aad: A,
32    ) -> Result<Self, Unspecified>
33    where
34        C: Cipher,
35        A: IntoAad<'a>,
36    {
37        cipher.decrypt_vec(encrypted, aad)
38    }
39}
40
41impl<const N: usize> Decrypt for [u8; N] {
42    type Encrypted = LocalCipherText;
43
44    fn decrypt_with_aad<'a, C, A>(
45        encrypted: Self::Encrypted,
46        cipher: &C,
47        aad: A,
48    ) -> Result<Self, Unspecified>
49    where
50        C: Cipher,
51        A: IntoAad<'a>,
52    {
53        let mut result_vec = cipher.decrypt_vec(encrypted, aad)?;
54        if result_vec.len() != N {
55            // Discard and zeroize the result vector if the length doesn't match
56            result_vec.zeroize();
57            return Err(Unspecified);
58        }
59        result_vec.try_into().map_err(|_| Unspecified)
60    }
61}
62
63impl Decrypt for String {
64    type Encrypted = LocalCipherText;
65
66    fn decrypt_with_aad<'a, C, A>(
67        encrypted: Self::Encrypted,
68        cipher: &C,
69        aad: A,
70    ) -> Result<Self, Unspecified>
71    where
72        C: Cipher,
73        A: IntoAad<'a>,
74    {
75        let bytes = cipher.decrypt_vec(encrypted, aad)?;
76        String::from_utf8(bytes).map_err(|_| Unspecified)
77    }
78}
79
80impl<T> Decrypt for Protected<T>
81where
82    Self: Controlled,
83    <Protected<T> as Controlled>::Inner: Decrypt,
84{
85    type Encrypted = <<Protected<T> as Controlled>::Inner as Decrypt>::Encrypted;
86
87    fn decrypt_with_aad<'a, C, A>(
88        encrypted: Self::Encrypted,
89        cipher: &C,
90        aad: A,
91    ) -> Result<Self, Unspecified>
92    where
93        C: Cipher,
94        A: IntoAad<'a>,
95    {
96        let inner = <Protected<T> as Controlled>::Inner::decrypt_with_aad(encrypted, cipher, aad)?;
97        Ok(Protected::init_from_inner(inner))
98    }
99}