4 * \brief ChaCha20 cipher.
6 * \author Daniel King <damaki.gh@gmail.com>
8 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
9 * SPDX-License-Identifier: Apache-2.0
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
15 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * This file is part of mbed TLS (https://tls.mbed.org)
26 #if !defined(MBEDTLS_CONFIG_FILE)
27 #include "mbedtls/config.h"
29 #include MBEDTLS_CONFIG_FILE
32 #if defined(MBEDTLS_CHACHA20_C)
34 #include "mbedtls/chacha20.h"
35 #include "mbedtls/platform_util.h"
40 #if defined(MBEDTLS_SELF_TEST)
41 #if defined(MBEDTLS_PLATFORM_C)
42 #include "mbedtls/platform.h"
45 #define mbedtls_printf printf
46 #endif /* MBEDTLS_PLATFORM_C */
47 #endif /* MBEDTLS_SELF_TEST */
49 #if !defined(MBEDTLS_CHACHA20_ALT)
51 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
52 !defined(inline) && !defined(__cplusplus)
53 #define inline __inline
56 /* Parameter validation macros */
57 #define CHACHA20_VALIDATE_RET( cond ) \
58 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
59 #define CHACHA20_VALIDATE( cond ) \
60 MBEDTLS_INTERNAL_VALIDATE( cond )
62 #define BYTES_TO_U32_LE( data, offset ) \
63 ( (uint32_t) (data)[offset] \
64 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
65 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
66 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
69 #define ROTL32( value, amount ) \
70 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
72 #define CHACHA20_CTR_INDEX ( 12U )
74 #define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
77 * \brief ChaCha20 quarter round operation.
79 * The quarter round is defined as follows (from RFC 7539):
80 * 1. a += b; d ^= a; d <<<= 16;
81 * 2. c += d; b ^= c; b <<<= 12;
82 * 3. a += b; d ^= a; d <<<= 8;
83 * 4. c += d; b ^= c; b <<<= 7;
85 * \param state ChaCha20 state to modify.
86 * \param a The index of 'a' in the state.
87 * \param b The index of 'b' in the state.
88 * \param c The index of 'c' in the state.
89 * \param d The index of 'd' in the state.
91 static inline void chacha20_quarter_round( uint32_t state[16],
97 /* a += b; d ^= a; d <<<= 16; */
100 state[d] = ROTL32( state[d], 16 );
102 /* c += d; b ^= c; b <<<= 12 */
103 state[c] += state[d];
104 state[b] ^= state[c];
105 state[b] = ROTL32( state[b], 12 );
107 /* a += b; d ^= a; d <<<= 8; */
108 state[a] += state[b];
109 state[d] ^= state[a];
110 state[d] = ROTL32( state[d], 8 );
112 /* c += d; b ^= c; b <<<= 7; */
113 state[c] += state[d];
114 state[b] ^= state[c];
115 state[b] = ROTL32( state[b], 7 );
119 * \brief Perform the ChaCha20 inner block operation.
121 * This function performs two rounds: the column round and the
124 * \param state The ChaCha20 state to update.
126 static void chacha20_inner_block( uint32_t state[16] )
128 chacha20_quarter_round( state, 0, 4, 8, 12 );
129 chacha20_quarter_round( state, 1, 5, 9, 13 );
130 chacha20_quarter_round( state, 2, 6, 10, 14 );
131 chacha20_quarter_round( state, 3, 7, 11, 15 );
133 chacha20_quarter_round( state, 0, 5, 10, 15 );
134 chacha20_quarter_round( state, 1, 6, 11, 12 );
135 chacha20_quarter_round( state, 2, 7, 8, 13 );
136 chacha20_quarter_round( state, 3, 4, 9, 14 );
140 * \brief Generates a keystream block.
142 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
143 * \param keystream Generated keystream bytes are written to this buffer.
145 static void chacha20_block( const uint32_t initial_state[16],
146 unsigned char keystream[64] )
148 uint32_t working_state[16];
151 memcpy( working_state,
153 CHACHA20_BLOCK_SIZE_BYTES );
155 for( i = 0U; i < 10U; i++ )
156 chacha20_inner_block( working_state );
158 working_state[ 0] += initial_state[ 0];
159 working_state[ 1] += initial_state[ 1];
160 working_state[ 2] += initial_state[ 2];
161 working_state[ 3] += initial_state[ 3];
162 working_state[ 4] += initial_state[ 4];
163 working_state[ 5] += initial_state[ 5];
164 working_state[ 6] += initial_state[ 6];
165 working_state[ 7] += initial_state[ 7];
166 working_state[ 8] += initial_state[ 8];
167 working_state[ 9] += initial_state[ 9];
168 working_state[10] += initial_state[10];
169 working_state[11] += initial_state[11];
170 working_state[12] += initial_state[12];
171 working_state[13] += initial_state[13];
172 working_state[14] += initial_state[14];
173 working_state[15] += initial_state[15];
175 for( i = 0U; i < 16; i++ )
177 size_t offset = i * 4U;
179 keystream[offset ] = (unsigned char)( working_state[i] );
180 keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
181 keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
182 keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
185 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
188 void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
190 CHACHA20_VALIDATE( ctx != NULL );
192 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
193 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
195 /* Initially, there's no keystream bytes available */
196 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
199 void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
203 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
207 int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
208 const unsigned char key[32] )
210 CHACHA20_VALIDATE_RET( ctx != NULL );
211 CHACHA20_VALIDATE_RET( key != NULL );
213 /* ChaCha20 constants - the string "expand 32-byte k" */
214 ctx->state[0] = 0x61707865;
215 ctx->state[1] = 0x3320646e;
216 ctx->state[2] = 0x79622d32;
217 ctx->state[3] = 0x6b206574;
220 ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
221 ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
222 ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
223 ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
224 ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
225 ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
226 ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
227 ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
232 int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
233 const unsigned char nonce[12],
236 CHACHA20_VALIDATE_RET( ctx != NULL );
237 CHACHA20_VALIDATE_RET( nonce != NULL );
240 ctx->state[12] = counter;
243 ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
244 ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
245 ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
247 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
249 /* Initially, there's no keystream bytes available */
250 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
255 int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
257 const unsigned char *input,
258 unsigned char *output )
263 CHACHA20_VALIDATE_RET( ctx != NULL );
264 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
265 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
267 /* Use leftover keystream bytes, if available */
268 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
270 output[offset] = input[offset]
271 ^ ctx->keystream8[ctx->keystream_bytes_used];
273 ctx->keystream_bytes_used++;
278 /* Process full blocks */
279 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
281 /* Generate new keystream block and increment counter */
282 chacha20_block( ctx->state, ctx->keystream8 );
283 ctx->state[CHACHA20_CTR_INDEX]++;
285 for( i = 0U; i < 64U; i += 8U )
287 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
288 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
289 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
290 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
291 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
292 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
293 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
294 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
297 offset += CHACHA20_BLOCK_SIZE_BYTES;
298 size -= CHACHA20_BLOCK_SIZE_BYTES;
301 /* Last (partial) block */
304 /* Generate new keystream block and increment counter */
305 chacha20_block( ctx->state, ctx->keystream8 );
306 ctx->state[CHACHA20_CTR_INDEX]++;
308 for( i = 0U; i < size; i++)
310 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
313 ctx->keystream_bytes_used = size;
320 int mbedtls_chacha20_crypt( const unsigned char key[32],
321 const unsigned char nonce[12],
324 const unsigned char* input,
325 unsigned char* output )
327 mbedtls_chacha20_context ctx;
330 CHACHA20_VALIDATE_RET( key != NULL );
331 CHACHA20_VALIDATE_RET( nonce != NULL );
332 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
333 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
335 mbedtls_chacha20_init( &ctx );
337 ret = mbedtls_chacha20_setkey( &ctx, key );
341 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
345 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
348 mbedtls_chacha20_free( &ctx );
352 #endif /* !MBEDTLS_CHACHA20_ALT */
354 #if defined(MBEDTLS_SELF_TEST)
356 static const unsigned char test_keys[2][32] =
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01
372 static const unsigned char test_nonces[2][12] =
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x02
384 static const uint32_t test_counters[2] =
390 static const unsigned char test_input[2][375] =
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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
403 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
404 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
405 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
406 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
407 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
408 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
409 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
410 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
411 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
412 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
413 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
414 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
415 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
416 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
417 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
418 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
419 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
420 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
421 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
422 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
423 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
424 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
425 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
426 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
427 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
428 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
429 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
430 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
431 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
432 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
433 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
434 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
435 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
436 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
437 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
438 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
439 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
440 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
441 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
442 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
443 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
444 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
445 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
446 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
447 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
448 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
449 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
453 static const unsigned char test_output[2][375] =
456 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
457 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
458 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
459 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
460 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
461 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
462 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
463 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
466 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
467 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
468 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
469 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
470 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
471 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
472 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
473 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
474 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
475 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
476 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
477 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
478 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
479 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
480 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
481 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
482 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
483 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
484 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
485 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
486 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
487 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
488 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
489 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
490 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
491 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
492 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
493 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
494 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
495 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
496 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
497 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
498 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
499 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
500 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
501 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
502 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
503 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
504 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
505 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
506 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
507 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
508 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
509 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
510 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
511 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
512 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
516 static const size_t test_lengths[2] =
522 #define ASSERT( cond, args ) \
528 mbedtls_printf args; \
535 int mbedtls_chacha20_self_test( int verbose )
537 unsigned char output[381];
541 for( i = 0U; i < 2U; i++ )
544 mbedtls_printf( " ChaCha20 test %u ", i );
546 ret = mbedtls_chacha20_crypt( test_keys[i],
553 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
555 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
556 ( "failed (output)\n" ) );
559 mbedtls_printf( "passed\n" );
563 mbedtls_printf( "\n" );
568 #endif /* MBEDTLS_SELF_TEST */
570 #endif /* !MBEDTLS_CHACHA20_C */