blob: 80fe50cc672fe628996676c4928cdcd0817cc672 [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útia2947ac2020-08-19 16:37:36 +02008 * Copyright The Mbed TLS Contributors
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 * **********
Daniel King34b822c2016-05-15 17:28:08 -030049 */
Daniel King34b822c2016-05-15 17:28:08 -030050
51#if !defined(MBEDTLS_CONFIG_FILE)
52#include "mbedtls/config.h"
53#else
54#include MBEDTLS_CONFIG_FILE
55#endif
56
57#if defined(MBEDTLS_CHACHA20_C)
58
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020059#include "mbedtls/chacha20.h"
60#include "mbedtls/platform_util.h"
Daniel King34b822c2016-05-15 17:28:08 -030061
62#include <stddef.h>
63#include <string.h>
64
65#if defined(MBEDTLS_SELF_TEST)
66#if defined(MBEDTLS_PLATFORM_C)
67#include "mbedtls/platform.h"
68#else
69#include <stdio.h>
70#define mbedtls_printf printf
71#endif /* MBEDTLS_PLATFORM_C */
72#endif /* MBEDTLS_SELF_TEST */
73
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020074#if !defined(MBEDTLS_CHACHA20_ALT)
75
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020076#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
77 !defined(inline) && !defined(__cplusplus)
78#define inline __inline
79#endif
80
Hanno Becker305e4e42018-12-11 15:03:16 +000081/* Parameter validation macros */
82#define CHACHA20_VALIDATE_RET( cond ) \
83 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
84#define CHACHA20_VALIDATE( cond ) \
85 MBEDTLS_INTERNAL_VALIDATE( cond )
86
Daniel Kinge6e79682016-05-24 11:16:17 -030087#define BYTES_TO_U32_LE( data, offset ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010088 ( (uint32_t) (data)[offset] \
89 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
90 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
91 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel King34b822c2016-05-15 17:28:08 -030092 )
93
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020094#define ROTL32( value, amount ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010095 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030096
97#define CHACHA20_CTR_INDEX ( 12U )
98
99#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
100
Daniel King34b822c2016-05-15 17:28:08 -0300101/**
102 * \brief ChaCha20 quarter round operation.
103 *
104 * The quarter round is defined as follows (from RFC 7539):
105 * 1. a += b; d ^= a; d <<<= 16;
106 * 2. c += d; b ^= c; b <<<= 12;
107 * 3. a += b; d ^= a; d <<<= 8;
108 * 4. c += d; b ^= c; b <<<= 7;
109 *
110 * \param state ChaCha20 state to modify.
111 * \param a The index of 'a' in the state.
112 * \param b The index of 'b' in the state.
113 * \param c The index of 'c' in the state.
114 * \param d The index of 'd' in the state.
115 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200116static inline void chacha20_quarter_round( uint32_t state[16],
117 size_t a,
118 size_t b,
119 size_t c,
120 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -0300121{
122 /* a += b; d ^= a; d <<<= 16; */
123 state[a] += state[b];
124 state[d] ^= state[a];
125 state[d] = ROTL32( state[d], 16 );
126
127 /* c += d; b ^= c; b <<<= 12 */
128 state[c] += state[d];
129 state[b] ^= state[c];
130 state[b] = ROTL32( state[b], 12 );
131
132 /* a += b; d ^= a; d <<<= 8; */
133 state[a] += state[b];
134 state[d] ^= state[a];
135 state[d] = ROTL32( state[d], 8 );
136
137 /* c += d; b ^= c; b <<<= 7; */
138 state[c] += state[d];
139 state[b] ^= state[c];
140 state[b] = ROTL32( state[b], 7 );
141}
142
143/**
144 * \brief Perform the ChaCha20 inner block operation.
145 *
146 * This function performs two rounds: the column round and the
147 * diagonal round.
148 *
149 * \param state The ChaCha20 state to update.
150 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200151static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300152{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200153 chacha20_quarter_round( state, 0, 4, 8, 12 );
154 chacha20_quarter_round( state, 1, 5, 9, 13 );
155 chacha20_quarter_round( state, 2, 6, 10, 14 );
156 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300157
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200158 chacha20_quarter_round( state, 0, 5, 10, 15 );
159 chacha20_quarter_round( state, 1, 6, 11, 12 );
160 chacha20_quarter_round( state, 2, 7, 8, 13 );
161 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300162}
163
164/**
165 * \brief Generates a keystream block.
166 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200167 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300168 * \param keystream Generated keystream bytes are written to this buffer.
169 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200170static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200171 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300172{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200173 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300174 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300175
Daniel Kingb8025c52016-05-17 14:43:01 -0300176 memcpy( working_state,
177 initial_state,
178 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300179
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200180 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200181 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300182
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200183 working_state[ 0] += initial_state[ 0];
184 working_state[ 1] += initial_state[ 1];
185 working_state[ 2] += initial_state[ 2];
186 working_state[ 3] += initial_state[ 3];
187 working_state[ 4] += initial_state[ 4];
188 working_state[ 5] += initial_state[ 5];
189 working_state[ 6] += initial_state[ 6];
190 working_state[ 7] += initial_state[ 7];
191 working_state[ 8] += initial_state[ 8];
192 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300193 working_state[10] += initial_state[10];
194 working_state[11] += initial_state[11];
195 working_state[12] += initial_state[12];
196 working_state[13] += initial_state[13];
197 working_state[14] += initial_state[14];
198 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300199
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200200 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300201 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200202 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300203
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200204 keystream[offset ] = (unsigned char)( working_state[i] );
205 keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
206 keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
207 keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
Daniel King34b822c2016-05-15 17:28:08 -0300208 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200209
210 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300211}
212
213void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
214{
Hanno Becker305e4e42018-12-11 15:03:16 +0000215 CHACHA20_VALIDATE( ctx != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300216
Hanno Becker305e4e42018-12-11 15:03:16 +0000217 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
218 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
219
220 /* Initially, there's no keystream bytes available */
221 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300222}
223
224void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
225{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200226 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300227 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200228 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300229 }
230}
231
232int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
233 const unsigned char key[32] )
234{
Hanno Becker305e4e42018-12-11 15:03:16 +0000235 CHACHA20_VALIDATE_RET( ctx != NULL );
236 CHACHA20_VALIDATE_RET( key != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300237
238 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200239 ctx->state[0] = 0x61707865;
240 ctx->state[1] = 0x3320646e;
241 ctx->state[2] = 0x79622d32;
242 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300243
244 /* Set key */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200245 ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
246 ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
247 ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
248 ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
249 ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
250 ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
251 ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
252 ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300253
254 return( 0 );
255}
256
257int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
258 const unsigned char nonce[12],
259 uint32_t counter )
260{
Hanno Becker305e4e42018-12-11 15:03:16 +0000261 CHACHA20_VALIDATE_RET( ctx != NULL );
262 CHACHA20_VALIDATE_RET( nonce != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300263
264 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200265 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300266
267 /* Nonce */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200268 ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
269 ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
270 ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300271
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200272 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200273
274 /* Initially, there's no keystream bytes available */
275 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
276
Daniel King34b822c2016-05-15 17:28:08 -0300277 return( 0 );
278}
279
Daniel Kingbd920622016-05-15 19:56:20 -0300280int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300281 size_t size,
282 const unsigned char *input,
283 unsigned char *output )
284{
285 size_t offset = 0U;
286 size_t i;
287
Hanno Becker305e4e42018-12-11 15:03:16 +0000288 CHACHA20_VALIDATE_RET( ctx != NULL );
289 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
290 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300291
292 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200293 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300294 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200295 output[offset] = input[offset]
296 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300297
298 ctx->keystream_bytes_used++;
299 offset++;
300 size--;
301 }
302
303 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200304 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300305 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200306 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200307 chacha20_block( ctx->state, ctx->keystream8 );
308 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300309
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200310 for( i = 0U; i < 64U; i += 8U )
Daniel King34b822c2016-05-15 17:28:08 -0300311 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200312 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
313 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
314 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
315 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
316 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
317 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
318 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
319 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
Daniel King34b822c2016-05-15 17:28:08 -0300320 }
321
Daniel Kingb8025c52016-05-17 14:43:01 -0300322 offset += CHACHA20_BLOCK_SIZE_BYTES;
323 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300324 }
325
326 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200327 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300328 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200329 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200330 chacha20_block( ctx->state, ctx->keystream8 );
331 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300332
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200333 for( i = 0U; i < size; i++)
Daniel King34b822c2016-05-15 17:28:08 -0300334 {
335 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
336 }
337
338 ctx->keystream_bytes_used = size;
339
Daniel King34b822c2016-05-15 17:28:08 -0300340 }
341
Daniel Kinge6e79682016-05-24 11:16:17 -0300342 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300343}
344
Daniel King34b822c2016-05-15 17:28:08 -0300345int mbedtls_chacha20_crypt( const unsigned char key[32],
346 const unsigned char nonce[12],
347 uint32_t counter,
348 size_t data_len,
349 const unsigned char* input,
350 unsigned char* output )
351{
352 mbedtls_chacha20_context ctx;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200353 int ret;
Daniel King34b822c2016-05-15 17:28:08 -0300354
Hanno Becker305e4e42018-12-11 15:03:16 +0000355 CHACHA20_VALIDATE_RET( key != NULL );
356 CHACHA20_VALIDATE_RET( nonce != NULL );
357 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
358 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
359
Daniel King34b822c2016-05-15 17:28:08 -0300360 mbedtls_chacha20_init( &ctx );
361
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200362 ret = mbedtls_chacha20_setkey( &ctx, key );
363 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300364 goto cleanup;
365
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200366 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
367 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300368 goto cleanup;
369
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200370 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300371
372cleanup:
373 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200374 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300375}
376
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200377#endif /* !MBEDTLS_CHACHA20_ALT */
378
Daniel King34b822c2016-05-15 17:28:08 -0300379#if defined(MBEDTLS_SELF_TEST)
380
381static const unsigned char test_keys[2][32] =
382{
383 {
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
388 },
389 {
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, 0x01
394 }
395};
396
397static const unsigned char test_nonces[2][12] =
398{
399 {
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00
402 },
403 {
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x02
406 }
407};
408
409static const uint32_t test_counters[2] =
410{
411 0U,
412 1U
413};
414
415static const unsigned char test_input[2][375] =
416{
417 {
418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 },
427 {
428 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
429 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
430 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
431 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
432 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
433 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
434 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
435 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
436 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
437 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
438 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
439 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
440 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
441 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
442 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
443 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
444 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
445 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
446 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
447 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
448 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
449 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
450 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
451 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
452 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
453 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
454 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
455 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
456 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
457 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
458 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
459 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
460 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
461 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
462 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
463 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
464 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
465 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
466 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
467 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
468 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
469 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
470 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
471 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
472 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
473 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
474 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
475 }
476};
477
478static const unsigned char test_output[2][375] =
479{
480 {
481 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
482 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
483 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
484 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
485 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
486 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
487 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
488 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
489 },
490 {
491 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
492 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
493 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
494 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
495 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
496 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
497 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
498 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
499 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
500 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
501 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
502 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
503 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
504 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
505 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
506 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
507 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
508 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
509 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
510 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
511 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
512 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
513 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
514 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
515 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
516 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
517 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
518 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
519 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
520 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
521 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
522 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
523 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
524 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
525 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
526 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
527 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
528 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
529 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
530 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
531 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
532 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
533 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
534 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
535 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
536 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
537 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
538 }
539};
540
541static const size_t test_lengths[2] =
542{
543 64U,
544 375U
545};
546
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200547#define ASSERT( cond, args ) \
548 do \
549 { \
550 if( ! ( cond ) ) \
551 { \
552 if( verbose != 0 ) \
553 mbedtls_printf args; \
554 \
555 return( -1 ); \
556 } \
557 } \
558 while( 0 )
559
Daniel King34b822c2016-05-15 17:28:08 -0300560int mbedtls_chacha20_self_test( int verbose )
561{
562 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200563 unsigned i;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200564 int ret;
Daniel King34b822c2016-05-15 17:28:08 -0300565
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200566 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300567 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200568 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200569 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300570
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200571 ret = mbedtls_chacha20_crypt( test_keys[i],
572 test_nonces[i],
573 test_counters[i],
574 test_lengths[i],
575 test_input[i],
576 output );
Daniel King34b822c2016-05-15 17:28:08 -0300577
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200578 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300579
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200580 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
581 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300582
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200583 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300584 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300585 }
586
587 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300588 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300589
590 return( 0 );
591}
592
593#endif /* MBEDTLS_SELF_TEST */
594
595#endif /* !MBEDTLS_CHACHA20_C */