blob: d851a25bd6f586fdd22927068e63370154098bc0 [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
Bence Szépkútif744bd72020-06-05 13:02:18 +02009 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10 *
11 * This file is provided under the Apache License 2.0, or the
12 * GNU General Public License v2.0 or later.
13 *
14 * **********
15 * Apache License 2.0:
Daniel King34b822c2016-05-15 17:28:08 -030016 *
17 * Licensed under the Apache License, Version 2.0 (the "License"); you may
18 * not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 * http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020029 * **********
30 *
31 * **********
32 * GNU General Public License v2.0 or later:
33 *
34 * This program is free software; you can redistribute it and/or modify
35 * it under the terms of the GNU General Public License as published by
36 * the Free Software Foundation; either version 2 of the License, or
37 * (at your option) any later version.
38 *
39 * This program is distributed in the hope that it will be useful,
40 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 * GNU General Public License for more details.
43 *
44 * You should have received a copy of the GNU General Public License along
45 * with this program; if not, write to the Free Software Foundation, Inc.,
46 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
47 *
48 * **********
49 *
Daniel King34b822c2016-05-15 17:28:08 -030050 * This file is part of mbed TLS (https://tls.mbed.org)
51 */
Daniel King34b822c2016-05-15 17:28:08 -030052
53#if !defined(MBEDTLS_CONFIG_FILE)
54#include "mbedtls/config.h"
55#else
56#include MBEDTLS_CONFIG_FILE
57#endif
58
59#if defined(MBEDTLS_CHACHA20_C)
60
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020061#include "mbedtls/chacha20.h"
62#include "mbedtls/platform_util.h"
Daniel King34b822c2016-05-15 17:28:08 -030063
64#include <stddef.h>
65#include <string.h>
66
67#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
69#include "mbedtls/platform.h"
70#else
71#include <stdio.h>
72#define mbedtls_printf printf
73#endif /* MBEDTLS_PLATFORM_C */
74#endif /* MBEDTLS_SELF_TEST */
75
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020076#if !defined(MBEDTLS_CHACHA20_ALT)
77
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020078#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
79 !defined(inline) && !defined(__cplusplus)
80#define inline __inline
81#endif
82
Hanno Becker305e4e42018-12-11 15:03:16 +000083/* Parameter validation macros */
84#define CHACHA20_VALIDATE_RET( cond ) \
85 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
86#define CHACHA20_VALIDATE( cond ) \
87 MBEDTLS_INTERNAL_VALIDATE( cond )
88
Daniel Kinge6e79682016-05-24 11:16:17 -030089#define BYTES_TO_U32_LE( data, offset ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010090 ( (uint32_t) (data)[offset] \
91 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
92 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
93 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel King34b822c2016-05-15 17:28:08 -030094 )
95
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020096#define ROTL32( value, amount ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010097 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030098
99#define CHACHA20_CTR_INDEX ( 12U )
100
101#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
102
Daniel King34b822c2016-05-15 17:28:08 -0300103/**
104 * \brief ChaCha20 quarter round operation.
105 *
106 * The quarter round is defined as follows (from RFC 7539):
107 * 1. a += b; d ^= a; d <<<= 16;
108 * 2. c += d; b ^= c; b <<<= 12;
109 * 3. a += b; d ^= a; d <<<= 8;
110 * 4. c += d; b ^= c; b <<<= 7;
111 *
112 * \param state ChaCha20 state to modify.
113 * \param a The index of 'a' in the state.
114 * \param b The index of 'b' in the state.
115 * \param c The index of 'c' in the state.
116 * \param d The index of 'd' in the state.
117 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200118static inline void chacha20_quarter_round( uint32_t state[16],
119 size_t a,
120 size_t b,
121 size_t c,
122 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -0300123{
124 /* a += b; d ^= a; d <<<= 16; */
125 state[a] += state[b];
126 state[d] ^= state[a];
127 state[d] = ROTL32( state[d], 16 );
128
129 /* c += d; b ^= c; b <<<= 12 */
130 state[c] += state[d];
131 state[b] ^= state[c];
132 state[b] = ROTL32( state[b], 12 );
133
134 /* a += b; d ^= a; d <<<= 8; */
135 state[a] += state[b];
136 state[d] ^= state[a];
137 state[d] = ROTL32( state[d], 8 );
138
139 /* c += d; b ^= c; b <<<= 7; */
140 state[c] += state[d];
141 state[b] ^= state[c];
142 state[b] = ROTL32( state[b], 7 );
143}
144
145/**
146 * \brief Perform the ChaCha20 inner block operation.
147 *
148 * This function performs two rounds: the column round and the
149 * diagonal round.
150 *
151 * \param state The ChaCha20 state to update.
152 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200153static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300154{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200155 chacha20_quarter_round( state, 0, 4, 8, 12 );
156 chacha20_quarter_round( state, 1, 5, 9, 13 );
157 chacha20_quarter_round( state, 2, 6, 10, 14 );
158 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300159
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200160 chacha20_quarter_round( state, 0, 5, 10, 15 );
161 chacha20_quarter_round( state, 1, 6, 11, 12 );
162 chacha20_quarter_round( state, 2, 7, 8, 13 );
163 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300164}
165
166/**
167 * \brief Generates a keystream block.
168 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200169 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300170 * \param keystream Generated keystream bytes are written to this buffer.
171 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200172static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200173 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300174{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200175 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300176 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300177
Daniel Kingb8025c52016-05-17 14:43:01 -0300178 memcpy( working_state,
179 initial_state,
180 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300181
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200182 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200183 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300184
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200185 working_state[ 0] += initial_state[ 0];
186 working_state[ 1] += initial_state[ 1];
187 working_state[ 2] += initial_state[ 2];
188 working_state[ 3] += initial_state[ 3];
189 working_state[ 4] += initial_state[ 4];
190 working_state[ 5] += initial_state[ 5];
191 working_state[ 6] += initial_state[ 6];
192 working_state[ 7] += initial_state[ 7];
193 working_state[ 8] += initial_state[ 8];
194 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300195 working_state[10] += initial_state[10];
196 working_state[11] += initial_state[11];
197 working_state[12] += initial_state[12];
198 working_state[13] += initial_state[13];
199 working_state[14] += initial_state[14];
200 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300201
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200202 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300203 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200204 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300205
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200206 keystream[offset ] = (unsigned char)( working_state[i] );
207 keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
208 keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
209 keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
Daniel King34b822c2016-05-15 17:28:08 -0300210 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200211
212 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300213}
214
215void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
216{
Hanno Becker305e4e42018-12-11 15:03:16 +0000217 CHACHA20_VALIDATE( ctx != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300218
Hanno Becker305e4e42018-12-11 15:03:16 +0000219 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
220 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
221
222 /* Initially, there's no keystream bytes available */
223 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300224}
225
226void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
227{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200228 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300229 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200230 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300231 }
232}
233
234int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
235 const unsigned char key[32] )
236{
Hanno Becker305e4e42018-12-11 15:03:16 +0000237 CHACHA20_VALIDATE_RET( ctx != NULL );
238 CHACHA20_VALIDATE_RET( key != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300239
240 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200241 ctx->state[0] = 0x61707865;
242 ctx->state[1] = 0x3320646e;
243 ctx->state[2] = 0x79622d32;
244 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300245
246 /* Set key */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200247 ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
248 ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
249 ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
250 ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
251 ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
252 ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
253 ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
254 ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300255
256 return( 0 );
257}
258
259int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
260 const unsigned char nonce[12],
261 uint32_t counter )
262{
Hanno Becker305e4e42018-12-11 15:03:16 +0000263 CHACHA20_VALIDATE_RET( ctx != NULL );
264 CHACHA20_VALIDATE_RET( nonce != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300265
266 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200267 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300268
269 /* Nonce */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200270 ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
271 ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
272 ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300273
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200274 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200275
276 /* Initially, there's no keystream bytes available */
277 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
278
Daniel King34b822c2016-05-15 17:28:08 -0300279 return( 0 );
280}
281
Daniel Kingbd920622016-05-15 19:56:20 -0300282int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300283 size_t size,
284 const unsigned char *input,
285 unsigned char *output )
286{
287 size_t offset = 0U;
288 size_t i;
289
Hanno Becker305e4e42018-12-11 15:03:16 +0000290 CHACHA20_VALIDATE_RET( ctx != NULL );
291 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
292 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300293
294 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200295 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300296 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200297 output[offset] = input[offset]
298 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300299
300 ctx->keystream_bytes_used++;
301 offset++;
302 size--;
303 }
304
305 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200306 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300307 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200308 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200309 chacha20_block( ctx->state, ctx->keystream8 );
310 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300311
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200312 for( i = 0U; i < 64U; i += 8U )
Daniel King34b822c2016-05-15 17:28:08 -0300313 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200314 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
315 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
316 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
317 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
318 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
319 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
320 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
321 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
Daniel King34b822c2016-05-15 17:28:08 -0300322 }
323
Daniel Kingb8025c52016-05-17 14:43:01 -0300324 offset += CHACHA20_BLOCK_SIZE_BYTES;
325 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300326 }
327
328 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200329 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300330 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200331 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200332 chacha20_block( ctx->state, ctx->keystream8 );
333 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300334
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200335 for( i = 0U; i < size; i++)
Daniel King34b822c2016-05-15 17:28:08 -0300336 {
337 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
338 }
339
340 ctx->keystream_bytes_used = size;
341
Daniel King34b822c2016-05-15 17:28:08 -0300342 }
343
Daniel Kinge6e79682016-05-24 11:16:17 -0300344 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300345}
346
Daniel King34b822c2016-05-15 17:28:08 -0300347int mbedtls_chacha20_crypt( const unsigned char key[32],
348 const unsigned char nonce[12],
349 uint32_t counter,
350 size_t data_len,
351 const unsigned char* input,
352 unsigned char* output )
353{
354 mbedtls_chacha20_context ctx;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200355 int ret;
Daniel King34b822c2016-05-15 17:28:08 -0300356
Hanno Becker305e4e42018-12-11 15:03:16 +0000357 CHACHA20_VALIDATE_RET( key != NULL );
358 CHACHA20_VALIDATE_RET( nonce != NULL );
359 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
360 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
361
Daniel King34b822c2016-05-15 17:28:08 -0300362 mbedtls_chacha20_init( &ctx );
363
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200364 ret = mbedtls_chacha20_setkey( &ctx, key );
365 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300366 goto cleanup;
367
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200368 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
369 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300370 goto cleanup;
371
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200372 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300373
374cleanup:
375 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200376 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300377}
378
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200379#endif /* !MBEDTLS_CHACHA20_ALT */
380
Daniel King34b822c2016-05-15 17:28:08 -0300381#if defined(MBEDTLS_SELF_TEST)
382
383static const unsigned char test_keys[2][32] =
384{
385 {
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 },
391 {
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
396 }
397};
398
399static const unsigned char test_nonces[2][12] =
400{
401 {
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00
404 },
405 {
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x02
408 }
409};
410
411static const uint32_t test_counters[2] =
412{
413 0U,
414 1U
415};
416
417static const unsigned char test_input[2][375] =
418{
419 {
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
428 },
429 {
430 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
431 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
432 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
433 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
434 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
435 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
436 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
437 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
438 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
439 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
440 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
441 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
442 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
443 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
444 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
445 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
446 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
447 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
448 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
449 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
450 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
451 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
452 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
453 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
454 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
455 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
456 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
457 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
458 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
459 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
460 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
461 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
462 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
463 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
464 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
465 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
466 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
467 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
468 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
469 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
470 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
471 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
472 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
473 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
474 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
475 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
476 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
477 }
478};
479
480static const unsigned char test_output[2][375] =
481{
482 {
483 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
484 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
485 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
486 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
487 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
488 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
489 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
490 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
491 },
492 {
493 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
494 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
495 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
496 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
497 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
498 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
499 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
500 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
501 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
502 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
503 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
504 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
505 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
506 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
507 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
508 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
509 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
510 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
511 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
512 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
513 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
514 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
515 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
516 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
517 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
518 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
519 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
520 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
521 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
522 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
523 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
524 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
525 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
526 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
527 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
528 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
529 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
530 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
531 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
532 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
533 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
534 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
535 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
536 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
537 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
538 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
539 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
540 }
541};
542
543static const size_t test_lengths[2] =
544{
545 64U,
546 375U
547};
548
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200549#define ASSERT( cond, args ) \
550 do \
551 { \
552 if( ! ( cond ) ) \
553 { \
554 if( verbose != 0 ) \
555 mbedtls_printf args; \
556 \
557 return( -1 ); \
558 } \
559 } \
560 while( 0 )
561
Daniel King34b822c2016-05-15 17:28:08 -0300562int mbedtls_chacha20_self_test( int verbose )
563{
564 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200565 unsigned i;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200566 int ret;
Daniel King34b822c2016-05-15 17:28:08 -0300567
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200568 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300569 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200570 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200571 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300572
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200573 ret = mbedtls_chacha20_crypt( test_keys[i],
574 test_nonces[i],
575 test_counters[i],
576 test_lengths[i],
577 test_input[i],
578 output );
Daniel King34b822c2016-05-15 17:28:08 -0300579
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200580 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300581
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200582 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
583 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300584
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200585 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300586 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300587 }
588
589 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300590 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300591
592 return( 0 );
593}
594
595#endif /* MBEDTLS_SELF_TEST */
596
597#endif /* !MBEDTLS_CHACHA20_C */