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
120
121
122
123
124
125
126
127
use crate::*;
pub const KEYBYTES: usize =
libsodium_sys::crypto_secretbox_xchacha20poly1305_KEYBYTES as usize;
pub const NONCEBYTES: usize =
libsodium_sys::crypto_secretbox_xchacha20poly1305_NONCEBYTES as usize;
pub const MACBYTES: usize =
libsodium_sys::crypto_secretbox_xchacha20poly1305_MACBYTES as usize;
pub async fn easy<N, M, K>(
nonce: N,
message: M,
shared_key: K,
) -> SodokenResult<BufRead>
where
N: Into<BufReadSized<NONCEBYTES>> + 'static + Send,
M: Into<BufRead> + 'static + Send,
K: Into<BufReadSized<KEYBYTES>> + 'static + Send,
{
let nonce = nonce.into();
let message = message.into();
let shared_key = shared_key.into();
tokio_exec_blocking(move || {
let nonce = nonce.read_lock_sized();
let message = message.read_lock();
let shared_key = shared_key.read_lock_sized();
let cipher = safe::sodium::crypto_secretbox_xchacha20poly1305_easy(
&nonce,
&message,
&shared_key,
)?;
Ok(cipher.into())
})
.await
}
pub fn open_easy_msg_len(cipher_len: usize) -> usize {
cipher_len - MACBYTES
}
pub async fn open_easy<N, M, C, K>(
nonce: N,
message: M,
cipher: C,
shared_key: K,
) -> SodokenResult<()>
where
N: Into<BufReadSized<NONCEBYTES>> + 'static + Send,
M: Into<BufWrite> + 'static + Send,
C: Into<BufRead> + 'static + Send,
K: Into<BufReadSized<KEYBYTES>> + 'static + Send,
{
let nonce = nonce.into();
let message = message.into();
let cipher = cipher.into();
let shared_key = shared_key.into();
tokio_exec_blocking(move || {
let nonce = nonce.read_lock_sized();
let mut message = message.write_lock();
let cipher = cipher.read_lock();
let shared_key = shared_key.read_lock_sized();
safe::sodium::crypto_secretbox_xchacha20poly1305_open_easy(
&nonce,
&mut message,
&cipher,
&shared_key,
)
})
.await
}
#[cfg(test)]
mod tests {
use crate::*;
#[tokio::test(flavor = "multi_thread")]
async fn test_secretbox() -> SodokenResult<()> {
let nonce: BufReadSized<{ secretbox::xchacha20poly1305::NONCEBYTES }> =
BufReadSized::new_no_lock(
[0; secretbox::xchacha20poly1305::NONCEBYTES],
);
let shared_key: BufWriteSized<
{ secretbox::xchacha20poly1305::KEYBYTES },
> = BufWriteSized::new_mem_locked()?;
let msg = BufRead::new_no_lock(b"test message");
random::bytes_buf(shared_key.clone()).await?;
let cipher = secretbox::xchacha20poly1305::easy(
nonce.clone(),
msg.clone(),
shared_key.clone(),
)
.await?;
assert_ne!(&*msg.read_lock(), &*cipher.read_lock());
let msg_len = secretbox::xchacha20poly1305::open_easy_msg_len(
cipher.read_lock().len(),
);
let msg2 = BufWrite::new_no_lock(msg_len);
secretbox::xchacha20poly1305::open_easy(
nonce.clone(),
msg2.clone(),
cipher.clone(),
shared_key.clone(),
)
.await?;
assert_eq!(&*msg.read_lock(), &*msg2.read_lock());
Ok(())
}
}