1 /* $OpenBSD: e_chacha20poly1305.c,v 1.26 2022/09/13 04:59:18 jsing Exp $ */
2 
3 /*
4  * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
5  * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
6  * Copyright (c) 2014, Google Inc.
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
15  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
17  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include <openssl/opensslconf.h>
25 
26 #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
27 
28 #include <openssl/err.h>
29 #include <openssl/evp.h>
30 #include <openssl/chacha.h>
31 #include <openssl/poly1305.h>
32 
33 #include "bytestring.h"
34 #include "evp_locl.h"
35 
36 #define POLY1305_TAG_LEN 16
37 
38 #define CHACHA20_CONSTANT_LEN 4
39 #define CHACHA20_IV_LEN 8
40 #define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
41 #define XCHACHA20_NONCE_LEN 24
42 
43 struct aead_chacha20_poly1305_ctx {
44 	unsigned char key[32];
45 	unsigned char tag_len;
46 };
47 
48 static int
49 aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,
50     size_t key_len, size_t tag_len)
51 {
52 	struct aead_chacha20_poly1305_ctx *c20_ctx;
53 
54 	if (tag_len == 0)
55 		tag_len = POLY1305_TAG_LEN;
56 
57 	if (tag_len > POLY1305_TAG_LEN) {
58 		EVPerror(EVP_R_TOO_LARGE);
59 		return 0;
60 	}
61 
62 	/* Internal error - EVP_AEAD_CTX_init should catch this. */
63 	if (key_len != sizeof(c20_ctx->key))
64 		return 0;
65 
66 	c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));
67 	if (c20_ctx == NULL)
68 		return 0;
69 
70 	memcpy(&c20_ctx->key[0], key, key_len);
71 	c20_ctx->tag_len = tag_len;
72 	ctx->aead_state = c20_ctx;
73 
74 	return 1;
75 }
76 
77 static void
78 aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)
79 {
80 	struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
81 
82 	freezero(c20_ctx, sizeof(*c20_ctx));
83 }
84 
85 static void
86 poly1305_update_with_length(poly1305_state *poly1305,
87     const unsigned char *data, size_t data_len)
88 {
89 	size_t j = data_len;
90 	unsigned char length_bytes[8];
91 	unsigned i;
92 
93 	for (i = 0; i < sizeof(length_bytes); i++) {
94 		length_bytes[i] = j;
95 		j >>= 8;
96 	}
97 
98 	if (data != NULL)
99 		CRYPTO_poly1305_update(poly1305, data, data_len);
100 	CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
101 }
102 
103 static void
104 poly1305_pad16(poly1305_state *poly1305, size_t data_len)
105 {
106 	static const unsigned char zero_pad16[16];
107 	size_t pad_len;
108 
109 	/* pad16() is defined in RFC 7539 2.8.1. */
110 	if ((pad_len = data_len % 16) == 0)
111 		return;
112 
113 	CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
114 }
115 
116 static void
117 poly1305_update_with_pad16(poly1305_state *poly1305,
118     const unsigned char *data, size_t data_len)
119 {
120 	CRYPTO_poly1305_update(poly1305, data, data_len);
121 	poly1305_pad16(poly1305, data_len);
122 }
123 
124 static int
125 aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
126     size_t *out_len, size_t max_out_len, const unsigned char *nonce,
127     size_t nonce_len, const unsigned char *in, size_t in_len,
128     const unsigned char *ad, size_t ad_len)
129 {
130 	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
131 	unsigned char poly1305_key[32];
132 	poly1305_state poly1305;
133 	const unsigned char *iv;
134 	uint64_t ctr;
135 
136 	if (max_out_len < in_len + c20_ctx->tag_len) {
137 		EVPerror(EVP_R_BUFFER_TOO_SMALL);
138 		return 0;
139 	}
140 
141 	if (nonce_len != ctx->aead->nonce_len) {
142 		EVPerror(EVP_R_IV_TOO_LARGE);
143 		return 0;
144 	}
145 
146 	ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 |
147 	    (uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32;
148 	iv = nonce + CHACHA20_CONSTANT_LEN;
149 
150 	memset(poly1305_key, 0, sizeof(poly1305_key));
151 	CRYPTO_chacha_20(poly1305_key, poly1305_key,
152 	    sizeof(poly1305_key), c20_ctx->key, iv, ctr);
153 
154 	CRYPTO_poly1305_init(&poly1305, poly1305_key);
155 	poly1305_update_with_pad16(&poly1305, ad, ad_len);
156 	CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
157 	poly1305_update_with_pad16(&poly1305, out, in_len);
158 	poly1305_update_with_length(&poly1305, NULL, ad_len);
159 	poly1305_update_with_length(&poly1305, NULL, in_len);
160 
161 	if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
162 		unsigned char tag[POLY1305_TAG_LEN];
163 		CRYPTO_poly1305_finish(&poly1305, tag);
164 		memcpy(out + in_len, tag, c20_ctx->tag_len);
165 		*out_len = in_len + c20_ctx->tag_len;
166 		return 1;
167 	}
168 
169 	CRYPTO_poly1305_finish(&poly1305, out + in_len);
170 	*out_len = in_len + POLY1305_TAG_LEN;
171 	return 1;
172 }
173 
174 static int
175 aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
176     size_t *out_len, size_t max_out_len, const unsigned char *nonce,
177     size_t nonce_len, const unsigned char *in, size_t in_len,
178     const unsigned char *ad, size_t ad_len)
179 {
180 	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
181 	unsigned char mac[POLY1305_TAG_LEN];
182 	unsigned char poly1305_key[32];
183 	const unsigned char *iv = nonce;
184 	poly1305_state poly1305;
185 	size_t plaintext_len;
186 	uint64_t ctr = 0;
187 
188 	if (in_len < c20_ctx->tag_len) {
189 		EVPerror(EVP_R_BAD_DECRYPT);
190 		return 0;
191 	}
192 
193 	if (nonce_len != ctx->aead->nonce_len) {
194 		EVPerror(EVP_R_IV_TOO_LARGE);
195 		return 0;
196 	}
197 
198 	plaintext_len = in_len - c20_ctx->tag_len;
199 
200 	if (max_out_len < plaintext_len) {
201 		EVPerror(EVP_R_BUFFER_TOO_SMALL);
202 		return 0;
203 	}
204 
205 	ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 |
206 	    (uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32;
207 	iv = nonce + CHACHA20_CONSTANT_LEN;
208 
209 	memset(poly1305_key, 0, sizeof(poly1305_key));
210 	CRYPTO_chacha_20(poly1305_key, poly1305_key,
211 	    sizeof(poly1305_key), c20_ctx->key, iv, ctr);
212 
213 	CRYPTO_poly1305_init(&poly1305, poly1305_key);
214 	poly1305_update_with_pad16(&poly1305, ad, ad_len);
215 	poly1305_update_with_pad16(&poly1305, in, plaintext_len);
216 	poly1305_update_with_length(&poly1305, NULL, ad_len);
217 	poly1305_update_with_length(&poly1305, NULL, plaintext_len);
218 
219 	CRYPTO_poly1305_finish(&poly1305, mac);
220 
221 	if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
222 		EVPerror(EVP_R_BAD_DECRYPT);
223 		return 0;
224 	}
225 
226 	CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, iv, ctr + 1);
227 	*out_len = plaintext_len;
228 	return 1;
229 }
230 
231 static int
232 aead_xchacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
233     size_t *out_len, size_t max_out_len, const unsigned char *nonce,
234     size_t nonce_len, const unsigned char *in, size_t in_len,
235     const unsigned char *ad, size_t ad_len)
236 {
237 	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
238 	unsigned char poly1305_key[32];
239 	unsigned char subkey[32];
240 	poly1305_state poly1305;
241 
242 	if (max_out_len < in_len + c20_ctx->tag_len) {
243 		EVPerror(EVP_R_BUFFER_TOO_SMALL);
244 		return 0;
245 	}
246 
247 	if (nonce_len != ctx->aead->nonce_len) {
248 		EVPerror(EVP_R_IV_TOO_LARGE);
249 		return 0;
250 	}
251 
252 	CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
253 
254 	CRYPTO_chacha_20(out, in, in_len, subkey, nonce + 16, 1);
255 
256 	memset(poly1305_key, 0, sizeof(poly1305_key));
257 	CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
258 	    subkey, nonce + 16, 0);
259 
260 	CRYPTO_poly1305_init(&poly1305, poly1305_key);
261 	poly1305_update_with_pad16(&poly1305, ad, ad_len);
262 	poly1305_update_with_pad16(&poly1305, out, in_len);
263 	poly1305_update_with_length(&poly1305, NULL, ad_len);
264 	poly1305_update_with_length(&poly1305, NULL, in_len);
265 
266 	if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
267 		unsigned char tag[POLY1305_TAG_LEN];
268 		CRYPTO_poly1305_finish(&poly1305, tag);
269 		memcpy(out + in_len, tag, c20_ctx->tag_len);
270 		*out_len = in_len + c20_ctx->tag_len;
271 		return 1;
272 	}
273 
274 	CRYPTO_poly1305_finish(&poly1305, out + in_len);
275 	*out_len = in_len + POLY1305_TAG_LEN;
276 	return 1;
277 }
278 
279 static int
280 aead_xchacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
281     size_t *out_len, size_t max_out_len, const unsigned char *nonce,
282     size_t nonce_len, const unsigned char *in, size_t in_len,
283     const unsigned char *ad, size_t ad_len)
284 {
285 	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
286 	unsigned char mac[POLY1305_TAG_LEN];
287 	unsigned char poly1305_key[32];
288 	unsigned char subkey[32];
289 	poly1305_state poly1305;
290 	size_t plaintext_len;
291 
292 	if (in_len < c20_ctx->tag_len) {
293 		EVPerror(EVP_R_BAD_DECRYPT);
294 		return 0;
295 	}
296 
297 	if (nonce_len != ctx->aead->nonce_len) {
298 		EVPerror(EVP_R_IV_TOO_LARGE);
299 		return 0;
300 	}
301 
302 	plaintext_len = in_len - c20_ctx->tag_len;
303 
304 	if (max_out_len < plaintext_len) {
305 		EVPerror(EVP_R_BUFFER_TOO_SMALL);
306 		return 0;
307 	}
308 
309 	CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
310 
311 	memset(poly1305_key, 0, sizeof(poly1305_key));
312 	CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
313 	    subkey, nonce + 16, 0);
314 
315 	CRYPTO_poly1305_init(&poly1305, poly1305_key);
316 	poly1305_update_with_pad16(&poly1305, ad, ad_len);
317 	poly1305_update_with_pad16(&poly1305, in, plaintext_len);
318 	poly1305_update_with_length(&poly1305, NULL, ad_len);
319 	poly1305_update_with_length(&poly1305, NULL, plaintext_len);
320 
321 	CRYPTO_poly1305_finish(&poly1305, mac);
322 	if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
323 		EVPerror(EVP_R_BAD_DECRYPT);
324 		return 0;
325 	}
326 
327 	CRYPTO_chacha_20(out, in, plaintext_len, subkey, nonce + 16, 1);
328 
329 	*out_len = plaintext_len;
330 	return 1;
331 }
332 
333 /* RFC 7539 */
334 static const EVP_AEAD aead_chacha20_poly1305 = {
335 	.key_len = 32,
336 	.nonce_len = CHACHA20_NONCE_LEN,
337 	.overhead = POLY1305_TAG_LEN,
338 	.max_tag_len = POLY1305_TAG_LEN,
339 
340 	.init = aead_chacha20_poly1305_init,
341 	.cleanup = aead_chacha20_poly1305_cleanup,
342 	.seal = aead_chacha20_poly1305_seal,
343 	.open = aead_chacha20_poly1305_open,
344 };
345 
346 const EVP_AEAD *
347 EVP_aead_chacha20_poly1305()
348 {
349 	return &aead_chacha20_poly1305;
350 }
351 
352 static const EVP_AEAD aead_xchacha20_poly1305 = {
353 	.key_len = 32,
354 	.nonce_len = XCHACHA20_NONCE_LEN,
355 	.overhead = POLY1305_TAG_LEN,
356 	.max_tag_len = POLY1305_TAG_LEN,
357 
358 	.init = aead_chacha20_poly1305_init,
359 	.cleanup = aead_chacha20_poly1305_cleanup,
360 	.seal = aead_xchacha20_poly1305_seal,
361 	.open = aead_xchacha20_poly1305_open,
362 };
363 
364 const EVP_AEAD *
365 EVP_aead_xchacha20_poly1305()
366 {
367 	return &aead_xchacha20_poly1305;
368 }
369 
370 struct chacha20_poly1305_ctx {
371 	ChaCha_ctx chacha;
372 	poly1305_state poly1305;
373 
374 	unsigned char key[32];
375 	unsigned char nonce[CHACHA20_NONCE_LEN];
376 	size_t nonce_len;
377 	unsigned char tag[POLY1305_TAG_LEN];
378 	size_t tag_len;
379 
380 	size_t ad_len;
381 	size_t in_len;
382 
383 	int in_ad;
384 	int started;
385 };
386 
387 static int
388 chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
389     const unsigned char *iv, int encrypt)
390 {
391 	struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
392 	uint8_t *data;
393 	CBB cbb;
394 	int ret = 0;
395 
396 	memset(&cbb, 0, sizeof(cbb));
397 
398 	if (key == NULL && iv == NULL)
399 		goto done;
400 
401 	cpx->started = 0;
402 
403 	if (key != NULL)
404 		memcpy(cpx->key, key, sizeof(cpx->key));
405 
406 	if (iv != NULL) {
407 		/*
408 		 * Left zero pad if configured nonce length is less than ChaCha
409 		 * nonce length.
410 		 */
411 		if (!CBB_init_fixed(&cbb, cpx->nonce, sizeof(cpx->nonce)))
412 			goto err;
413 		if (!CBB_add_space(&cbb, &data, sizeof(cpx->nonce) - cpx->nonce_len))
414 			goto err;
415 		if (!CBB_add_bytes(&cbb, iv, cpx->nonce_len))
416 			goto err;
417 		if (!CBB_finish(&cbb, NULL, NULL))
418 			goto err;
419 	}
420 
421  done:
422 	ret = 1;
423 
424  err:
425 	CBB_cleanup(&cbb);
426 
427 	return ret;
428 }
429 
430 static int
431 chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
432     const unsigned char *in, size_t len)
433 {
434 	struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
435 
436 	/*
437 	 * Since we're making AEAD work within the constraints of EVP_CIPHER...
438 	 * If in is non-NULL then this is an update, while if in is NULL then
439 	 * this is a final. If in is non-NULL but out is NULL, then the input
440 	 * being provided is associated data. Plus we have to handle encryption
441 	 * (sealing) and decryption (opening) in the same function.
442 	 */
443 
444 	if (!cpx->started) {
445 		unsigned char poly1305_key[32];
446 		const unsigned char *iv;
447 		uint64_t ctr;
448 
449 		ctr = (uint64_t)((uint32_t)(cpx->nonce[0]) |
450 		    (uint32_t)(cpx->nonce[1]) << 8 |
451 		    (uint32_t)(cpx->nonce[2]) << 16 |
452 		    (uint32_t)(cpx->nonce[3]) << 24) << 32;
453 		iv = cpx->nonce + CHACHA20_CONSTANT_LEN;
454 
455 		ChaCha_set_key(&cpx->chacha, cpx->key, 8 * sizeof(cpx->key));
456 		ChaCha_set_iv(&cpx->chacha, iv, NULL);
457 
458 		/* See chacha.c for details re handling of counter. */
459 		cpx->chacha.input[12] = (uint32_t)ctr;
460 		cpx->chacha.input[13] = (uint32_t)(ctr >> 32);
461 
462 		memset(poly1305_key, 0, sizeof(poly1305_key));
463 		ChaCha(&cpx->chacha, poly1305_key, poly1305_key,
464 		    sizeof(poly1305_key));
465 		CRYPTO_poly1305_init(&cpx->poly1305, poly1305_key);
466 
467 		/* Mark remaining key block as used. */
468 		cpx->chacha.unused = 0;
469 
470 		cpx->ad_len = 0;
471 		cpx->in_len = 0;
472 		cpx->in_ad = 0;
473 
474 		cpx->started = 1;
475 	}
476 
477 	if (len > SIZE_MAX - cpx->in_len) {
478 		EVPerror(EVP_R_TOO_LARGE);
479 		return 0;
480 	}
481 
482 	/* Disallow authenticated data after plaintext/ciphertext. */
483 	if (cpx->in_len > 0 && in != NULL && out == NULL)
484 		return -1;
485 
486 	if (cpx->in_ad && (in == NULL || out != NULL)) {
487 		poly1305_pad16(&cpx->poly1305, cpx->ad_len);
488 		cpx->in_ad = 0;
489 	}
490 
491 	/* Update with AD or plaintext/ciphertext. */
492 	if (in != NULL) {
493 		if (out == NULL) {
494 			cpx->ad_len += len;
495 			cpx->in_ad = 1;
496 		} else {
497 			ChaCha(&cpx->chacha, out, in, len);
498 			cpx->in_len += len;
499 		}
500 		if (ctx->encrypt && out != NULL)
501 			CRYPTO_poly1305_update(&cpx->poly1305, out, len);
502 		else
503 			CRYPTO_poly1305_update(&cpx->poly1305, in, len);
504 
505 		return len;
506 	}
507 
508 	/* Final. */
509 	poly1305_pad16(&cpx->poly1305, cpx->in_len);
510 	poly1305_update_with_length(&cpx->poly1305, NULL, cpx->ad_len);
511 	poly1305_update_with_length(&cpx->poly1305, NULL, cpx->in_len);
512 
513 	if (ctx->encrypt) {
514 		CRYPTO_poly1305_finish(&cpx->poly1305, cpx->tag);
515 		cpx->tag_len = sizeof(cpx->tag);
516 	} else {
517 		unsigned char tag[POLY1305_TAG_LEN];
518 
519 		/* Ensure that a tag has been provided. */
520 		if (cpx->tag_len <= 0)
521 			return -1;
522 
523 		CRYPTO_poly1305_finish(&cpx->poly1305, tag);
524 		if (timingsafe_memcmp(tag, cpx->tag, cpx->tag_len) != 0)
525 			return -1;
526 	}
527 
528 	cpx->started = 0;
529 
530 	return len;
531 }
532 
533 static void
534 chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
535 {
536 	struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
537 
538 	explicit_bzero(cpx, sizeof(*cpx));
539 }
540 
541 static int
542 chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
543 {
544 	struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
545 
546 	switch (type) {
547 	case EVP_CTRL_INIT:
548 		memset(cpx, 0, sizeof(*cpx));
549 		cpx->nonce_len = sizeof(cpx->nonce);
550 		return 1;
551 
552 	case EVP_CTRL_AEAD_SET_IVLEN:
553 		if (arg <= 0 || arg > sizeof(cpx->nonce))
554 			return 0;
555 		cpx->nonce_len = arg;
556 		return 1;
557 
558 	case EVP_CTRL_AEAD_SET_TAG:
559 		if (ctx->encrypt)
560 			return 0;
561 		if (arg <= 0 || arg > sizeof(cpx->tag))
562 			return 0;
563 		if (ptr != NULL) {
564 			memcpy(cpx->tag, ptr, arg);
565 			cpx->tag_len = arg;
566 		}
567 		return 1;
568 
569 	case EVP_CTRL_AEAD_GET_TAG:
570 		if (!ctx->encrypt)
571 			return 0;
572 		if (arg <= 0 || arg > cpx->tag_len)
573 			return 0;
574 		memcpy(ptr, cpx->tag, arg);
575 		return 1;
576 
577 	case EVP_CTRL_AEAD_SET_IV_FIXED:
578 		if (arg != sizeof(cpx->nonce))
579 			return 0;
580 		memcpy(cpx->nonce, ptr, arg);
581 		return 1;
582 	}
583 
584 	return 0;
585 }
586 
587 static const EVP_CIPHER cipher_chacha20_poly1305 = {
588 	.nid = NID_chacha20_poly1305,
589 	.block_size = 1,
590 	.key_len = 32,
591 	.iv_len = 12,
592 	.flags = EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
593 	    EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_AEAD_CIPHER |
594 	    EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1,
595 	.init = chacha20_poly1305_init,
596 	.do_cipher = chacha20_poly1305_cipher,
597 	.cleanup = chacha20_poly1305_cleanup,
598 	.ctx_size = sizeof(struct chacha20_poly1305_ctx),
599 	.ctrl = chacha20_poly1305_ctrl,
600 };
601 
602 const EVP_CIPHER *
603 EVP_chacha20_poly1305(void)
604 {
605 	return &cipher_chacha20_poly1305;
606 }
607 
608 #endif  /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */
609