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