blob: 1f75528c00e11ffbb87fb2a1da9daedb6c333eef [file] [log] [blame]
Daniel Kingb8025c52016-05-17 14:43:01 -03001/**
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +02002 * \file chachapoly.c
Daniel Kingb8025c52016-05-17 14:43:01 -03003 *
4 * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
5 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02006 * Copyright The Mbed TLS Contributors
Daniel Kingb8025c52016-05-17 14:43:01 -03007 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
Daniel Kingb8025c52016-05-17 14:43:01 -030020 */
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Daniel Kingb8025c52016-05-17 14:43:01 -030022
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020023#if defined(MBEDTLS_CHACHAPOLY_C)
Daniel Kingb8025c52016-05-17 14:43:01 -030024
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020025#include "mbedtls/chachapoly.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020026#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000027#include "mbedtls/error.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020028
Daniel Kingb8025c52016-05-17 14:43:01 -030029#include <string.h>
30
31#if defined(MBEDTLS_SELF_TEST)
32#if defined(MBEDTLS_PLATFORM_C)
33#include "mbedtls/platform.h"
34#else
35#include <stdio.h>
36#define mbedtls_printf printf
37#endif /* MBEDTLS_PLATFORM_C */
38#endif /* MBEDTLS_SELF_TEST */
39
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020040#if !defined(MBEDTLS_CHACHAPOLY_ALT)
Daniel Kingb8025c52016-05-17 14:43:01 -030041
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020042#define CHACHAPOLY_STATE_INIT ( 0 )
43#define CHACHAPOLY_STATE_AAD ( 1 )
44#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
45#define CHACHAPOLY_STATE_FINISHED ( 3 )
Daniel Kingb8025c52016-05-17 14:43:01 -030046
Daniel Kingb8025c52016-05-17 14:43:01 -030047/**
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020048 * \brief Adds nul bytes to pad the AAD for Poly1305.
Daniel Kingb8025c52016-05-17 14:43:01 -030049 *
50 * \param ctx The ChaCha20-Poly1305 context.
51 */
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020052static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030053{
Daniel Kinge6e79682016-05-24 11:16:17 -030054 uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
Daniel Kingb8025c52016-05-17 14:43:01 -030055 unsigned char zeroes[15];
56
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020057 if( partial_block_len == 0U )
58 return( 0 );
59
60 memset( zeroes, 0, sizeof( zeroes ) );
61
62 return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
63 zeroes,
64 16U - partial_block_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -030065}
66
67/**
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020068 * \brief Adds nul bytes to pad the ciphertext for Poly1305.
Daniel Kingb8025c52016-05-17 14:43:01 -030069 *
70 * \param ctx The ChaCha20-Poly1305 context.
71 */
Manuel Pégourié-Gonnard26c3b0a2018-06-04 12:06:23 +020072static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030073{
Daniel Kinge6e79682016-05-24 11:16:17 -030074 uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
Daniel Kingb8025c52016-05-17 14:43:01 -030075 unsigned char zeroes[15];
76
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020077 if( partial_block_len == 0U )
78 return( 0 );
79
80 memset( zeroes, 0, sizeof( zeroes ) );
81 return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
82 zeroes,
83 16U - partial_block_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -030084}
85
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020086void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030087{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050088 mbedtls_chacha20_init( &ctx->chacha20_ctx );
89 mbedtls_poly1305_init( &ctx->poly1305_ctx );
90 ctx->aad_len = 0U;
91 ctx->ciphertext_len = 0U;
92 ctx->state = CHACHAPOLY_STATE_INIT;
93 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
Daniel Kingb8025c52016-05-17 14:43:01 -030094}
95
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020096void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030097{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050098 if( ctx == NULL )
99 return;
100
101 mbedtls_chacha20_free( &ctx->chacha20_ctx );
102 mbedtls_poly1305_free( &ctx->poly1305_ctx );
103 ctx->aad_len = 0U;
104 ctx->ciphertext_len = 0U;
105 ctx->state = CHACHAPOLY_STATE_INIT;
106 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
Daniel Kingb8025c52016-05-17 14:43:01 -0300107}
108
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200109int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
110 const unsigned char key[32] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300111{
Janos Follath24eed8d2019-11-22 13:21:35 +0000112 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300113
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200114 ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
Daniel Kingb8025c52016-05-17 14:43:01 -0300115
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200116 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300117}
118
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200119int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
120 const unsigned char nonce[12],
121 mbedtls_chachapoly_mode_t mode )
Daniel Kingb8025c52016-05-17 14:43:01 -0300122{
Janos Follath24eed8d2019-11-22 13:21:35 +0000123 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300124 unsigned char poly1305_key[64];
Daniel Kingb8025c52016-05-17 14:43:01 -0300125
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200126 /* Set counter = 0, will be update to 1 when generating Poly1305 key */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200127 ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
128 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300129 goto cleanup;
130
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200131 /* Generate the Poly1305 key by getting the ChaCha20 keystream output with
132 * counter = 0. This is the same as encrypting a buffer of zeroes.
Daniel Kingb8025c52016-05-17 14:43:01 -0300133 * Only the first 256-bits (32 bytes) of the key is used for Poly1305.
134 * The other 256 bits are discarded.
135 */
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200136 memset( poly1305_key, 0, sizeof( poly1305_key ) );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200137 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200138 poly1305_key, poly1305_key );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200139 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300140 goto cleanup;
141
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200142 ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
Daniel Kingb8025c52016-05-17 14:43:01 -0300143
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200144 if( ret == 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300145 {
146 ctx->aad_len = 0U;
147 ctx->ciphertext_len = 0U;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200148 ctx->state = CHACHAPOLY_STATE_AAD;
Daniel Kingb8025c52016-05-17 14:43:01 -0300149 ctx->mode = mode;
150 }
151
152cleanup:
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200153 mbedtls_platform_zeroize( poly1305_key, 64U );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200154 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300155}
156
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200157int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
Manuel Pégourié-Gonnard5ef92d32018-05-09 09:34:25 +0200158 const unsigned char *aad,
159 size_t aad_len )
Daniel Kingb8025c52016-05-17 14:43:01 -0300160{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500161 if( ctx->state != CHACHAPOLY_STATE_AAD )
Manuel Pégourié-Gonnardc7bc9e12018-06-18 10:30:30 +0200162 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300163
164 ctx->aad_len += aad_len;
165
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200166 return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -0300167}
168
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200169int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
170 size_t len,
171 const unsigned char *input,
172 unsigned char *output )
Daniel Kingb8025c52016-05-17 14:43:01 -0300173{
Janos Follath24eed8d2019-11-22 13:21:35 +0000174 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200175
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500176 if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
177 ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
Daniel Kingb8025c52016-05-17 14:43:01 -0300178 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200179 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300180 }
181
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200182 if( ctx->state == CHACHAPOLY_STATE_AAD )
Daniel Kingb8025c52016-05-17 14:43:01 -0300183 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200184 ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
Daniel Kingb8025c52016-05-17 14:43:01 -0300185
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200186 ret = chachapoly_pad_aad( ctx );
187 if( ret != 0 )
188 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300189 }
190
191 ctx->ciphertext_len += len;
192
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200193 if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300194 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200195 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
196 if( ret != 0 )
197 return( ret );
198
199 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
200 if( ret != 0 )
201 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300202 }
203 else /* DECRYPT */
204 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200205 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
206 if( ret != 0 )
207 return( ret );
208
209 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
210 if( ret != 0 )
211 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300212 }
213
214 return( 0 );
215}
216
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200217int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
218 unsigned char mac[16] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300219{
Janos Follath24eed8d2019-11-22 13:21:35 +0000220 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300221 unsigned char len_block[16];
222
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500223 if( ctx->state == CHACHAPOLY_STATE_INIT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300224 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200225 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300226 }
227
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200228 if( ctx->state == CHACHAPOLY_STATE_AAD )
Daniel Kingb8025c52016-05-17 14:43:01 -0300229 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200230 ret = chachapoly_pad_aad( ctx );
231 if( ret != 0 )
232 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300233 }
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200234 else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300235 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200236 ret = chachapoly_pad_ciphertext( ctx );
237 if( ret != 0 )
238 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300239 }
240
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200241 ctx->state = CHACHAPOLY_STATE_FINISHED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300242
243 /* The lengths of the AAD and ciphertext are processed by
244 * Poly1305 as the final 128-bit block, encoded as little-endian integers.
245 */
Joe Subbianib6511b02021-07-16 15:02:55 +0100246 MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
247 MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
Daniel Kingb8025c52016-05-17 14:43:01 -0300248
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200249 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
250 if( ret != 0 )
251 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300252
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200253 ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
254
255 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300256}
257
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200258static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
259 mbedtls_chachapoly_mode_t mode,
260 size_t length,
261 const unsigned char nonce[12],
262 const unsigned char *aad,
263 size_t aad_len,
264 const unsigned char *input,
265 unsigned char *output,
266 unsigned char tag[16] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300267{
Janos Follath24eed8d2019-11-22 13:21:35 +0000268 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300269
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200270 ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
271 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300272 goto cleanup;
273
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200274 ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
275 if( ret != 0 )
276 goto cleanup;
Daniel Kingb8025c52016-05-17 14:43:01 -0300277
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200278 ret = mbedtls_chachapoly_update( ctx, length, input, output );
279 if( ret != 0 )
280 goto cleanup;
Daniel Kingb8025c52016-05-17 14:43:01 -0300281
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200282 ret = mbedtls_chachapoly_finish( ctx, tag );
Daniel Kingb8025c52016-05-17 14:43:01 -0300283
284cleanup:
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200285 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300286}
287
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200288int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
289 size_t length,
290 const unsigned char nonce[12],
291 const unsigned char *aad,
292 size_t aad_len,
293 const unsigned char *input,
294 unsigned char *output,
295 unsigned char tag[16] )
296{
297 return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
298 length, nonce, aad, aad_len,
299 input, output, tag ) );
300}
301
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200302int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
303 size_t length,
304 const unsigned char nonce[12],
305 const unsigned char *aad,
306 size_t aad_len,
307 const unsigned char tag[16],
308 const unsigned char *input,
309 unsigned char *output )
310{
Janos Follath24eed8d2019-11-22 13:21:35 +0000311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200312 unsigned char check_tag[16];
313 size_t i;
314 int diff;
Manuel Pégourié-Gonnard59d2c302018-05-10 10:39:32 +0200315
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200316 if( ( ret = chachapoly_crypt_and_tag( ctx,
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200317 MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
318 aad, aad_len, input, output, check_tag ) ) != 0 )
319 {
320 return( ret );
321 }
322
323 /* Check tag in "constant-time" */
324 for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
325 diff |= tag[i] ^ check_tag[i];
326
327 if( diff != 0 )
328 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200329 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200330 return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
331 }
332
333 return( 0 );
334}
335
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200336#endif /* MBEDTLS_CHACHAPOLY_ALT */
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200337
Daniel Kingb8025c52016-05-17 14:43:01 -0300338#if defined(MBEDTLS_SELF_TEST)
339
340static const unsigned char test_key[1][32] =
341{
342 {
343 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
344 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
345 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
346 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
347 }
348};
349
350static const unsigned char test_nonce[1][12] =
351{
352 {
353 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */
354 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */
355 }
356};
357
358static const unsigned char test_aad[1][12] =
359{
360 {
361 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
362 0xc4, 0xc5, 0xc6, 0xc7
363 }
364};
365
366static const size_t test_aad_len[1] =
367{
368 12U
369};
370
371static const unsigned char test_input[1][114] =
372{
373 {
374 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
375 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
376 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
377 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
378 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
379 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
380 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
381 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
382 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
383 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
384 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
385 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
386 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
387 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
388 0x74, 0x2e
389 }
390};
391
392static const unsigned char test_output[1][114] =
393{
394 {
395 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
396 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
397 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
398 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
399 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
400 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
401 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
402 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
403 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
404 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
405 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
406 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
407 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
408 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
409 0x61, 0x16
410 }
411};
412
413static const size_t test_input_len[1] =
414{
415 114U
416};
417
418static const unsigned char test_mac[1][16] =
419{
420 {
421 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
422 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
423 }
424};
425
Ouss4e0b26872020-08-11 16:07:09 +0100426/* Make sure no other definition is already present. */
427#undef ASSERT
428
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200429#define ASSERT( cond, args ) \
430 do \
431 { \
432 if( ! ( cond ) ) \
433 { \
434 if( verbose != 0 ) \
435 mbedtls_printf args; \
436 \
437 return( -1 ); \
438 } \
439 } \
440 while( 0 )
441
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200442int mbedtls_chachapoly_self_test( int verbose )
Daniel Kingb8025c52016-05-17 14:43:01 -0300443{
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200444 mbedtls_chachapoly_context ctx;
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200445 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000446 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300447 unsigned char output[200];
448 unsigned char mac[16];
449
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200450 for( i = 0U; i < 1U; i++ )
Daniel Kingb8025c52016-05-17 14:43:01 -0300451 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200452 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200453 mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300454
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200455 mbedtls_chachapoly_init( &ctx );
456
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200457 ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
458 ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200459
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200460 ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
461 test_input_len[i],
462 test_nonce[i],
463 test_aad[i],
464 test_aad_len[i],
465 test_input[i],
466 output,
467 mac );
Daniel Kingb8025c52016-05-17 14:43:01 -0300468
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200469 ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
Daniel Kingb8025c52016-05-17 14:43:01 -0300470
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200471 ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
472 ( "failure (wrong output)\n" ) );
473
474 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
475 ( "failure (wrong MAC)\n" ) );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300476
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200477 mbedtls_chachapoly_free( &ctx );
478
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200479 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300480 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300481 }
482
483 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300484 mbedtls_printf( "\n" );
Daniel Kingb8025c52016-05-17 14:43:01 -0300485
486 return( 0 );
487}
488
489#endif /* MBEDTLS_SELF_TEST */
490
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200491#endif /* MBEDTLS_CHACHAPOLY_C */