1use aws_lc_rs::aead::UnboundKey;
2use vitaminc_aead::{Cipher, Decrypt, Encrypt, IntoAad, LocalCipherText, Unspecified};
3use vitaminc_protected::{Controlled, Protected};
4use vitaminc_random::{Generatable, RandomError, SafeRand};
5
6#[derive(Debug)]
10#[cfg_attr(test, derive(Clone))]
11pub struct Key(Protected<[u8; 32]>);
12
13impl Key {
14 pub(crate) fn as_unbound(&self) -> Result<UnboundKey, Unspecified> {
15 UnboundKey::new(&aws_lc_rs::aead::AES_256_GCM, self.0.risky_ref()).map_err(|_| Unspecified)
16 }
17}
18
19impl From<[u8; 32]> for Key {
20 fn from(key: [u8; 32]) -> Self {
21 Self(Protected::new(key))
22 }
23}
24
25impl Generatable for Key {
26 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
27 Generatable::random(rng).map(Self)
28 }
29}
30
31pub struct EncryptedKey(LocalCipherText);
32
33impl Encrypt for Key {
34 type Encrypted = EncryptedKey;
35
36 fn encrypt_with_aad<'a, C, A>(self, cipher: &C, aad: A) -> Result<Self::Encrypted, Unspecified>
37 where
38 C: Cipher,
39 A: IntoAad<'a>,
40 {
41 self.0.encrypt_with_aad(cipher, aad).map(EncryptedKey)
42 }
43}
44
45impl Decrypt for Key {
46 type Encrypted = EncryptedKey;
47
48 fn decrypt_with_aad<'a, C, A>(
49 encrypted: Self::Encrypted,
50 cipher: &C,
51 aad: A,
52 ) -> Result<Self, Unspecified>
53 where
54 C: Cipher,
55 A: IntoAad<'a>,
56 {
57 Decrypt::decrypt_with_aad(encrypted.0, cipher, aad).map(Self)
58 }
59}
60
61#[cfg(test)]
62pub(crate) mod tests {
63 use super::*;
64 use quickcheck::Arbitrary;
65
66 fn gen_array(g: &mut quickcheck::Gen) -> [u8; 32] {
67 let mut array = [0u8; 32];
68 for byte in array.iter_mut() {
69 *byte = u8::arbitrary(g);
70 }
71 array
72 }
73
74 impl quickcheck::Arbitrary for Key {
75 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
76 let key = gen_array(g);
77 Self(Protected::new(key))
78 }
79 }
80
81 #[derive(Clone, Debug)]
83 pub(crate) struct DifferingKeyPair(pub Key, pub Key);
84
85 #[cfg(test)]
86 impl quickcheck::Arbitrary for DifferingKeyPair {
87 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
88 let raw_a = gen_array(g);
89 let mut raw_b = gen_array(g);
90 while raw_a == raw_b {
91 raw_b = gen_array(g);
92 }
93 Self(Key::from(raw_a), Key::from(raw_b))
94 }
95 }
96}