1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use ::stream::StreamCipher;
use ::auth::NonceMac;
use ::hash::GenericHash;
use super::{ AeadCipher, DecryptFail };
use std::marker::PhantomData;
#[derive(Debug, Clone)]
pub struct General<C, M, H> {
cipher: C,
mac: M,
aad: Vec<u8>,
_ext: PhantomData<H>
}
impl<C, M, H> AeadCipher for General<C, M, H>
where
C: StreamCipher,
M: NonceMac,
H: GenericHash
{
fn new(key: &[u8]) -> Self {
let mkey = H::default()
.with_size(M::key_length())
.hash::<Vec<u8>>(key);
General {
cipher: C::new(key),
mac: M::new(&mkey),
aad: Vec::new(),
_ext: PhantomData
}
}
#[inline] fn key_length() -> usize { C::key_length() }
#[inline] fn tag_length() -> usize { M::tag_length() }
#[inline] fn nonce_length() -> usize { C::nonce_length() }
fn with_aad(&mut self, aad: &[u8]) -> &mut Self {
self.aad = aad.into();
self
}
fn encrypt(&mut self, nonce: &[u8], data: &[u8]) -> Vec<u8> {
let mnonce = H::default()
.with_size(M::nonce_length())
.hash::<Vec<u8>>(nonce);
let mut output = self.cipher.process(nonce, data);
let mut aad = self.aad.clone();
aad.extend_from_slice(&output);
let mut tag = self.mac
.with_nonce(&mnonce)
.result::<Vec<u8>>(&aad);
output.append(&mut tag);
output
}
fn decrypt(&mut self, nonce: &[u8], data: &[u8]) -> Result<Vec<u8>, DecryptFail> {
if data.len() < Self::tag_length() { Err(DecryptFail::LengthError)? };
let mnonce = H::default()
.with_size(M::nonce_length())
.hash::<Vec<u8>>(nonce);
let (data, tag) = data.split_at(data.len() - Self::tag_length());
let mut aad = self.aad.clone();
aad.extend_from_slice(data);
if self.mac.with_nonce(&mnonce).verify(&aad, tag) {
Ok(self.cipher.process(nonce, data))
} else {
Err(DecryptFail::AuthenticationFail)
}
}
}