/src/wolfssl-disable-fastmath/wolfcrypt/src/chacha20_poly1305.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* chacha.c |
2 | | * |
3 | | * Copyright (C) 2006-2022 wolfSSL Inc. |
4 | | * |
5 | | * This file is part of wolfSSL. |
6 | | * |
7 | | * wolfSSL is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * wolfSSL is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
20 | | */ |
21 | | /* |
22 | | |
23 | | DESCRIPTION |
24 | | This library contains implementation for the ChaCha20 stream cipher and |
25 | | the Poly1305 authenticator, both as as combined-mode, |
26 | | or Authenticated Encryption with Additional Data (AEAD) algorithm. |
27 | | |
28 | | */ |
29 | | |
30 | | #ifdef HAVE_CONFIG_H |
31 | | #include <config.h> |
32 | | #endif |
33 | | |
34 | | #include <wolfssl/wolfcrypt/settings.h> |
35 | | |
36 | | #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) |
37 | | |
38 | | #include <wolfssl/wolfcrypt/chacha20_poly1305.h> |
39 | | #include <wolfssl/wolfcrypt/error-crypt.h> |
40 | | #include <wolfssl/wolfcrypt/logging.h> |
41 | | |
42 | | #ifdef NO_INLINE |
43 | | #include <wolfssl/wolfcrypt/misc.h> |
44 | | #else |
45 | | #define WOLFSSL_MISC_INCLUDED |
46 | | #include <wolfcrypt/src/misc.c> |
47 | | #endif |
48 | | |
49 | 0 | #define CHACHA20_POLY1305_AEAD_INITIAL_COUNTER 0 |
50 | | WOLFSSL_ABI |
51 | | int wc_ChaCha20Poly1305_Encrypt( |
52 | | const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], |
53 | | const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], |
54 | | const byte* inAAD, const word32 inAADLen, |
55 | | const byte* inPlaintext, const word32 inPlaintextLen, |
56 | | byte* outCiphertext, |
57 | | byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]) |
58 | 0 | { |
59 | 0 | int ret; |
60 | 0 | ChaChaPoly_Aead aead; |
61 | | |
62 | | /* Validate function arguments */ |
63 | 0 | if (!inKey || !inIV || |
64 | 0 | (inPlaintextLen > 0 && inPlaintext == NULL) || |
65 | 0 | !outCiphertext || |
66 | 0 | !outAuthTag) |
67 | 0 | { |
68 | 0 | return BAD_FUNC_ARG; |
69 | 0 | } |
70 | | |
71 | 0 | ret = wc_ChaCha20Poly1305_Init(&aead, inKey, inIV, |
72 | 0 | CHACHA20_POLY1305_AEAD_ENCRYPT); |
73 | 0 | if (ret == 0) |
74 | 0 | ret = wc_ChaCha20Poly1305_UpdateAad(&aead, inAAD, inAADLen); |
75 | 0 | if (ret == 0) |
76 | 0 | ret = wc_ChaCha20Poly1305_UpdateData(&aead, inPlaintext, outCiphertext, |
77 | 0 | inPlaintextLen); |
78 | 0 | if (ret == 0) |
79 | 0 | ret = wc_ChaCha20Poly1305_Final(&aead, outAuthTag); |
80 | 0 | return ret; |
81 | 0 | } |
82 | | |
83 | | WOLFSSL_ABI |
84 | | int wc_ChaCha20Poly1305_Decrypt( |
85 | | const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], |
86 | | const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], |
87 | | const byte* inAAD, const word32 inAADLen, |
88 | | const byte* inCiphertext, const word32 inCiphertextLen, |
89 | | const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE], |
90 | | byte* outPlaintext) |
91 | 0 | { |
92 | 0 | int ret; |
93 | 0 | ChaChaPoly_Aead aead; |
94 | 0 | byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; |
95 | | |
96 | | /* Validate function arguments */ |
97 | 0 | if (!inKey || !inIV || |
98 | 0 | (inCiphertextLen > 0 && inCiphertext == NULL) || |
99 | 0 | !inAuthTag || |
100 | 0 | !outPlaintext) |
101 | 0 | { |
102 | 0 | return BAD_FUNC_ARG; |
103 | 0 | } |
104 | | |
105 | 0 | XMEMSET(calculatedAuthTag, 0, sizeof(calculatedAuthTag)); |
106 | |
|
107 | 0 | ret = wc_ChaCha20Poly1305_Init(&aead, inKey, inIV, |
108 | 0 | CHACHA20_POLY1305_AEAD_DECRYPT); |
109 | 0 | if (ret == 0) |
110 | 0 | ret = wc_ChaCha20Poly1305_UpdateAad(&aead, inAAD, inAADLen); |
111 | 0 | if (ret == 0) |
112 | 0 | ret = wc_ChaCha20Poly1305_UpdateData(&aead, inCiphertext, outPlaintext, |
113 | 0 | inCiphertextLen); |
114 | 0 | if (ret == 0) |
115 | 0 | ret = wc_ChaCha20Poly1305_Final(&aead, calculatedAuthTag); |
116 | 0 | if (ret == 0) |
117 | 0 | ret = wc_ChaCha20Poly1305_CheckTag(inAuthTag, calculatedAuthTag); |
118 | 0 | return ret; |
119 | 0 | } |
120 | | |
121 | | int wc_ChaCha20Poly1305_CheckTag( |
122 | | const byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE], |
123 | | const byte authTagChk[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]) |
124 | 0 | { |
125 | 0 | int ret = 0; |
126 | 0 | if (authTag == NULL || authTagChk == NULL) { |
127 | 0 | return BAD_FUNC_ARG; |
128 | 0 | } |
129 | 0 | if (ConstantCompare(authTag, authTagChk, |
130 | 0 | CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) != 0) { |
131 | 0 | ret = MAC_CMP_FAILED_E; |
132 | 0 | } |
133 | 0 | return ret; |
134 | 0 | } |
135 | | |
136 | | int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead, |
137 | | const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], |
138 | | const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], |
139 | | int isEncrypt) |
140 | 0 | { |
141 | 0 | int ret; |
142 | 0 | byte authKey[CHACHA20_POLY1305_AEAD_KEYSIZE]; |
143 | | |
144 | | /* check arguments */ |
145 | 0 | if (aead == NULL || inKey == NULL || inIV == NULL) { |
146 | 0 | return BAD_FUNC_ARG; |
147 | 0 | } |
148 | | |
149 | | /* setup aead context */ |
150 | 0 | XMEMSET(aead, 0, sizeof(ChaChaPoly_Aead)); |
151 | 0 | XMEMSET(authKey, 0, sizeof(authKey)); |
152 | 0 | aead->isEncrypt = (byte)isEncrypt; |
153 | | |
154 | | /* Initialize the ChaCha20 context (key and iv) */ |
155 | 0 | ret = wc_Chacha_SetKey(&aead->chacha, inKey, |
156 | 0 | CHACHA20_POLY1305_AEAD_KEYSIZE); |
157 | 0 | if (ret == 0) { |
158 | 0 | ret = wc_Chacha_SetIV(&aead->chacha, inIV, |
159 | 0 | CHACHA20_POLY1305_AEAD_INITIAL_COUNTER); |
160 | 0 | } |
161 | | |
162 | | /* Create the Poly1305 key */ |
163 | 0 | if (ret == 0) { |
164 | 0 | ret = wc_Chacha_Process(&aead->chacha, authKey, authKey, |
165 | 0 | CHACHA20_POLY1305_AEAD_KEYSIZE); |
166 | 0 | } |
167 | | |
168 | | /* Initialize Poly1305 context */ |
169 | 0 | if (ret == 0) { |
170 | 0 | ret = wc_Poly1305SetKey(&aead->poly, authKey, |
171 | 0 | CHACHA20_POLY1305_AEAD_KEYSIZE); |
172 | 0 | } |
173 | | |
174 | | /* advance counter by 1 after creating Poly1305 key */ |
175 | 0 | if (ret == 0) { |
176 | 0 | ret = wc_Chacha_SetIV(&aead->chacha, inIV, |
177 | 0 | CHACHA20_POLY1305_AEAD_INITIAL_COUNTER + 1); |
178 | 0 | } |
179 | |
|
180 | 0 | if (ret == 0) { |
181 | 0 | aead->state = CHACHA20_POLY1305_STATE_READY; |
182 | 0 | } |
183 | |
|
184 | 0 | return ret; |
185 | 0 | } |
186 | | |
187 | | /* optional additional authentication data */ |
188 | | int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead, |
189 | | const byte* inAAD, word32 inAADLen) |
190 | 0 | { |
191 | 0 | int ret = 0; |
192 | |
|
193 | 0 | if (aead == NULL || (inAAD == NULL && inAADLen > 0)) { |
194 | 0 | return BAD_FUNC_ARG; |
195 | 0 | } |
196 | 0 | if (aead->state != CHACHA20_POLY1305_STATE_READY && |
197 | 0 | aead->state != CHACHA20_POLY1305_STATE_AAD) { |
198 | 0 | return BAD_STATE_E; |
199 | 0 | } |
200 | 0 | if (inAADLen > CHACHA20_POLY1305_MAX - aead->aadLen) |
201 | 0 | return CHACHA_POLY_OVERFLOW; |
202 | | |
203 | 0 | if (inAAD && inAADLen > 0) { |
204 | 0 | ret = wc_Poly1305Update(&aead->poly, inAAD, inAADLen); |
205 | 0 | if (ret == 0) { |
206 | 0 | aead->aadLen += inAADLen; |
207 | 0 | aead->state = CHACHA20_POLY1305_STATE_AAD; |
208 | 0 | } |
209 | 0 | } |
210 | |
|
211 | 0 | return ret; |
212 | 0 | } |
213 | | |
214 | | /* inData and outData can be same pointer (inline) */ |
215 | | int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead, |
216 | | const byte* inData, byte* outData, word32 dataLen) |
217 | 0 | { |
218 | 0 | int ret = 0; |
219 | |
|
220 | 0 | if (aead == NULL || inData == NULL || outData == NULL) { |
221 | 0 | return BAD_FUNC_ARG; |
222 | 0 | } |
223 | 0 | if (aead->state != CHACHA20_POLY1305_STATE_READY && |
224 | 0 | aead->state != CHACHA20_POLY1305_STATE_AAD && |
225 | 0 | aead->state != CHACHA20_POLY1305_STATE_DATA) { |
226 | 0 | return BAD_STATE_E; |
227 | 0 | } |
228 | 0 | if (dataLen > CHACHA20_POLY1305_MAX - aead->dataLen) |
229 | 0 | return CHACHA_POLY_OVERFLOW; |
230 | | |
231 | | /* Pad the AAD */ |
232 | 0 | if (aead->state == CHACHA20_POLY1305_STATE_AAD) { |
233 | 0 | ret = wc_Poly1305_Pad(&aead->poly, aead->aadLen); |
234 | 0 | } |
235 | | |
236 | | /* advance state */ |
237 | 0 | aead->state = CHACHA20_POLY1305_STATE_DATA; |
238 | | |
239 | | /* Perform ChaCha20 encrypt/decrypt and Poly1305 auth calc */ |
240 | 0 | if (ret == 0) { |
241 | 0 | if (aead->isEncrypt) { |
242 | 0 | ret = wc_Chacha_Process(&aead->chacha, outData, inData, dataLen); |
243 | 0 | if (ret == 0) |
244 | 0 | ret = wc_Poly1305Update(&aead->poly, outData, dataLen); |
245 | 0 | } |
246 | 0 | else { |
247 | 0 | ret = wc_Poly1305Update(&aead->poly, inData, dataLen); |
248 | 0 | if (ret == 0) |
249 | 0 | ret = wc_Chacha_Process(&aead->chacha, outData, inData, dataLen); |
250 | 0 | } |
251 | 0 | } |
252 | 0 | if (ret == 0) { |
253 | 0 | aead->dataLen += dataLen; |
254 | 0 | } |
255 | 0 | return ret; |
256 | 0 | } |
257 | | |
258 | | int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead, |
259 | | byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]) |
260 | 0 | { |
261 | 0 | int ret = 0; |
262 | |
|
263 | 0 | if (aead == NULL || outAuthTag == NULL) { |
264 | 0 | return BAD_FUNC_ARG; |
265 | 0 | } |
266 | 0 | if (aead->state != CHACHA20_POLY1305_STATE_AAD && |
267 | 0 | aead->state != CHACHA20_POLY1305_STATE_DATA) { |
268 | 0 | return BAD_STATE_E; |
269 | 0 | } |
270 | | |
271 | | /* Pad the AAD - Make sure it is done */ |
272 | 0 | if (aead->state == CHACHA20_POLY1305_STATE_AAD) { |
273 | 0 | ret = wc_Poly1305_Pad(&aead->poly, aead->aadLen); |
274 | 0 | } |
275 | | |
276 | | /* Pad the plaintext/ciphertext to 16 bytes */ |
277 | 0 | if (ret == 0) { |
278 | 0 | ret = wc_Poly1305_Pad(&aead->poly, aead->dataLen); |
279 | 0 | } |
280 | | |
281 | | /* Add the aad length and plaintext/ciphertext length */ |
282 | 0 | if (ret == 0) { |
283 | 0 | ret = wc_Poly1305_EncodeSizes(&aead->poly, aead->aadLen, |
284 | 0 | aead->dataLen); |
285 | 0 | } |
286 | | |
287 | | /* Finalize the auth tag */ |
288 | 0 | if (ret == 0) { |
289 | 0 | ret = wc_Poly1305Final(&aead->poly, outAuthTag); |
290 | 0 | } |
291 | | |
292 | | /* reset and cleanup sensitive context */ |
293 | 0 | ForceZero(aead, sizeof(ChaChaPoly_Aead)); |
294 | |
|
295 | 0 | return ret; |
296 | 0 | } |
297 | | |
298 | | #ifdef HAVE_XCHACHA |
299 | | |
300 | | int wc_XChaCha20Poly1305_Init( |
301 | | ChaChaPoly_Aead *aead, |
302 | | const byte *ad, word32 ad_len, |
303 | | const byte *nonce, word32 nonce_len, |
304 | | const byte *key, word32 key_len, |
305 | | int isEncrypt) |
306 | 0 | { |
307 | 0 | byte authKey[CHACHA20_POLY1305_AEAD_KEYSIZE]; |
308 | 0 | int ret; |
309 | |
|
310 | 0 | if ((ad == NULL) || (nonce == NULL) || (key == NULL)) |
311 | 0 | return BAD_FUNC_ARG; |
312 | | |
313 | 0 | if ((key_len != CHACHA20_POLY1305_AEAD_KEYSIZE) || |
314 | 0 | (nonce_len != XCHACHA20_POLY1305_AEAD_NONCE_SIZE)) |
315 | 0 | return BAD_FUNC_ARG; |
316 | | |
317 | 0 | if ((ret = wc_XChacha_SetKey(&aead->chacha, |
318 | 0 | key, key_len, |
319 | 0 | nonce, nonce_len, |
320 | 0 | 0 /* counter */)) < 0) |
321 | 0 | return ret; |
322 | | |
323 | 0 | XMEMSET(authKey, 0, sizeof authKey); |
324 | | |
325 | | /* Create the Poly1305 key */ |
326 | 0 | if ((ret = wc_Chacha_Process(&aead->chacha, authKey, authKey, |
327 | 0 | (word32)sizeof authKey)) < 0) |
328 | 0 | return ret; |
329 | | /* advance to start of the next ChaCha block. */ |
330 | 0 | wc_Chacha_purge_current_block(&aead->chacha); |
331 | | |
332 | | /* Initialize Poly1305 context */ |
333 | 0 | if ((ret = wc_Poly1305SetKey(&aead->poly, authKey, |
334 | 0 | (word32)sizeof authKey)) < 0) |
335 | 0 | return ret; |
336 | | |
337 | 0 | if ((ret = wc_Poly1305Update(&aead->poly, ad, (word32)ad_len)) < 0) |
338 | 0 | return ret; |
339 | | |
340 | 0 | if ((ret = wc_Poly1305_Pad(&aead->poly, (word32)ad_len)) < 0) |
341 | 0 | return ret; |
342 | | |
343 | 0 | aead->isEncrypt = (byte)isEncrypt; |
344 | 0 | aead->state = CHACHA20_POLY1305_STATE_AAD; |
345 | |
|
346 | 0 | return 0; |
347 | 0 | } |
348 | | |
349 | | static WC_INLINE int wc_XChaCha20Poly1305_crypt_oneshot( |
350 | | byte *dst, const size_t dst_space, |
351 | | const byte *src, const size_t src_len, |
352 | | const byte *ad, const size_t ad_len, |
353 | | const byte *nonce, const size_t nonce_len, |
354 | | const byte *key, const size_t key_len, |
355 | | int isEncrypt) |
356 | 0 | { |
357 | 0 | int ret; |
358 | 0 | ssize_t dst_len = isEncrypt ? |
359 | 0 | (ssize_t)src_len + POLY1305_DIGEST_SIZE : |
360 | 0 | (ssize_t)src_len - POLY1305_DIGEST_SIZE; |
361 | 0 | const byte *src_i; |
362 | 0 | byte *dst_i; |
363 | 0 | size_t src_len_rem; |
364 | 0 | #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) |
365 | 0 | ChaChaPoly_Aead *aead = (ChaChaPoly_Aead *)XMALLOC(sizeof *aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
366 | |
|
367 | 0 | if (aead == NULL) |
368 | 0 | return MEMORY_E; |
369 | | #else |
370 | | ChaChaPoly_Aead aead_buf, *aead = &aead_buf; |
371 | | #endif |
372 | | |
373 | 0 | if ((dst == NULL) || (src == NULL)) { |
374 | 0 | ret = BAD_FUNC_ARG; |
375 | 0 | goto out; |
376 | 0 | } |
377 | | |
378 | 0 | if ((ssize_t)dst_space < dst_len) { |
379 | 0 | ret = BUFFER_E; |
380 | 0 | goto out; |
381 | 0 | } |
382 | | |
383 | 0 | if ((ret = wc_XChaCha20Poly1305_Init(aead, ad, (word32)ad_len, |
384 | 0 | nonce, (word32)nonce_len, |
385 | 0 | key, (word32)key_len, 1)) < 0) |
386 | 0 | goto out; |
387 | | |
388 | | #ifdef WOLFSSL_CHECK_MEM_ZERO |
389 | | wc_MemZero_Add("wc_XChaCha20Poly1305_crypt_oneshot aead", aead, |
390 | | sizeof(ChaChaPoly_Aead)); |
391 | | #endif |
392 | | |
393 | | /* process the input in 16k pieces to accommodate src_lens that don't fit in a word32, |
394 | | * and to exploit hot cache for the input data. |
395 | | */ |
396 | 0 | src_i = src; |
397 | 0 | src_len_rem = isEncrypt ? src_len : (size_t)dst_len; |
398 | 0 | dst_i = dst; |
399 | 0 | while (src_len_rem > 0) { |
400 | 0 | word32 this_src_len = |
401 | 0 | (src_len_rem > 16384) ? |
402 | 0 | 16384 : |
403 | 0 | (word32)src_len_rem; |
404 | |
|
405 | 0 | if ((ret = wc_Chacha_Process(&aead->chacha, dst_i, src_i, this_src_len)) < 0) |
406 | 0 | goto out; |
407 | | |
408 | 0 | if ((ret = wc_Poly1305Update(&aead->poly, isEncrypt ? dst_i : src_i, this_src_len)) < 0) |
409 | 0 | goto out; |
410 | | |
411 | 0 | src_len_rem -= (size_t)this_src_len; |
412 | 0 | src_i += this_src_len; |
413 | 0 | dst_i += this_src_len; |
414 | 0 | } |
415 | | |
416 | 0 | if (aead->poly.leftover) { |
417 | 0 | if ((ret = wc_Poly1305_Pad(&aead->poly, (word32)aead->poly.leftover)) < 0) |
418 | 0 | return ret; |
419 | 0 | } |
420 | | |
421 | 0 | #ifdef WORD64_AVAILABLE |
422 | 0 | ret = wc_Poly1305_EncodeSizes64(&aead->poly, ad_len, isEncrypt ? src_len : (size_t)dst_len); |
423 | | #else |
424 | | ret = wc_Poly1305_EncodeSizes(&aead->poly, ad_len, isEncrypt ? src_len : (size_t)dst_len); |
425 | | #endif |
426 | 0 | if (ret < 0) |
427 | 0 | goto out; |
428 | | |
429 | 0 | if (isEncrypt) |
430 | 0 | ret = wc_Poly1305Final(&aead->poly, dst + src_len); |
431 | 0 | else { |
432 | 0 | byte outAuthTag[POLY1305_DIGEST_SIZE]; |
433 | |
|
434 | 0 | if ((ret = wc_Poly1305Final(&aead->poly, outAuthTag)) < 0) |
435 | 0 | goto out; |
436 | | |
437 | 0 | if (ConstantCompare(outAuthTag, src + dst_len, POLY1305_DIGEST_SIZE) != 0) { |
438 | 0 | ret = MAC_CMP_FAILED_E; |
439 | 0 | goto out; |
440 | 0 | } |
441 | 0 | } |
442 | | |
443 | 0 | out: |
444 | |
|
445 | 0 | ForceZero(aead, sizeof *aead); |
446 | |
|
447 | 0 | #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) |
448 | 0 | XFREE(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
449 | | #elif defined(WOLFSSL_CHECK_MEM_ZERO) |
450 | | wc_MemZero_Check(aead, sizeof(ChaChaPoly_Aead)); |
451 | | #endif |
452 | |
|
453 | 0 | return ret; |
454 | 0 | } |
455 | | |
456 | | int wc_XChaCha20Poly1305_Encrypt( |
457 | | byte *dst, const size_t dst_space, |
458 | | const byte *src, const size_t src_len, |
459 | | const byte *ad, const size_t ad_len, |
460 | | const byte *nonce, const size_t nonce_len, |
461 | | const byte *key, const size_t key_len) |
462 | 0 | { |
463 | 0 | return wc_XChaCha20Poly1305_crypt_oneshot(dst, dst_space, src, src_len, ad, ad_len, nonce, nonce_len, key, key_len, 1); |
464 | 0 | } |
465 | | |
466 | | int wc_XChaCha20Poly1305_Decrypt( |
467 | | byte *dst, const size_t dst_space, |
468 | | const byte *src, const size_t src_len, |
469 | | const byte *ad, const size_t ad_len, |
470 | | const byte *nonce, const size_t nonce_len, |
471 | | const byte *key, const size_t key_len) |
472 | 0 | { |
473 | 0 | return wc_XChaCha20Poly1305_crypt_oneshot(dst, dst_space, src, src_len, ad, ad_len, nonce, nonce_len, key, key_len, 0); |
474 | 0 | } |
475 | | |
476 | | #endif /* HAVE_XCHACHA */ |
477 | | |
478 | | #endif /* HAVE_CHACHA && HAVE_POLY1305 */ |