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