blob: f92e5074a7cb770813b2c83e5c4a874fd8efbe02 [file] [log] [blame]
Daniel King34b822c2016-05-15 17:28:08 -03001/**
2 * \file chacha20.c
3 *
4 * \brief ChaCha20 cipher.
5 *
6 * \author Daniel King <damaki.gh@gmail.com>
7 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02008 * Copyright The Mbed TLS Contributors
Daniel King34b822c2016-05-15 17:28:08 -03009 * SPDX-License-Identifier: Apache-2.0
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
Daniel King34b822c2016-05-15 17:28:08 -030022 */
Daniel King34b822c2016-05-15 17:28:08 -030023
Gilles Peskinedb09ef62020-06-03 01:43:33 +020024#include "common.h"
Daniel King34b822c2016-05-15 17:28:08 -030025
26#if defined(MBEDTLS_CHACHA20_C)
27
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020028#include "mbedtls/chacha20.h"
29#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000030#include "mbedtls/error.h"
Daniel King34b822c2016-05-15 17:28:08 -030031
32#include <stddef.h>
33#include <string.h>
34
35#if defined(MBEDTLS_SELF_TEST)
Daniel King34b822c2016-05-15 17:28:08 -030036#include "mbedtls/platform.h"
Daniel King34b822c2016-05-15 17:28:08 -030037#endif /* MBEDTLS_SELF_TEST */
38
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020039#if !defined(MBEDTLS_CHACHA20_ALT)
40
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020041#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
42 !defined(inline) && !defined(__cplusplus)
43#define inline __inline
44#endif
45
Hanno Becker305e4e42018-12-11 15:03:16 +000046/* Parameter validation macros */
47#define CHACHA20_VALIDATE_RET( cond ) \
48 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
49#define CHACHA20_VALIDATE( cond ) \
50 MBEDTLS_INTERNAL_VALIDATE( cond )
51
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020052#define ROTL32( value, amount ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010053 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030054
55#define CHACHA20_CTR_INDEX ( 12U )
56
57#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
58
Daniel King34b822c2016-05-15 17:28:08 -030059/**
60 * \brief ChaCha20 quarter round operation.
61 *
62 * The quarter round is defined as follows (from RFC 7539):
63 * 1. a += b; d ^= a; d <<<= 16;
64 * 2. c += d; b ^= c; b <<<= 12;
65 * 3. a += b; d ^= a; d <<<= 8;
66 * 4. c += d; b ^= c; b <<<= 7;
67 *
68 * \param state ChaCha20 state to modify.
69 * \param a The index of 'a' in the state.
70 * \param b The index of 'b' in the state.
71 * \param c The index of 'c' in the state.
72 * \param d The index of 'd' in the state.
73 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020074static inline void chacha20_quarter_round( uint32_t state[16],
75 size_t a,
76 size_t b,
77 size_t c,
78 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -030079{
80 /* a += b; d ^= a; d <<<= 16; */
81 state[a] += state[b];
82 state[d] ^= state[a];
83 state[d] = ROTL32( state[d], 16 );
84
85 /* c += d; b ^= c; b <<<= 12 */
86 state[c] += state[d];
87 state[b] ^= state[c];
88 state[b] = ROTL32( state[b], 12 );
89
90 /* a += b; d ^= a; d <<<= 8; */
91 state[a] += state[b];
92 state[d] ^= state[a];
93 state[d] = ROTL32( state[d], 8 );
94
95 /* c += d; b ^= c; b <<<= 7; */
96 state[c] += state[d];
97 state[b] ^= state[c];
98 state[b] = ROTL32( state[b], 7 );
99}
100
101/**
102 * \brief Perform the ChaCha20 inner block operation.
103 *
104 * This function performs two rounds: the column round and the
105 * diagonal round.
106 *
107 * \param state The ChaCha20 state to update.
108 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200109static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300110{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200111 chacha20_quarter_round( state, 0, 4, 8, 12 );
112 chacha20_quarter_round( state, 1, 5, 9, 13 );
113 chacha20_quarter_round( state, 2, 6, 10, 14 );
114 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300115
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200116 chacha20_quarter_round( state, 0, 5, 10, 15 );
117 chacha20_quarter_round( state, 1, 6, 11, 12 );
118 chacha20_quarter_round( state, 2, 7, 8, 13 );
119 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300120}
121
122/**
123 * \brief Generates a keystream block.
124 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200125 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300126 * \param keystream Generated keystream bytes are written to this buffer.
127 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200128static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200129 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300130{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200131 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300132 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300133
Daniel Kingb8025c52016-05-17 14:43:01 -0300134 memcpy( working_state,
135 initial_state,
136 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300137
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200138 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200139 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300140
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200141 working_state[ 0] += initial_state[ 0];
142 working_state[ 1] += initial_state[ 1];
143 working_state[ 2] += initial_state[ 2];
144 working_state[ 3] += initial_state[ 3];
145 working_state[ 4] += initial_state[ 4];
146 working_state[ 5] += initial_state[ 5];
147 working_state[ 6] += initial_state[ 6];
148 working_state[ 7] += initial_state[ 7];
149 working_state[ 8] += initial_state[ 8];
150 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300151 working_state[10] += initial_state[10];
152 working_state[11] += initial_state[11];
153 working_state[12] += initial_state[12];
154 working_state[13] += initial_state[13];
155 working_state[14] += initial_state[14];
156 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300157
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200158 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300159 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200160 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300161
Joe Subbiani6627fb22021-07-16 15:02:55 +0100162 MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
Daniel King34b822c2016-05-15 17:28:08 -0300163 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200164
165 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300166}
167
168void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
169{
Hanno Becker305e4e42018-12-11 15:03:16 +0000170 CHACHA20_VALIDATE( ctx != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300171
Hanno Becker305e4e42018-12-11 15:03:16 +0000172 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
173 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
174
175 /* Initially, there's no keystream bytes available */
176 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300177}
178
179void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
180{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200181 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300182 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200183 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300184 }
185}
186
187int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
188 const unsigned char key[32] )
189{
Hanno Becker305e4e42018-12-11 15:03:16 +0000190 CHACHA20_VALIDATE_RET( ctx != NULL );
191 CHACHA20_VALIDATE_RET( key != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300192
193 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200194 ctx->state[0] = 0x61707865;
195 ctx->state[1] = 0x3320646e;
196 ctx->state[2] = 0x79622d32;
197 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300198
199 /* Set key */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100200 ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
201 ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
202 ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
203 ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
204 ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
205 ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
206 ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
207 ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300208
209 return( 0 );
210}
211
212int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
213 const unsigned char nonce[12],
214 uint32_t counter )
215{
Hanno Becker305e4e42018-12-11 15:03:16 +0000216 CHACHA20_VALIDATE_RET( ctx != NULL );
217 CHACHA20_VALIDATE_RET( nonce != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300218
219 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200220 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300221
222 /* Nonce */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100223 ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
224 ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
225 ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300226
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200227 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200228
229 /* Initially, there's no keystream bytes available */
230 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
231
Daniel King34b822c2016-05-15 17:28:08 -0300232 return( 0 );
233}
234
Daniel Kingbd920622016-05-15 19:56:20 -0300235int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300236 size_t size,
237 const unsigned char *input,
238 unsigned char *output )
239{
240 size_t offset = 0U;
241 size_t i;
242
Hanno Becker305e4e42018-12-11 15:03:16 +0000243 CHACHA20_VALIDATE_RET( ctx != NULL );
244 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
245 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300246
247 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200248 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300249 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200250 output[offset] = input[offset]
251 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300252
253 ctx->keystream_bytes_used++;
254 offset++;
255 size--;
256 }
257
258 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200259 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300260 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200261 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200262 chacha20_block( ctx->state, ctx->keystream8 );
263 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300264
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200265 for( i = 0U; i < 64U; i += 8U )
Daniel King34b822c2016-05-15 17:28:08 -0300266 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200267 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
268 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
269 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
270 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
271 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
272 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
273 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
274 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
Daniel King34b822c2016-05-15 17:28:08 -0300275 }
276
Daniel Kingb8025c52016-05-17 14:43:01 -0300277 offset += CHACHA20_BLOCK_SIZE_BYTES;
278 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300279 }
280
281 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200282 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300283 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200284 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200285 chacha20_block( ctx->state, ctx->keystream8 );
286 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300287
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200288 for( i = 0U; i < size; i++)
Daniel King34b822c2016-05-15 17:28:08 -0300289 {
290 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
291 }
292
293 ctx->keystream_bytes_used = size;
294
Daniel King34b822c2016-05-15 17:28:08 -0300295 }
296
Daniel Kinge6e79682016-05-24 11:16:17 -0300297 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300298}
299
Daniel King34b822c2016-05-15 17:28:08 -0300300int mbedtls_chacha20_crypt( const unsigned char key[32],
301 const unsigned char nonce[12],
302 uint32_t counter,
303 size_t data_len,
304 const unsigned char* input,
305 unsigned char* output )
306{
307 mbedtls_chacha20_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000308 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300309
Hanno Becker305e4e42018-12-11 15:03:16 +0000310 CHACHA20_VALIDATE_RET( key != NULL );
311 CHACHA20_VALIDATE_RET( nonce != NULL );
312 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
313 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
314
Daniel King34b822c2016-05-15 17:28:08 -0300315 mbedtls_chacha20_init( &ctx );
316
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200317 ret = mbedtls_chacha20_setkey( &ctx, key );
318 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300319 goto cleanup;
320
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200321 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
322 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300323 goto cleanup;
324
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200325 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300326
327cleanup:
328 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200329 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300330}
331
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200332#endif /* !MBEDTLS_CHACHA20_ALT */
333
Daniel King34b822c2016-05-15 17:28:08 -0300334#if defined(MBEDTLS_SELF_TEST)
335
336static const unsigned char test_keys[2][32] =
337{
338 {
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
343 },
344 {
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
349 }
350};
351
352static const unsigned char test_nonces[2][12] =
353{
354 {
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00
357 },
358 {
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x02
361 }
362};
363
364static const uint32_t test_counters[2] =
365{
366 0U,
367 1U
368};
369
370static const unsigned char test_input[2][375] =
371{
372 {
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
381 },
382 {
383 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
384 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
385 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
386 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
387 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
388 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
389 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
390 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
391 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
392 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
393 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
394 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
395 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
396 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
397 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
398 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
399 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
400 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
401 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
402 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
403 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
404 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
405 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
406 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
407 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
408 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
409 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
410 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
411 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
412 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
413 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
414 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
415 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
416 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
417 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
418 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
419 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
420 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
421 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
422 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
423 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
424 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
425 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
426 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
427 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
428 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
429 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
430 }
431};
432
433static const unsigned char test_output[2][375] =
434{
435 {
436 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
437 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
438 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
439 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
440 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
441 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
442 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
443 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
444 },
445 {
446 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
447 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
448 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
449 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
450 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
451 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
452 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
453 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
454 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
455 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
456 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
457 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
458 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
459 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
460 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
461 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
462 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
463 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
464 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
465 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
466 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
467 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
468 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
469 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
470 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
471 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
472 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
473 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
474 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
475 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
476 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
477 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
478 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
479 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
480 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
481 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
482 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
483 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
484 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
485 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
486 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
487 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
488 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
489 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
490 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
491 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
492 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
493 }
494};
495
496static const size_t test_lengths[2] =
497{
498 64U,
499 375U
500};
501
Ouss4e0b26872020-08-11 16:07:09 +0100502/* Make sure no other definition is already present. */
503#undef ASSERT
504
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200505#define ASSERT( cond, args ) \
506 do \
507 { \
508 if( ! ( cond ) ) \
509 { \
510 if( verbose != 0 ) \
511 mbedtls_printf args; \
512 \
513 return( -1 ); \
514 } \
515 } \
516 while( 0 )
517
Daniel King34b822c2016-05-15 17:28:08 -0300518int mbedtls_chacha20_self_test( int verbose )
519{
520 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200521 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000522 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300523
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200524 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300525 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200526 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200527 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300528
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200529 ret = mbedtls_chacha20_crypt( test_keys[i],
530 test_nonces[i],
531 test_counters[i],
532 test_lengths[i],
533 test_input[i],
534 output );
Daniel King34b822c2016-05-15 17:28:08 -0300535
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200536 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300537
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200538 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
539 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300540
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200541 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300542 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300543 }
544
545 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300546 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300547
548 return( 0 );
549}
550
551#endif /* MBEDTLS_SELF_TEST */
552
553#endif /* !MBEDTLS_CHACHA20_C */