blob: e283853a409241568d4d905f4f438dd5e9220c75 [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
Daniel Kingb8025c52016-05-17 14:43:01 -030031#include "mbedtls/platform.h"
Daniel Kingb8025c52016-05-17 14:43:01 -030032
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020033#if !defined(MBEDTLS_CHACHAPOLY_ALT)
Daniel Kingb8025c52016-05-17 14:43:01 -030034
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020035#define CHACHAPOLY_STATE_INIT ( 0 )
36#define CHACHAPOLY_STATE_AAD ( 1 )
37#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
38#define CHACHAPOLY_STATE_FINISHED ( 3 )
Daniel Kingb8025c52016-05-17 14:43:01 -030039
Daniel Kingb8025c52016-05-17 14:43:01 -030040/**
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020041 * \brief Adds nul bytes to pad the AAD for Poly1305.
Daniel Kingb8025c52016-05-17 14:43:01 -030042 *
43 * \param ctx The ChaCha20-Poly1305 context.
44 */
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020045static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030046{
Daniel Kinge6e79682016-05-24 11:16:17 -030047 uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
Daniel Kingb8025c52016-05-17 14:43:01 -030048 unsigned char zeroes[15];
49
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020050 if( partial_block_len == 0U )
51 return( 0 );
52
53 memset( zeroes, 0, sizeof( zeroes ) );
54
55 return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
56 zeroes,
57 16U - partial_block_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -030058}
59
60/**
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020061 * \brief Adds nul bytes to pad the ciphertext for Poly1305.
Daniel Kingb8025c52016-05-17 14:43:01 -030062 *
63 * \param ctx The ChaCha20-Poly1305 context.
64 */
Manuel Pégourié-Gonnard26c3b0a2018-06-04 12:06:23 +020065static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030066{
Daniel Kinge6e79682016-05-24 11:16:17 -030067 uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
Daniel Kingb8025c52016-05-17 14:43:01 -030068 unsigned char zeroes[15];
69
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +020070 if( partial_block_len == 0U )
71 return( 0 );
72
73 memset( zeroes, 0, sizeof( zeroes ) );
74 return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
75 zeroes,
76 16U - partial_block_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -030077}
78
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020079void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030080{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050081 mbedtls_chacha20_init( &ctx->chacha20_ctx );
82 mbedtls_poly1305_init( &ctx->poly1305_ctx );
83 ctx->aad_len = 0U;
84 ctx->ciphertext_len = 0U;
85 ctx->state = CHACHAPOLY_STATE_INIT;
86 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
Daniel Kingb8025c52016-05-17 14:43:01 -030087}
88
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +020089void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
Daniel Kingb8025c52016-05-17 14:43:01 -030090{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050091 if( ctx == NULL )
92 return;
93
94 mbedtls_chacha20_free( &ctx->chacha20_ctx );
95 mbedtls_poly1305_free( &ctx->poly1305_ctx );
96 ctx->aad_len = 0U;
97 ctx->ciphertext_len = 0U;
98 ctx->state = CHACHAPOLY_STATE_INIT;
99 ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
Daniel Kingb8025c52016-05-17 14:43:01 -0300100}
101
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200102int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
103 const unsigned char key[32] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300104{
Janos Follath24eed8d2019-11-22 13:21:35 +0000105 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300106
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200107 ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
Daniel Kingb8025c52016-05-17 14:43:01 -0300108
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200109 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300110}
111
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200112int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
113 const unsigned char nonce[12],
114 mbedtls_chachapoly_mode_t mode )
Daniel Kingb8025c52016-05-17 14:43:01 -0300115{
Janos Follath24eed8d2019-11-22 13:21:35 +0000116 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300117 unsigned char poly1305_key[64];
Daniel Kingb8025c52016-05-17 14:43:01 -0300118
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200119 /* Set counter = 0, will be update to 1 when generating Poly1305 key */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200120 ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
121 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300122 goto cleanup;
123
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200124 /* Generate the Poly1305 key by getting the ChaCha20 keystream output with
125 * counter = 0. This is the same as encrypting a buffer of zeroes.
Daniel Kingb8025c52016-05-17 14:43:01 -0300126 * Only the first 256-bits (32 bytes) of the key is used for Poly1305.
127 * The other 256 bits are discarded.
128 */
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200129 memset( poly1305_key, 0, sizeof( poly1305_key ) );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200130 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
Manuel Pégourié-Gonnard56206c42018-05-07 12:18:34 +0200131 poly1305_key, poly1305_key );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200132 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300133 goto cleanup;
134
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200135 ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
Daniel Kingb8025c52016-05-17 14:43:01 -0300136
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200137 if( ret == 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300138 {
139 ctx->aad_len = 0U;
140 ctx->ciphertext_len = 0U;
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200141 ctx->state = CHACHAPOLY_STATE_AAD;
Daniel Kingb8025c52016-05-17 14:43:01 -0300142 ctx->mode = mode;
143 }
144
145cleanup:
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200146 mbedtls_platform_zeroize( poly1305_key, 64U );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200147 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300148}
149
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200150int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
Manuel Pégourié-Gonnard5ef92d32018-05-09 09:34:25 +0200151 const unsigned char *aad,
152 size_t aad_len )
Daniel Kingb8025c52016-05-17 14:43:01 -0300153{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500154 if( ctx->state != CHACHAPOLY_STATE_AAD )
Manuel Pégourié-Gonnardc7bc9e12018-06-18 10:30:30 +0200155 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300156
157 ctx->aad_len += aad_len;
158
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200159 return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
Daniel Kingb8025c52016-05-17 14:43:01 -0300160}
161
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200162int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
163 size_t len,
164 const unsigned char *input,
165 unsigned char *output )
Daniel Kingb8025c52016-05-17 14:43:01 -0300166{
Janos Follath24eed8d2019-11-22 13:21:35 +0000167 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200168
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500169 if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
170 ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
Daniel Kingb8025c52016-05-17 14:43:01 -0300171 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200172 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300173 }
174
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200175 if( ctx->state == CHACHAPOLY_STATE_AAD )
Daniel Kingb8025c52016-05-17 14:43:01 -0300176 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200177 ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
Daniel Kingb8025c52016-05-17 14:43:01 -0300178
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200179 ret = chachapoly_pad_aad( ctx );
180 if( ret != 0 )
181 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300182 }
183
184 ctx->ciphertext_len += len;
185
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200186 if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300187 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200188 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
189 if( ret != 0 )
190 return( ret );
191
192 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
193 if( ret != 0 )
194 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300195 }
196 else /* DECRYPT */
197 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200198 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
199 if( ret != 0 )
200 return( ret );
201
202 ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
203 if( ret != 0 )
204 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300205 }
206
207 return( 0 );
208}
209
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200210int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
211 unsigned char mac[16] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300212{
Janos Follath24eed8d2019-11-22 13:21:35 +0000213 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300214 unsigned char len_block[16];
215
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500216 if( ctx->state == CHACHAPOLY_STATE_INIT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300217 {
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200218 return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
Daniel Kingb8025c52016-05-17 14:43:01 -0300219 }
220
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200221 if( ctx->state == CHACHAPOLY_STATE_AAD )
Daniel Kingb8025c52016-05-17 14:43:01 -0300222 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200223 ret = chachapoly_pad_aad( ctx );
224 if( ret != 0 )
225 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300226 }
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200227 else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
Daniel Kingb8025c52016-05-17 14:43:01 -0300228 {
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200229 ret = chachapoly_pad_ciphertext( ctx );
230 if( ret != 0 )
231 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300232 }
233
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200234 ctx->state = CHACHAPOLY_STATE_FINISHED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300235
236 /* The lengths of the AAD and ciphertext are processed by
237 * Poly1305 as the final 128-bit block, encoded as little-endian integers.
238 */
Joe Subbianib6511b02021-07-16 15:02:55 +0100239 MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
240 MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
Daniel Kingb8025c52016-05-17 14:43:01 -0300241
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200242 ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
243 if( ret != 0 )
244 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300245
Manuel Pégourié-Gonnardf4f01b62018-05-24 18:43:42 +0200246 ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
247
248 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300249}
250
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200251static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
252 mbedtls_chachapoly_mode_t mode,
253 size_t length,
254 const unsigned char nonce[12],
255 const unsigned char *aad,
256 size_t aad_len,
257 const unsigned char *input,
258 unsigned char *output,
259 unsigned char tag[16] )
Daniel Kingb8025c52016-05-17 14:43:01 -0300260{
Janos Follath24eed8d2019-11-22 13:21:35 +0000261 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300262
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200263 ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
264 if( ret != 0 )
Daniel Kingb8025c52016-05-17 14:43:01 -0300265 goto cleanup;
266
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200267 ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
268 if( ret != 0 )
269 goto cleanup;
Daniel Kingb8025c52016-05-17 14:43:01 -0300270
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200271 ret = mbedtls_chachapoly_update( ctx, length, input, output );
272 if( ret != 0 )
273 goto cleanup;
Daniel Kingb8025c52016-05-17 14:43:01 -0300274
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200275 ret = mbedtls_chachapoly_finish( ctx, tag );
Daniel Kingb8025c52016-05-17 14:43:01 -0300276
277cleanup:
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200278 return( ret );
Daniel Kingb8025c52016-05-17 14:43:01 -0300279}
280
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200281int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
282 size_t length,
283 const unsigned char nonce[12],
284 const unsigned char *aad,
285 size_t aad_len,
286 const unsigned char *input,
287 unsigned char *output,
288 unsigned char tag[16] )
289{
290 return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
291 length, nonce, aad, aad_len,
292 input, output, tag ) );
293}
294
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200295int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
296 size_t length,
297 const unsigned char nonce[12],
298 const unsigned char *aad,
299 size_t aad_len,
300 const unsigned char tag[16],
301 const unsigned char *input,
302 unsigned char *output )
303{
Janos Follath24eed8d2019-11-22 13:21:35 +0000304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200305 unsigned char check_tag[16];
306 size_t i;
307 int diff;
Manuel Pégourié-Gonnard59d2c302018-05-10 10:39:32 +0200308
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200309 if( ( ret = chachapoly_crypt_and_tag( ctx,
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200310 MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
311 aad, aad_len, input, output, check_tag ) ) != 0 )
312 {
313 return( ret );
314 }
315
316 /* Check tag in "constant-time" */
317 for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
318 diff |= tag[i] ^ check_tag[i];
319
320 if( diff != 0 )
321 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200322 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200323 return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
324 }
325
326 return( 0 );
327}
328
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200329#endif /* MBEDTLS_CHACHAPOLY_ALT */
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200330
Daniel Kingb8025c52016-05-17 14:43:01 -0300331#if defined(MBEDTLS_SELF_TEST)
332
333static const unsigned char test_key[1][32] =
334{
335 {
336 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
337 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
338 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
339 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
340 }
341};
342
343static const unsigned char test_nonce[1][12] =
344{
345 {
346 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */
347 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */
348 }
349};
350
351static const unsigned char test_aad[1][12] =
352{
353 {
354 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
355 0xc4, 0xc5, 0xc6, 0xc7
356 }
357};
358
359static const size_t test_aad_len[1] =
360{
361 12U
362};
363
364static const unsigned char test_input[1][114] =
365{
366 {
367 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
368 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
369 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
370 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
371 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
372 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
373 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
374 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
375 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
376 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
377 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
378 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
379 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
380 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
381 0x74, 0x2e
382 }
383};
384
385static const unsigned char test_output[1][114] =
386{
387 {
388 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
389 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
390 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
391 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
392 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
393 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
394 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
395 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
396 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
397 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
398 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
399 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
400 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
401 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
402 0x61, 0x16
403 }
404};
405
406static const size_t test_input_len[1] =
407{
408 114U
409};
410
411static const unsigned char test_mac[1][16] =
412{
413 {
414 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
415 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
416 }
417};
418
Ouss4e0b26872020-08-11 16:07:09 +0100419/* Make sure no other definition is already present. */
420#undef ASSERT
421
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200422#define ASSERT( cond, args ) \
423 do \
424 { \
425 if( ! ( cond ) ) \
426 { \
427 if( verbose != 0 ) \
428 mbedtls_printf args; \
429 \
430 return( -1 ); \
431 } \
432 } \
433 while( 0 )
434
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200435int mbedtls_chachapoly_self_test( int verbose )
Daniel Kingb8025c52016-05-17 14:43:01 -0300436{
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200437 mbedtls_chachapoly_context ctx;
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200438 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000439 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingb8025c52016-05-17 14:43:01 -0300440 unsigned char output[200];
441 unsigned char mac[16];
442
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200443 for( i = 0U; i < 1U; i++ )
Daniel Kingb8025c52016-05-17 14:43:01 -0300444 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200445 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200446 mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300447
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200448 mbedtls_chachapoly_init( &ctx );
449
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200450 ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
451 ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200452
Manuel Pégourié-Gonnard3dc62a02018-06-04 12:18:19 +0200453 ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
454 test_input_len[i],
455 test_nonce[i],
456 test_aad[i],
457 test_aad_len[i],
458 test_input[i],
459 output,
460 mac );
Daniel Kingb8025c52016-05-17 14:43:01 -0300461
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200462 ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
Daniel Kingb8025c52016-05-17 14:43:01 -0300463
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200464 ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
465 ( "failure (wrong output)\n" ) );
466
467 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
468 ( "failure (wrong MAC)\n" ) );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300469
Manuel Pégourié-Gonnard346b8d52018-05-07 12:56:36 +0200470 mbedtls_chachapoly_free( &ctx );
471
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200472 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300473 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300474 }
475
476 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300477 mbedtls_printf( "\n" );
Daniel Kingb8025c52016-05-17 14:43:01 -0300478
479 return( 0 );
480}
481
482#endif /* MBEDTLS_SELF_TEST */
483
Manuel Pégourié-Gonnarddca3a5d2018-05-07 10:43:27 +0200484#endif /* MBEDTLS_CHACHAPOLY_C */