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
use generic_array::GenericArray;
use salsa20::cipher::{KeyIvInit, StreamCipher};
use salsa20::XSalsa20;
use subtle::ConstantTimeEq;
use zeroize::Zeroize;
use crate::classic::crypto_secretbox::{Key, Mac, Nonce};
use crate::error::Error;
use crate::poly1305::Poly1305;
pub(crate) fn crypto_secretbox_detached_inplace(
data: &mut [u8],
mac: &mut Mac,
nonce: &Nonce,
key: &Key,
) {
let mut cipher = XSalsa20::new(
GenericArray::from_slice(key),
GenericArray::from_slice(nonce),
);
let mut mac_key = crate::poly1305::Key::new();
cipher.apply_keystream(&mut mac_key);
let mut computed_mac = Poly1305::new(&mac_key);
mac_key.zeroize();
cipher.apply_keystream(data);
computed_mac.update(data);
computed_mac.finalize(mac);
}
pub(crate) fn crypto_secretbox_open_detached_inplace(
data: &mut [u8],
mac: &Mac,
nonce: &Nonce,
key: &Key,
) -> Result<(), Error> {
let mut cipher = XSalsa20::new(
GenericArray::from_slice(key),
GenericArray::from_slice(nonce),
);
let mut mac_key = crate::poly1305::Key::new();
cipher.apply_keystream(&mut mac_key);
let mut computed_mac = Poly1305::new(&mac_key);
mac_key.zeroize();
computed_mac.update(data);
let computed_mac = computed_mac.finalize_to_array();
cipher.apply_keystream(data);
if mac.ct_eq(&computed_mac).unwrap_u8() == 1 {
Ok(())
} else {
Err(dryoc_error!("decryption error (authentication failure)"))
}
}