blob: f991b218488b67d463426c0178262a5898acd26d [file] [log] [blame]
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001/* SPDX-License-Identifier: Apache-2.0 */
2/**
3 * \file chacha20.c
4 *
5 * \brief ChaCha20 cipher.
6 *
7 * \author Daniel King <damaki.gh@gmail.com>
8 *
9 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
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.
22 *
23 * This file is part of mbed TLS (https://tls.mbed.org)
24 */
25
26#if !defined(MBEDTLS_CONFIG_FILE)
27#include "mbedtls/config.h"
28#else
29#include MBEDTLS_CONFIG_FILE
30#endif
31
32#if defined(MBEDTLS_CHACHA20_C)
33
34#include "mbedtls/chacha20.h"
35#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020036#include "mbedtls/error.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010037
38#include <stddef.h>
39#include <string.h>
40
41#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
43#include "mbedtls/platform.h"
44#else
45#include <stdio.h>
46#define mbedtls_printf printf
47#endif /* MBEDTLS_PLATFORM_C */
48#endif /* MBEDTLS_SELF_TEST */
49
50#if !defined(MBEDTLS_CHACHA20_ALT)
51
52#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
53 !defined(inline) && !defined(__cplusplus)
54#define inline __inline
55#endif
56
57/* Parameter validation macros */
58#define CHACHA20_VALIDATE_RET( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
60#define CHACHA20_VALIDATE( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE( cond )
62
63#define BYTES_TO_U32_LE( data, offset ) \
Jerome Forissier5b25c762020-04-07 11:18:49 +020064 ( (uint32_t) (data)[offset] \
65 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
66 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
67 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +010068 )
69
70#define ROTL32( value, amount ) \
Jerome Forissier5b25c762020-04-07 11:18:49 +020071 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Jens Wiklander3d3b0592019-03-20 15:30:29 +010072
73#define CHACHA20_CTR_INDEX ( 12U )
74
75#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
76
77/**
78 * \brief ChaCha20 quarter round operation.
79 *
80 * The quarter round is defined as follows (from RFC 7539):
81 * 1. a += b; d ^= a; d <<<= 16;
82 * 2. c += d; b ^= c; b <<<= 12;
83 * 3. a += b; d ^= a; d <<<= 8;
84 * 4. c += d; b ^= c; b <<<= 7;
85 *
86 * \param state ChaCha20 state to modify.
87 * \param a The index of 'a' in the state.
88 * \param b The index of 'b' in the state.
89 * \param c The index of 'c' in the state.
90 * \param d The index of 'd' in the state.
91 */
92static inline void chacha20_quarter_round( uint32_t state[16],
93 size_t a,
94 size_t b,
95 size_t c,
96 size_t d )
97{
98 /* a += b; d ^= a; d <<<= 16; */
99 state[a] += state[b];
100 state[d] ^= state[a];
101 state[d] = ROTL32( state[d], 16 );
102
103 /* c += d; b ^= c; b <<<= 12 */
104 state[c] += state[d];
105 state[b] ^= state[c];
106 state[b] = ROTL32( state[b], 12 );
107
108 /* a += b; d ^= a; d <<<= 8; */
109 state[a] += state[b];
110 state[d] ^= state[a];
111 state[d] = ROTL32( state[d], 8 );
112
113 /* c += d; b ^= c; b <<<= 7; */
114 state[c] += state[d];
115 state[b] ^= state[c];
116 state[b] = ROTL32( state[b], 7 );
117}
118
119/**
120 * \brief Perform the ChaCha20 inner block operation.
121 *
122 * This function performs two rounds: the column round and the
123 * diagonal round.
124 *
125 * \param state The ChaCha20 state to update.
126 */
127static void chacha20_inner_block( uint32_t state[16] )
128{
129 chacha20_quarter_round( state, 0, 4, 8, 12 );
130 chacha20_quarter_round( state, 1, 5, 9, 13 );
131 chacha20_quarter_round( state, 2, 6, 10, 14 );
132 chacha20_quarter_round( state, 3, 7, 11, 15 );
133
134 chacha20_quarter_round( state, 0, 5, 10, 15 );
135 chacha20_quarter_round( state, 1, 6, 11, 12 );
136 chacha20_quarter_round( state, 2, 7, 8, 13 );
137 chacha20_quarter_round( state, 3, 4, 9, 14 );
138}
139
140/**
141 * \brief Generates a keystream block.
142 *
143 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
144 * \param keystream Generated keystream bytes are written to this buffer.
145 */
146static void chacha20_block( const uint32_t initial_state[16],
147 unsigned char keystream[64] )
148{
149 uint32_t working_state[16];
150 size_t i;
151
152 memcpy( working_state,
153 initial_state,
154 CHACHA20_BLOCK_SIZE_BYTES );
155
156 for( i = 0U; i < 10U; i++ )
157 chacha20_inner_block( working_state );
158
159 working_state[ 0] += initial_state[ 0];
160 working_state[ 1] += initial_state[ 1];
161 working_state[ 2] += initial_state[ 2];
162 working_state[ 3] += initial_state[ 3];
163 working_state[ 4] += initial_state[ 4];
164 working_state[ 5] += initial_state[ 5];
165 working_state[ 6] += initial_state[ 6];
166 working_state[ 7] += initial_state[ 7];
167 working_state[ 8] += initial_state[ 8];
168 working_state[ 9] += initial_state[ 9];
169 working_state[10] += initial_state[10];
170 working_state[11] += initial_state[11];
171 working_state[12] += initial_state[12];
172 working_state[13] += initial_state[13];
173 working_state[14] += initial_state[14];
174 working_state[15] += initial_state[15];
175
176 for( i = 0U; i < 16; i++ )
177 {
178 size_t offset = i * 4U;
179
180 keystream[offset ] = (unsigned char)( working_state[i] );
181 keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
182 keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
183 keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
184 }
185
186 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
187}
188
189void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
190{
191 CHACHA20_VALIDATE( ctx != NULL );
192
193 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
194 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
195
196 /* Initially, there's no keystream bytes available */
197 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
198}
199
200void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
201{
202 if( ctx != NULL )
203 {
204 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
205 }
206}
207
208int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
209 const unsigned char key[32] )
210{
211 CHACHA20_VALIDATE_RET( ctx != NULL );
212 CHACHA20_VALIDATE_RET( key != NULL );
213
214 /* ChaCha20 constants - the string "expand 32-byte k" */
215 ctx->state[0] = 0x61707865;
216 ctx->state[1] = 0x3320646e;
217 ctx->state[2] = 0x79622d32;
218 ctx->state[3] = 0x6b206574;
219
220 /* Set key */
221 ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
222 ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
223 ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
224 ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
225 ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
226 ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
227 ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
228 ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
229
230 return( 0 );
231}
232
233int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
234 const unsigned char nonce[12],
235 uint32_t counter )
236{
237 CHACHA20_VALIDATE_RET( ctx != NULL );
238 CHACHA20_VALIDATE_RET( nonce != NULL );
239
240 /* Counter */
241 ctx->state[12] = counter;
242
243 /* Nonce */
244 ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
245 ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
246 ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
247
248 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
249
250 /* Initially, there's no keystream bytes available */
251 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
252
253 return( 0 );
254}
255
256int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
257 size_t size,
258 const unsigned char *input,
259 unsigned char *output )
260{
261 size_t offset = 0U;
262 size_t i;
263
264 CHACHA20_VALIDATE_RET( ctx != NULL );
265 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
266 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
267
268 /* Use leftover keystream bytes, if available */
269 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
270 {
271 output[offset] = input[offset]
272 ^ ctx->keystream8[ctx->keystream_bytes_used];
273
274 ctx->keystream_bytes_used++;
275 offset++;
276 size--;
277 }
278
279 /* Process full blocks */
280 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
281 {
282 /* Generate new keystream block and increment counter */
283 chacha20_block( ctx->state, ctx->keystream8 );
284 ctx->state[CHACHA20_CTR_INDEX]++;
285
286 for( i = 0U; i < 64U; i += 8U )
287 {
288 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
289 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
290 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
291 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
292 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
293 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
294 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
295 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
296 }
297
298 offset += CHACHA20_BLOCK_SIZE_BYTES;
299 size -= CHACHA20_BLOCK_SIZE_BYTES;
300 }
301
302 /* Last (partial) block */
303 if( size > 0U )
304 {
305 /* Generate new keystream block and increment counter */
306 chacha20_block( ctx->state, ctx->keystream8 );
307 ctx->state[CHACHA20_CTR_INDEX]++;
308
309 for( i = 0U; i < size; i++)
310 {
311 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
312 }
313
314 ctx->keystream_bytes_used = size;
315
316 }
317
318 return( 0 );
319}
320
321int mbedtls_chacha20_crypt( const unsigned char key[32],
322 const unsigned char nonce[12],
323 uint32_t counter,
324 size_t data_len,
325 const unsigned char* input,
326 unsigned char* output )
327{
328 mbedtls_chacha20_context ctx;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200329 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100330
331 CHACHA20_VALIDATE_RET( key != NULL );
332 CHACHA20_VALIDATE_RET( nonce != NULL );
333 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
334 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
335
336 mbedtls_chacha20_init( &ctx );
337
338 ret = mbedtls_chacha20_setkey( &ctx, key );
339 if( ret != 0 )
340 goto cleanup;
341
342 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
343 if( ret != 0 )
344 goto cleanup;
345
346 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
347
348cleanup:
349 mbedtls_chacha20_free( &ctx );
350 return( ret );
351}
352
353#endif /* !MBEDTLS_CHACHA20_ALT */
354
355#if defined(MBEDTLS_SELF_TEST)
356
357static const unsigned char test_keys[2][32] =
358{
359 {
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
364 },
365 {
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
370 }
371};
372
373static const unsigned char test_nonces[2][12] =
374{
375 {
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00
378 },
379 {
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x02
382 }
383};
384
385static const uint32_t test_counters[2] =
386{
387 0U,
388 1U
389};
390
391static const unsigned char test_input[2][375] =
392{
393 {
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
402 },
403 {
404 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
405 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
406 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
407 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
408 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
409 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
410 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
411 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
412 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
413 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
414 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
415 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
416 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
417 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
418 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
419 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
420 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
421 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
422 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
423 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
424 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
425 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
426 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
427 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
428 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
429 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
430 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
431 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
432 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
433 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
434 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
435 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
436 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
437 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
438 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
439 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
440 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
441 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
442 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
443 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
444 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
445 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
446 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
447 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
448 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
449 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
450 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
451 }
452};
453
454static const unsigned char test_output[2][375] =
455{
456 {
457 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
458 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
459 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
460 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
461 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
462 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
463 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
464 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
465 },
466 {
467 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
468 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
469 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
470 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
471 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
472 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
473 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
474 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
475 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
476 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
477 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
478 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
479 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
480 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
481 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
482 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
483 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
484 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
485 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
486 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
487 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
488 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
489 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
490 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
491 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
492 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
493 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
494 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
495 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
496 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
497 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
498 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
499 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
500 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
501 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
502 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
503 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
504 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
505 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
506 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
507 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
508 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
509 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
510 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
511 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
512 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
513 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
514 }
515};
516
517static const size_t test_lengths[2] =
518{
519 64U,
520 375U
521};
522
523#define ASSERT( cond, args ) \
524 do \
525 { \
526 if( ! ( cond ) ) \
527 { \
528 if( verbose != 0 ) \
529 mbedtls_printf args; \
530 \
531 return( -1 ); \
532 } \
533 } \
534 while( 0 )
535
536int mbedtls_chacha20_self_test( int verbose )
537{
538 unsigned char output[381];
539 unsigned i;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200540 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100541
542 for( i = 0U; i < 2U; i++ )
543 {
544 if( verbose != 0 )
545 mbedtls_printf( " ChaCha20 test %u ", i );
546
547 ret = mbedtls_chacha20_crypt( test_keys[i],
548 test_nonces[i],
549 test_counters[i],
550 test_lengths[i],
551 test_input[i],
552 output );
553
554 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
555
556 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
557 ( "failed (output)\n" ) );
558
559 if( verbose != 0 )
560 mbedtls_printf( "passed\n" );
561 }
562
563 if( verbose != 0 )
564 mbedtls_printf( "\n" );
565
566 return( 0 );
567}
568
569#endif /* MBEDTLS_SELF_TEST */
570
571#endif /* !MBEDTLS_CHACHA20_C */