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
108
109
110
111
112
113
114
115
116
117
118
119
use std::sync::Arc;
use tink_core::utils::{wrap_err, TinkError};
pub fn new(
h: &tink_core::keyset::Handle,
) -> Result<Box<dyn tink_core::DeterministicAead>, TinkError> {
new_with_key_manager(h, None)
}
fn new_with_key_manager(
h: &tink_core::keyset::Handle,
km: Option<Arc<dyn tink_core::registry::KeyManager>>,
) -> Result<Box<dyn tink_core::DeterministicAead>, TinkError> {
let ps = h
.primitives_with_key_manager(km)
.map_err(|e| wrap_err("daead::factory: cannot obtain primitive set", e))?;
let ret = WrappedDeterministicAead::new(ps)?;
Ok(Box::new(ret))
}
#[derive(Clone)]
struct WrappedDeterministicAead {
ps: tink_core::primitiveset::TypedPrimitiveSet<Box<dyn tink_core::DeterministicAead>>,
}
impl WrappedDeterministicAead {
fn new(
ps: tink_core::primitiveset::PrimitiveSet,
) -> Result<WrappedDeterministicAead, TinkError> {
let entry = match &ps.primary {
None => return Err("daead::factory: no primary primitive".into()),
Some(p) => p,
};
match entry.primitive {
tink_core::Primitive::DeterministicAead(_) => {}
_ => return Err("daead::factory: not a DeterministicAEAD primitive".into()),
};
for (_, primitives) in ps.entries.iter() {
for p in primitives {
match p.primitive {
tink_core::Primitive::DeterministicAead(_) => {}
_ => return Err("daead::factory: not a DeterministicAEAD primitive".into()),
};
}
}
Ok(WrappedDeterministicAead { ps: ps.into() })
}
}
impl tink_core::DeterministicAead for WrappedDeterministicAead {
fn encrypt_deterministically(&self, pt: &[u8], aad: &[u8]) -> Result<Vec<u8>, TinkError> {
let primary = self
.ps
.primary
.as_ref()
.ok_or_else(|| TinkError::new("no primary"))?;
let ct = primary.primitive.encrypt_deterministically(pt, aad)?;
let mut ret = Vec::with_capacity(primary.prefix.len() + ct.len());
ret.extend_from_slice(&primary.prefix);
ret.extend_from_slice(&ct);
Ok(ret)
}
fn decrypt_deterministically(&self, ct: &[u8], aad: &[u8]) -> Result<Vec<u8>, TinkError> {
let prefix_size = tink_core::cryptofmt::NON_RAW_PREFIX_SIZE;
if ct.len() > prefix_size {
let prefix = &ct[..prefix_size];
let ct_no_prefix = &ct[prefix_size..];
if let Some(entries) = self.ps.entries_for_prefix(&prefix) {
for entry in entries {
if let Ok(pt) = entry.primitive.decrypt_deterministically(ct_no_prefix, aad) {
return Ok(pt);
}
}
}
}
if let Some(entries) = self.ps.raw_entries() {
for entry in entries {
if let Ok(pt) = entry.primitive.decrypt_deterministically(ct, aad) {
return Ok(pt);
}
}
}
Err("daead::factory: decryption failed".into())
}
}