blob: a1314eab6dfba44204dfef4cf5a10e135fd09875 [file] [log] [blame]
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001/**
2 * \file chachapoly.c
3 *
4 * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
5 *
Jerome Forissier79013242021-07-28 10:24:04 +02006 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander3d3b0592019-03-20 15:30:29 +01008 */
Jerome Forissier79013242021-07-28 10:24:04 +02009#include "common.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010010
11#if defined(MBEDTLS_CHACHAPOLY_C)
12
13#include "mbedtls/chachapoly.h"
14#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020015#include "mbedtls/error.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020016#include "mbedtls/constant_time.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010017
18#include <string.h>
19
Jens Wiklander3d3b0592019-03-20 15:30:29 +010020#include "mbedtls/platform.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010021
22#if !defined(MBEDTLS_CHACHAPOLY_ALT)
23
Jens Wiklander32b31802023-10-06 16:59:46 +020024#define CHACHAPOLY_STATE_INIT (0)
25#define CHACHAPOLY_STATE_AAD (1)
26#define CHACHAPOLY_STATE_CIPHERTEXT (2) /* Encrypting or decrypting */
27#define CHACHAPOLY_STATE_FINISHED (3)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010028
29/**
30 * \brief Adds nul bytes to pad the AAD for Poly1305.
31 *
32 * \param ctx The ChaCha20-Poly1305 context.
33 */
Jens Wiklander32b31802023-10-06 16:59:46 +020034static int chachapoly_pad_aad(mbedtls_chachapoly_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010035{
Jens Wiklander32b31802023-10-06 16:59:46 +020036 uint32_t partial_block_len = (uint32_t) (ctx->aad_len % 16U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010037 unsigned char zeroes[15];
38
Jens Wiklander32b31802023-10-06 16:59:46 +020039 if (partial_block_len == 0U) {
40 return 0;
41 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +010042
Jens Wiklander32b31802023-10-06 16:59:46 +020043 memset(zeroes, 0, sizeof(zeroes));
Jens Wiklander3d3b0592019-03-20 15:30:29 +010044
Jens Wiklander32b31802023-10-06 16:59:46 +020045 return mbedtls_poly1305_update(&ctx->poly1305_ctx,
46 zeroes,
47 16U - partial_block_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010048}
49
50/**
51 * \brief Adds nul bytes to pad the ciphertext for Poly1305.
52 *
53 * \param ctx The ChaCha20-Poly1305 context.
54 */
Jens Wiklander32b31802023-10-06 16:59:46 +020055static int chachapoly_pad_ciphertext(mbedtls_chachapoly_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010056{
Jens Wiklander32b31802023-10-06 16:59:46 +020057 uint32_t partial_block_len = (uint32_t) (ctx->ciphertext_len % 16U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010058 unsigned char zeroes[15];
59
Jens Wiklander32b31802023-10-06 16:59:46 +020060 if (partial_block_len == 0U) {
61 return 0;
62 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +010063
Jens Wiklander32b31802023-10-06 16:59:46 +020064 memset(zeroes, 0, sizeof(zeroes));
65 return mbedtls_poly1305_update(&ctx->poly1305_ctx,
66 zeroes,
67 16U - partial_block_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010068}
69
Jens Wiklander32b31802023-10-06 16:59:46 +020070void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010071{
Jens Wiklander32b31802023-10-06 16:59:46 +020072 mbedtls_chacha20_init(&ctx->chacha20_ctx);
73 mbedtls_poly1305_init(&ctx->poly1305_ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010074 ctx->aad_len = 0U;
75 ctx->ciphertext_len = 0U;
76 ctx->state = CHACHAPOLY_STATE_INIT;
77 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
78}
79
Jens Wiklander32b31802023-10-06 16:59:46 +020080void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010081{
Jens Wiklander32b31802023-10-06 16:59:46 +020082 if (ctx == NULL) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +010083 return;
Jens Wiklander32b31802023-10-06 16:59:46 +020084 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +010085
Jens Wiklander32b31802023-10-06 16:59:46 +020086 mbedtls_chacha20_free(&ctx->chacha20_ctx);
87 mbedtls_poly1305_free(&ctx->poly1305_ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010088 ctx->aad_len = 0U;
89 ctx->ciphertext_len = 0U;
90 ctx->state = CHACHAPOLY_STATE_INIT;
91 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
92}
93
Jens Wiklander32b31802023-10-06 16:59:46 +020094int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx,
95 const unsigned char key[32])
Jens Wiklander3d3b0592019-03-20 15:30:29 +010096{
Jerome Forissier11fa71b2020-04-20 17:17:56 +020097 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010098
Jens Wiklander32b31802023-10-06 16:59:46 +020099 ret = mbedtls_chacha20_setkey(&ctx->chacha20_ctx, key);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100100
Jens Wiklander32b31802023-10-06 16:59:46 +0200101 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100102}
103
Jens Wiklander32b31802023-10-06 16:59:46 +0200104int mbedtls_chachapoly_starts(mbedtls_chachapoly_context *ctx,
105 const unsigned char nonce[12],
106 mbedtls_chachapoly_mode_t mode)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100107{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200108 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100109 unsigned char poly1305_key[64];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100110
111 /* Set counter = 0, will be update to 1 when generating Poly1305 key */
Jens Wiklander32b31802023-10-06 16:59:46 +0200112 ret = mbedtls_chacha20_starts(&ctx->chacha20_ctx, nonce, 0U);
113 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100114 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200115 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100116
117 /* Generate the Poly1305 key by getting the ChaCha20 keystream output with
118 * counter = 0. This is the same as encrypting a buffer of zeroes.
119 * Only the first 256-bits (32 bytes) of the key is used for Poly1305.
120 * The other 256 bits are discarded.
121 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200122 memset(poly1305_key, 0, sizeof(poly1305_key));
123 ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, sizeof(poly1305_key),
124 poly1305_key, poly1305_key);
125 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100126 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200127 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100128
Jens Wiklander32b31802023-10-06 16:59:46 +0200129 ret = mbedtls_poly1305_starts(&ctx->poly1305_ctx, poly1305_key);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100130
Jens Wiklander32b31802023-10-06 16:59:46 +0200131 if (ret == 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100132 ctx->aad_len = 0U;
133 ctx->ciphertext_len = 0U;
134 ctx->state = CHACHAPOLY_STATE_AAD;
135 ctx->mode = mode;
136 }
137
138cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +0200139 mbedtls_platform_zeroize(poly1305_key, 64U);
140 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100141}
142
Jens Wiklander32b31802023-10-06 16:59:46 +0200143int mbedtls_chachapoly_update_aad(mbedtls_chachapoly_context *ctx,
144 const unsigned char *aad,
145 size_t aad_len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100146{
Jens Wiklander32b31802023-10-06 16:59:46 +0200147 if (ctx->state != CHACHAPOLY_STATE_AAD) {
148 return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE;
149 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100150
151 ctx->aad_len += aad_len;
152
Jens Wiklander32b31802023-10-06 16:59:46 +0200153 return mbedtls_poly1305_update(&ctx->poly1305_ctx, aad, aad_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100154}
155
Jens Wiklander32b31802023-10-06 16:59:46 +0200156int mbedtls_chachapoly_update(mbedtls_chachapoly_context *ctx,
157 size_t len,
158 const unsigned char *input,
159 unsigned char *output)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100160{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200161 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100162
Jens Wiklander32b31802023-10-06 16:59:46 +0200163 if ((ctx->state != CHACHAPOLY_STATE_AAD) &&
164 (ctx->state != CHACHAPOLY_STATE_CIPHERTEXT)) {
165 return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100166 }
167
Jens Wiklander32b31802023-10-06 16:59:46 +0200168 if (ctx->state == CHACHAPOLY_STATE_AAD) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100169 ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
170
Jens Wiklander32b31802023-10-06 16:59:46 +0200171 ret = chachapoly_pad_aad(ctx);
172 if (ret != 0) {
173 return ret;
174 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100175 }
176
177 ctx->ciphertext_len += len;
178
Jens Wiklander32b31802023-10-06 16:59:46 +0200179 if (ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT) {
180 ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, len, input, output);
181 if (ret != 0) {
182 return ret;
183 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100184
Jens Wiklander32b31802023-10-06 16:59:46 +0200185 ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, output, len);
186 if (ret != 0) {
187 return ret;
188 }
189 } else { /* DECRYPT */
190 ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, input, len);
191 if (ret != 0) {
192 return ret;
193 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100194
Jens Wiklander32b31802023-10-06 16:59:46 +0200195 ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, len, input, output);
196 if (ret != 0) {
197 return ret;
198 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100199 }
200
Jens Wiklander32b31802023-10-06 16:59:46 +0200201 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100202}
203
Jens Wiklander32b31802023-10-06 16:59:46 +0200204int mbedtls_chachapoly_finish(mbedtls_chachapoly_context *ctx,
205 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100206{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200207 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100208 unsigned char len_block[16];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100209
Jens Wiklander32b31802023-10-06 16:59:46 +0200210 if (ctx->state == CHACHAPOLY_STATE_INIT) {
211 return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100212 }
213
Jens Wiklander32b31802023-10-06 16:59:46 +0200214 if (ctx->state == CHACHAPOLY_STATE_AAD) {
215 ret = chachapoly_pad_aad(ctx);
216 if (ret != 0) {
217 return ret;
218 }
219 } else if (ctx->state == CHACHAPOLY_STATE_CIPHERTEXT) {
220 ret = chachapoly_pad_ciphertext(ctx);
221 if (ret != 0) {
222 return ret;
223 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100224 }
225
226 ctx->state = CHACHAPOLY_STATE_FINISHED;
227
228 /* The lengths of the AAD and ciphertext are processed by
229 * Poly1305 as the final 128-bit block, encoded as little-endian integers.
230 */
Jerome Forissier039e02d2022-08-09 17:10:15 +0200231 MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
232 MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100233
Jens Wiklander32b31802023-10-06 16:59:46 +0200234 ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, len_block, 16U);
235 if (ret != 0) {
236 return ret;
237 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100238
Jens Wiklander32b31802023-10-06 16:59:46 +0200239 ret = mbedtls_poly1305_finish(&ctx->poly1305_ctx, mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100240
Jens Wiklander32b31802023-10-06 16:59:46 +0200241 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100242}
243
Jens Wiklander32b31802023-10-06 16:59:46 +0200244static int chachapoly_crypt_and_tag(mbedtls_chachapoly_context *ctx,
245 mbedtls_chachapoly_mode_t mode,
246 size_t length,
247 const unsigned char nonce[12],
248 const unsigned char *aad,
249 size_t aad_len,
250 const unsigned char *input,
251 unsigned char *output,
252 unsigned char tag[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100253{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200254 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100255
Jens Wiklander32b31802023-10-06 16:59:46 +0200256 ret = mbedtls_chachapoly_starts(ctx, nonce, mode);
257 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100258 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200259 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100260
Jens Wiklander32b31802023-10-06 16:59:46 +0200261 ret = mbedtls_chachapoly_update_aad(ctx, aad, aad_len);
262 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100263 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200264 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100265
Jens Wiklander32b31802023-10-06 16:59:46 +0200266 ret = mbedtls_chachapoly_update(ctx, length, input, output);
267 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100268 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200269 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100270
Jens Wiklander32b31802023-10-06 16:59:46 +0200271 ret = mbedtls_chachapoly_finish(ctx, tag);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100272
273cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +0200274 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100275}
276
Jens Wiklander32b31802023-10-06 16:59:46 +0200277int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx,
278 size_t length,
279 const unsigned char nonce[12],
280 const unsigned char *aad,
281 size_t aad_len,
282 const unsigned char *input,
283 unsigned char *output,
284 unsigned char tag[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100285{
Jens Wiklander32b31802023-10-06 16:59:46 +0200286 return chachapoly_crypt_and_tag(ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
287 length, nonce, aad, aad_len,
288 input, output, tag);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100289}
290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx,
292 size_t length,
293 const unsigned char nonce[12],
294 const unsigned char *aad,
295 size_t aad_len,
296 const unsigned char tag[16],
297 const unsigned char *input,
298 unsigned char *output)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100299{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100301 unsigned char check_tag[16];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100302 int diff;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100303
Jens Wiklander32b31802023-10-06 16:59:46 +0200304 if ((ret = chachapoly_crypt_and_tag(ctx,
305 MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
306 aad, aad_len, input, output, check_tag)) != 0) {
307 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100308 }
309
310 /* Check tag in "constant-time" */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200311 diff = mbedtls_ct_memcmp(tag, check_tag, sizeof(check_tag));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100312
Jens Wiklander32b31802023-10-06 16:59:46 +0200313 if (diff != 0) {
314 mbedtls_platform_zeroize(output, length);
315 return MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED;
316 }
317
318 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100319}
320
321#endif /* MBEDTLS_CHACHAPOLY_ALT */
322
323#if defined(MBEDTLS_SELF_TEST)
324
325static const unsigned char test_key[1][32] =
326{
327 {
328 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
329 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
330 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
331 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
332 }
333};
334
335static const unsigned char test_nonce[1][12] =
336{
337 {
338 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */
339 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */
340 }
341};
342
343static const unsigned char test_aad[1][12] =
344{
345 {
346 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
347 0xc4, 0xc5, 0xc6, 0xc7
348 }
349};
350
351static const size_t test_aad_len[1] =
352{
353 12U
354};
355
356static const unsigned char test_input[1][114] =
357{
358 {
359 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
360 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
361 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
362 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
363 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
364 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
365 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
366 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
367 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
368 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
369 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
370 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
371 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
372 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
373 0x74, 0x2e
374 }
375};
376
377static const unsigned char test_output[1][114] =
378{
379 {
380 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
381 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
382 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
383 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
384 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
385 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
386 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
387 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
388 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
389 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
390 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
391 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
392 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
393 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
394 0x61, 0x16
395 }
396};
397
398static const size_t test_input_len[1] =
399{
400 114U
401};
402
403static const unsigned char test_mac[1][16] =
404{
405 {
406 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
407 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
408 }
409};
410
Jerome Forissier79013242021-07-28 10:24:04 +0200411/* Make sure no other definition is already present. */
412#undef ASSERT
413
Jens Wiklander32b31802023-10-06 16:59:46 +0200414#define ASSERT(cond, args) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100415 do \
416 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200417 if (!(cond)) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100418 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200419 if (verbose != 0) \
420 mbedtls_printf args; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100421 \
Jens Wiklander32b31802023-10-06 16:59:46 +0200422 return -1; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100423 } \
424 } \
Jens Wiklander32b31802023-10-06 16:59:46 +0200425 while (0)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100426
Jens Wiklander32b31802023-10-06 16:59:46 +0200427int mbedtls_chachapoly_self_test(int verbose)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100428{
429 mbedtls_chachapoly_context ctx;
430 unsigned i;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200431 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100432 unsigned char output[200];
433 unsigned char mac[16];
434
Jens Wiklander32b31802023-10-06 16:59:46 +0200435 for (i = 0U; i < 1U; i++) {
436 if (verbose != 0) {
437 mbedtls_printf(" ChaCha20-Poly1305 test %u ", i);
438 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100439
Jens Wiklander32b31802023-10-06 16:59:46 +0200440 mbedtls_chachapoly_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100441
Jens Wiklander32b31802023-10-06 16:59:46 +0200442 ret = mbedtls_chachapoly_setkey(&ctx, test_key[i]);
443 ASSERT(0 == ret, ("setkey() error code: %i\n", ret));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100444
Jens Wiklander32b31802023-10-06 16:59:46 +0200445 ret = mbedtls_chachapoly_encrypt_and_tag(&ctx,
446 test_input_len[i],
447 test_nonce[i],
448 test_aad[i],
449 test_aad_len[i],
450 test_input[i],
451 output,
452 mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100453
Jens Wiklander32b31802023-10-06 16:59:46 +0200454 ASSERT(0 == ret, ("crypt_and_tag() error code: %i\n", ret));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100455
Jens Wiklander32b31802023-10-06 16:59:46 +0200456 ASSERT(0 == memcmp(output, test_output[i], test_input_len[i]),
457 ("failure (wrong output)\n"));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100458
Jens Wiklander32b31802023-10-06 16:59:46 +0200459 ASSERT(0 == memcmp(mac, test_mac[i], 16U),
460 ("failure (wrong MAC)\n"));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100461
Jens Wiklander32b31802023-10-06 16:59:46 +0200462 mbedtls_chachapoly_free(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100463
Jens Wiklander32b31802023-10-06 16:59:46 +0200464 if (verbose != 0) {
465 mbedtls_printf("passed\n");
466 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100467 }
468
Jens Wiklander32b31802023-10-06 16:59:46 +0200469 if (verbose != 0) {
470 mbedtls_printf("\n");
471 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100472
Jens Wiklander32b31802023-10-06 16:59:46 +0200473 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100474}
475
476#endif /* MBEDTLS_SELF_TEST */
477
478#endif /* MBEDTLS_CHACHAPOLY_C */