1 /*
2 * (C) 2019 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6
7 #include <botan/sodium.h>
8 #include <botan/aead.h>
9
10 namespace Botan {
11
12 namespace {
13
sodium_aead_chacha20poly1305_encrypt(uint8_t ctext[],unsigned long long * ctext_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],size_t nonce_len,const uint8_t key[])14 int sodium_aead_chacha20poly1305_encrypt(uint8_t ctext[],
15 unsigned long long* ctext_len,
16 const uint8_t ptext[],
17 size_t ptext_len,
18 const uint8_t ad[],
19 size_t ad_len,
20 const uint8_t nonce[],
21 size_t nonce_len,
22 const uint8_t key[])
23 {
24 auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION);
25
26 chacha20poly1305->set_key(key, 32);
27 chacha20poly1305->set_associated_data(ad, ad_len);
28 chacha20poly1305->start(nonce, nonce_len);
29
30 // FIXME do this in-place
31 secure_vector<uint8_t> buf;
32 buf.reserve(ptext_len + 16);
33 buf.assign(ptext, ptext + ptext_len);
34
35 chacha20poly1305->finish(buf);
36
37 copy_mem(ctext, buf.data(), buf.size());
38 if(ctext_len)
39 *ctext_len = buf.size();
40 return 0;
41 }
42
sodium_aead_chacha20poly1305_decrypt(uint8_t ptext[],unsigned long long * ptext_len,const uint8_t ctext[],size_t ctext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],size_t nonce_len,const uint8_t key[])43 int sodium_aead_chacha20poly1305_decrypt(uint8_t ptext[],
44 unsigned long long* ptext_len,
45 const uint8_t ctext[],
46 size_t ctext_len,
47 const uint8_t ad[],
48 size_t ad_len,
49 const uint8_t nonce[],
50 size_t nonce_len,
51 const uint8_t key[])
52 {
53 if(ctext_len < 16)
54 return -1;
55
56 *ptext_len = 0;
57
58 auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION);
59
60 chacha20poly1305->set_key(key, 32);
61 chacha20poly1305->set_associated_data(ad, ad_len);
62 chacha20poly1305->start(nonce, nonce_len);
63
64 // FIXME do this in-place
65 secure_vector<uint8_t> buf;
66 buf.assign(ctext, ctext + ctext_len);
67
68 try
69 {
70 chacha20poly1305->finish(buf);
71 }
72 catch(Invalid_Authentication_Tag&)
73 {
74 return -1;
75 }
76
77 *ptext_len = ctext_len - 16;
78
79 copy_mem(ptext, buf.data(), buf.size());
80 return 0;
81 }
82
sodium_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[],uint8_t mac[],const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],size_t nonce_len,const uint8_t key[])83 int sodium_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[],
84 uint8_t mac[],
85 const uint8_t ptext[],
86 size_t ptext_len,
87 const uint8_t ad[],
88 size_t ad_len,
89 const uint8_t nonce[],
90 size_t nonce_len,
91 const uint8_t key[])
92 {
93 auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", ENCRYPTION);
94
95 chacha20poly1305->set_key(key, 32);
96 chacha20poly1305->set_associated_data(ad, ad_len);
97 chacha20poly1305->start(nonce, nonce_len);
98
99 // FIXME do this in-place
100 secure_vector<uint8_t> buf;
101 buf.reserve(ptext_len + 16);
102 buf.assign(ptext, ptext + ptext_len);
103
104 chacha20poly1305->finish(buf);
105
106 copy_mem(ctext, buf.data(), ptext_len);
107 copy_mem(mac, buf.data() + ptext_len, 16);
108 return 0;
109 }
110
sodium_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[],const uint8_t ctext[],size_t ctext_len,const uint8_t mac[],const uint8_t ad[],size_t ad_len,const uint8_t nonce[],size_t nonce_len,const uint8_t key[])111 int sodium_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[],
112 const uint8_t ctext[],
113 size_t ctext_len,
114 const uint8_t mac[],
115 const uint8_t ad[],
116 size_t ad_len,
117 const uint8_t nonce[],
118 size_t nonce_len,
119 const uint8_t key[])
120 {
121 auto chacha20poly1305 = AEAD_Mode::create_or_throw("ChaCha20Poly1305", DECRYPTION);
122
123 chacha20poly1305->set_key(key, 32);
124 chacha20poly1305->set_associated_data(ad, ad_len);
125 chacha20poly1305->start(nonce, nonce_len);
126
127 // FIXME do this in-place
128 secure_vector<uint8_t> buf;
129 buf.reserve(ctext_len + 16);
130 buf.assign(ctext, ctext + ctext_len);
131 buf.insert(buf.end(), mac, mac + 16);
132
133 try
134 {
135 chacha20poly1305->finish(buf);
136 }
137 catch(Invalid_Authentication_Tag&)
138 {
139 return -1;
140 }
141
142 copy_mem(ptext, buf.data(), buf.size());
143 return 0;
144 }
145
146 }
147
crypto_aead_chacha20poly1305_ietf_encrypt(uint8_t ctext[],unsigned long long * ctext_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])148 int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt(uint8_t ctext[],
149 unsigned long long* ctext_len,
150 const uint8_t ptext[],
151 size_t ptext_len,
152 const uint8_t ad[],
153 size_t ad_len,
154 const uint8_t unused_secret_nonce[],
155 const uint8_t nonce[],
156 const uint8_t key[])
157 {
158 BOTAN_UNUSED(unused_secret_nonce);
159
160 return sodium_aead_chacha20poly1305_encrypt(
161 ctext, ctext_len, ptext, ptext_len,
162 ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key);
163 }
164
crypto_aead_chacha20poly1305_ietf_decrypt(uint8_t ptext[],unsigned long long * ptext_len,uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])165 int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt(uint8_t ptext[],
166 unsigned long long* ptext_len,
167 uint8_t unused_secret_nonce[],
168 const uint8_t ctext[],
169 size_t ctext_len,
170 const uint8_t ad[],
171 size_t ad_len,
172 const uint8_t nonce[],
173 const uint8_t key[])
174 {
175 BOTAN_UNUSED(unused_secret_nonce);
176
177 return sodium_aead_chacha20poly1305_decrypt(
178 ptext, ptext_len, ctext, ctext_len,
179 ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key);
180 }
181
crypto_aead_chacha20poly1305_ietf_encrypt_detached(uint8_t ctext[],uint8_t mac[],unsigned long long * mac_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])182 int Sodium::crypto_aead_chacha20poly1305_ietf_encrypt_detached(uint8_t ctext[],
183 uint8_t mac[],
184 unsigned long long* mac_len,
185 const uint8_t ptext[],
186 size_t ptext_len,
187 const uint8_t ad[],
188 size_t ad_len,
189 const uint8_t unused_secret_nonce[],
190 const uint8_t nonce[],
191 const uint8_t key[])
192 {
193 BOTAN_UNUSED(unused_secret_nonce);
194
195 if(mac_len)
196 *mac_len = 16;
197
198 return sodium_aead_chacha20poly1305_encrypt_detached(
199 ctext, mac, ptext, ptext_len,
200 ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key);
201 }
202
crypto_aead_chacha20poly1305_ietf_decrypt_detached(uint8_t ptext[],uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t mac[],const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])203 int Sodium::crypto_aead_chacha20poly1305_ietf_decrypt_detached(uint8_t ptext[],
204 uint8_t unused_secret_nonce[],
205 const uint8_t ctext[],
206 size_t ctext_len,
207 const uint8_t mac[],
208 const uint8_t ad[],
209 size_t ad_len,
210 const uint8_t nonce[],
211 const uint8_t key[])
212 {
213 BOTAN_UNUSED(unused_secret_nonce);
214
215 return sodium_aead_chacha20poly1305_decrypt_detached(
216 ptext, ctext, ctext_len, mac,
217 ad, ad_len, nonce, crypto_aead_chacha20poly1305_ietf_npubbytes(), key);
218 }
219
crypto_aead_chacha20poly1305_encrypt(uint8_t ctext[],unsigned long long * ctext_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])220 int Sodium::crypto_aead_chacha20poly1305_encrypt(uint8_t ctext[],
221 unsigned long long* ctext_len,
222 const uint8_t ptext[],
223 size_t ptext_len,
224 const uint8_t ad[],
225 size_t ad_len,
226 const uint8_t unused_secret_nonce[],
227 const uint8_t nonce[],
228 const uint8_t key[])
229 {
230 BOTAN_UNUSED(unused_secret_nonce);
231 return sodium_aead_chacha20poly1305_encrypt(
232 ctext, ctext_len, ptext, ptext_len,
233 ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key);
234 }
235
crypto_aead_chacha20poly1305_decrypt(uint8_t ptext[],unsigned long long * ptext_len,uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])236 int Sodium::crypto_aead_chacha20poly1305_decrypt(uint8_t ptext[],
237 unsigned long long* ptext_len,
238 uint8_t unused_secret_nonce[],
239 const uint8_t ctext[],
240 size_t ctext_len,
241 const uint8_t ad[],
242 size_t ad_len,
243 const uint8_t nonce[],
244 const uint8_t key[])
245 {
246 BOTAN_UNUSED(unused_secret_nonce);
247 return sodium_aead_chacha20poly1305_decrypt(
248 ptext, ptext_len, ctext, ctext_len,
249 ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key);
250 }
251
crypto_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[],uint8_t mac[],unsigned long long * mac_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])252 int Sodium::crypto_aead_chacha20poly1305_encrypt_detached(uint8_t ctext[],
253 uint8_t mac[],
254 unsigned long long* mac_len,
255 const uint8_t ptext[],
256 size_t ptext_len,
257 const uint8_t ad[],
258 size_t ad_len,
259 const uint8_t unused_secret_nonce[],
260 const uint8_t nonce[],
261 const uint8_t key[])
262 {
263 BOTAN_UNUSED(unused_secret_nonce);
264 if(mac_len)
265 *mac_len = 16;
266
267 return sodium_aead_chacha20poly1305_encrypt_detached(
268 ctext, mac, ptext, ptext_len,
269 ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key);
270 }
271
crypto_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[],uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t mac[],const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])272 int Sodium::crypto_aead_chacha20poly1305_decrypt_detached(uint8_t ptext[],
273 uint8_t unused_secret_nonce[],
274 const uint8_t ctext[],
275 size_t ctext_len,
276 const uint8_t mac[],
277 const uint8_t ad[],
278 size_t ad_len,
279 const uint8_t nonce[],
280 const uint8_t key[])
281 {
282 BOTAN_UNUSED(unused_secret_nonce);
283
284 return sodium_aead_chacha20poly1305_decrypt_detached(
285 ptext, ctext, ctext_len, mac,
286 ad, ad_len, nonce, crypto_aead_chacha20poly1305_npubbytes(), key);
287 }
288
crypto_aead_xchacha20poly1305_ietf_encrypt(uint8_t ctext[],unsigned long long * ctext_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])289 int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt(uint8_t ctext[],
290 unsigned long long* ctext_len,
291 const uint8_t ptext[],
292 size_t ptext_len,
293 const uint8_t ad[],
294 size_t ad_len,
295 const uint8_t unused_secret_nonce[],
296 const uint8_t nonce[],
297 const uint8_t key[])
298 {
299 BOTAN_UNUSED(unused_secret_nonce);
300
301 return sodium_aead_chacha20poly1305_encrypt(
302 ctext, ctext_len, ptext, ptext_len,
303 ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key);
304 }
305
crypto_aead_xchacha20poly1305_ietf_decrypt(uint8_t ptext[],unsigned long long * ptext_len,uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])306 int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt(uint8_t ptext[],
307 unsigned long long* ptext_len,
308 uint8_t unused_secret_nonce[],
309 const uint8_t ctext[],
310 size_t ctext_len,
311 const uint8_t ad[],
312 size_t ad_len,
313 const uint8_t nonce[],
314 const uint8_t key[])
315 {
316 BOTAN_UNUSED(unused_secret_nonce);
317
318 return sodium_aead_chacha20poly1305_decrypt(
319 ptext, ptext_len, ctext, ctext_len,
320 ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key);
321 }
322
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(uint8_t ctext[],uint8_t mac[],unsigned long long * mac_len,const uint8_t ptext[],size_t ptext_len,const uint8_t ad[],size_t ad_len,const uint8_t unused_secret_nonce[],const uint8_t nonce[],const uint8_t key[])323 int Sodium::crypto_aead_xchacha20poly1305_ietf_encrypt_detached(uint8_t ctext[],
324 uint8_t mac[],
325 unsigned long long* mac_len,
326 const uint8_t ptext[],
327 size_t ptext_len,
328 const uint8_t ad[],
329 size_t ad_len,
330 const uint8_t unused_secret_nonce[],
331 const uint8_t nonce[],
332 const uint8_t key[])
333 {
334 BOTAN_UNUSED(unused_secret_nonce);
335 if(mac_len)
336 *mac_len = 16;
337
338 return sodium_aead_chacha20poly1305_encrypt_detached(
339 ctext, mac, ptext, ptext_len,
340 ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key);
341 }
342
crypto_aead_xchacha20poly1305_ietf_decrypt_detached(uint8_t ptext[],uint8_t unused_secret_nonce[],const uint8_t ctext[],size_t ctext_len,const uint8_t mac[],const uint8_t ad[],size_t ad_len,const uint8_t nonce[],const uint8_t key[])343 int Sodium::crypto_aead_xchacha20poly1305_ietf_decrypt_detached(uint8_t ptext[],
344 uint8_t unused_secret_nonce[],
345 const uint8_t ctext[],
346 size_t ctext_len,
347 const uint8_t mac[],
348 const uint8_t ad[],
349 size_t ad_len,
350 const uint8_t nonce[],
351 const uint8_t key[])
352 {
353 BOTAN_UNUSED(unused_secret_nonce);
354 return sodium_aead_chacha20poly1305_decrypt_detached(
355 ptext, ctext, ctext_len, mac,
356 ad, ad_len, nonce, crypto_aead_xchacha20poly1305_ietf_npubbytes(), key);
357 }
358
359 }
360