blob: 28751043ab43f44d3dd30000d579234f1228971f [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úti1e148272020-08-07 13:07:28 +02008 * Copyright The Mbed TLS Contributors
Daniel King34b822c2016-05-15 17:28:08 -03009 * 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.
Daniel King34b822c2016-05-15 17:28:08 -030022 */
Daniel King34b822c2016-05-15 17:28:08 -030023
Gilles Peskinedb09ef62020-06-03 01:43:33 +020024#include "common.h"
Daniel King34b822c2016-05-15 17:28:08 -030025
26#if defined(MBEDTLS_CHACHA20_C)
27
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020028#include "mbedtls/chacha20.h"
29#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000030#include "mbedtls/error.h"
Daniel King34b822c2016-05-15 17:28:08 -030031
32#include <stddef.h>
33#include <string.h>
34
Daniel King34b822c2016-05-15 17:28:08 -030035#include "mbedtls/platform.h"
Daniel King34b822c2016-05-15 17:28:08 -030036
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020037#if !defined(MBEDTLS_CHACHA20_ALT)
38
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020039#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
40 !defined(inline) && !defined(__cplusplus)
41#define inline __inline
42#endif
43
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020044#define ROTL32( value, amount ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010045 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030046
47#define CHACHA20_CTR_INDEX ( 12U )
48
49#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
50
Daniel King34b822c2016-05-15 17:28:08 -030051/**
52 * \brief ChaCha20 quarter round operation.
53 *
54 * The quarter round is defined as follows (from RFC 7539):
55 * 1. a += b; d ^= a; d <<<= 16;
56 * 2. c += d; b ^= c; b <<<= 12;
57 * 3. a += b; d ^= a; d <<<= 8;
58 * 4. c += d; b ^= c; b <<<= 7;
59 *
60 * \param state ChaCha20 state to modify.
61 * \param a The index of 'a' in the state.
62 * \param b The index of 'b' in the state.
63 * \param c The index of 'c' in the state.
64 * \param d The index of 'd' in the state.
65 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020066static inline void chacha20_quarter_round( uint32_t state[16],
67 size_t a,
68 size_t b,
69 size_t c,
70 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -030071{
72 /* a += b; d ^= a; d <<<= 16; */
73 state[a] += state[b];
74 state[d] ^= state[a];
75 state[d] = ROTL32( state[d], 16 );
76
77 /* c += d; b ^= c; b <<<= 12 */
78 state[c] += state[d];
79 state[b] ^= state[c];
80 state[b] = ROTL32( state[b], 12 );
81
82 /* a += b; d ^= a; d <<<= 8; */
83 state[a] += state[b];
84 state[d] ^= state[a];
85 state[d] = ROTL32( state[d], 8 );
86
87 /* c += d; b ^= c; b <<<= 7; */
88 state[c] += state[d];
89 state[b] ^= state[c];
90 state[b] = ROTL32( state[b], 7 );
91}
92
93/**
94 * \brief Perform the ChaCha20 inner block operation.
95 *
96 * This function performs two rounds: the column round and the
97 * diagonal round.
98 *
99 * \param state The ChaCha20 state to update.
100 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200101static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300102{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200103 chacha20_quarter_round( state, 0, 4, 8, 12 );
104 chacha20_quarter_round( state, 1, 5, 9, 13 );
105 chacha20_quarter_round( state, 2, 6, 10, 14 );
106 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300107
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200108 chacha20_quarter_round( state, 0, 5, 10, 15 );
109 chacha20_quarter_round( state, 1, 6, 11, 12 );
110 chacha20_quarter_round( state, 2, 7, 8, 13 );
111 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300112}
113
114/**
115 * \brief Generates a keystream block.
116 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200117 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300118 * \param keystream Generated keystream bytes are written to this buffer.
119 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200120static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200121 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300122{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200123 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300124 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300125
Daniel Kingb8025c52016-05-17 14:43:01 -0300126 memcpy( working_state,
127 initial_state,
128 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300129
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200130 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200131 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300132
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200133 working_state[ 0] += initial_state[ 0];
134 working_state[ 1] += initial_state[ 1];
135 working_state[ 2] += initial_state[ 2];
136 working_state[ 3] += initial_state[ 3];
137 working_state[ 4] += initial_state[ 4];
138 working_state[ 5] += initial_state[ 5];
139 working_state[ 6] += initial_state[ 6];
140 working_state[ 7] += initial_state[ 7];
141 working_state[ 8] += initial_state[ 8];
142 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300143 working_state[10] += initial_state[10];
144 working_state[11] += initial_state[11];
145 working_state[12] += initial_state[12];
146 working_state[13] += initial_state[13];
147 working_state[14] += initial_state[14];
148 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300149
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200150 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300151 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200152 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300153
Joe Subbianib6511b02021-07-16 15:02:55 +0100154 MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
Daniel King34b822c2016-05-15 17:28:08 -0300155 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200156
157 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300158}
159
160void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
161{
Hanno Becker305e4e42018-12-11 15:03:16 +0000162 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
163 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
164
165 /* Initially, there's no keystream bytes available */
166 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300167}
168
169void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
170{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200171 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300172 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200173 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300174 }
175}
176
177int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
178 const unsigned char key[32] )
179{
Daniel King34b822c2016-05-15 17:28:08 -0300180 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200181 ctx->state[0] = 0x61707865;
182 ctx->state[1] = 0x3320646e;
183 ctx->state[2] = 0x79622d32;
184 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300185
186 /* Set key */
Joe Subbiani6a506312021-07-07 16:56:29 +0100187 ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
188 ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
189 ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
190 ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
191 ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
192 ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
193 ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
194 ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300195
196 return( 0 );
197}
198
199int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
200 const unsigned char nonce[12],
201 uint32_t counter )
202{
Daniel King34b822c2016-05-15 17:28:08 -0300203 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200204 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300205
206 /* Nonce */
Joe Subbiani6a506312021-07-07 16:56:29 +0100207 ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
208 ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
209 ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300210
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200211 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200212
213 /* Initially, there's no keystream bytes available */
214 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
215
Daniel King34b822c2016-05-15 17:28:08 -0300216 return( 0 );
217}
218
Daniel Kingbd920622016-05-15 19:56:20 -0300219int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300220 size_t size,
221 const unsigned char *input,
222 unsigned char *output )
223{
224 size_t offset = 0U;
Daniel King34b822c2016-05-15 17:28:08 -0300225
Daniel King34b822c2016-05-15 17:28:08 -0300226 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200227 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300228 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200229 output[offset] = input[offset]
230 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300231
232 ctx->keystream_bytes_used++;
233 offset++;
234 size--;
235 }
236
237 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200238 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300239 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200240 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200241 chacha20_block( ctx->state, ctx->keystream8 );
242 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300243
Dave Rodgmanc1d90222022-11-22 16:35:42 +0000244 mbedtls_xor( output + offset, input + offset, ctx->keystream8, 64U );
Daniel King34b822c2016-05-15 17:28:08 -0300245
Daniel Kingb8025c52016-05-17 14:43:01 -0300246 offset += CHACHA20_BLOCK_SIZE_BYTES;
247 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300248 }
249
250 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200251 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300252 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200253 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200254 chacha20_block( ctx->state, ctx->keystream8 );
255 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300256
Dave Rodgmanc1d90222022-11-22 16:35:42 +0000257 mbedtls_xor( output + offset, input + offset, ctx->keystream8, size );
Daniel King34b822c2016-05-15 17:28:08 -0300258
259 ctx->keystream_bytes_used = size;
260
Daniel King34b822c2016-05-15 17:28:08 -0300261 }
262
Daniel Kinge6e79682016-05-24 11:16:17 -0300263 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300264}
265
Daniel King34b822c2016-05-15 17:28:08 -0300266int mbedtls_chacha20_crypt( const unsigned char key[32],
267 const unsigned char nonce[12],
268 uint32_t counter,
269 size_t data_len,
270 const unsigned char* input,
271 unsigned char* output )
272{
273 mbedtls_chacha20_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000274 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300275
276 mbedtls_chacha20_init( &ctx );
277
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200278 ret = mbedtls_chacha20_setkey( &ctx, key );
279 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300280 goto cleanup;
281
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200282 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
283 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300284 goto cleanup;
285
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200286 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300287
288cleanup:
289 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200290 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300291}
292
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200293#endif /* !MBEDTLS_CHACHA20_ALT */
294
Daniel King34b822c2016-05-15 17:28:08 -0300295#if defined(MBEDTLS_SELF_TEST)
296
297static const unsigned char test_keys[2][32] =
298{
299 {
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
304 },
305 {
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
310 }
311};
312
313static const unsigned char test_nonces[2][12] =
314{
315 {
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00
318 },
319 {
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x02
322 }
323};
324
325static const uint32_t test_counters[2] =
326{
327 0U,
328 1U
329};
330
331static const unsigned char test_input[2][375] =
332{
333 {
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
342 },
343 {
344 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
345 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
346 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
347 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
348 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
349 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
350 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
351 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
352 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
353 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
354 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
355 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
356 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
357 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
358 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
359 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
360 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
361 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
362 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
363 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
364 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
365 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
366 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
367 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
368 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
369 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
370 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
371 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
372 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
373 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
374 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
375 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
376 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
377 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
378 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
379 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
380 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
381 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
382 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
383 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
384 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
385 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
386 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
387 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
388 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
389 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
390 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
391 }
392};
393
394static const unsigned char test_output[2][375] =
395{
396 {
397 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
398 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
399 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
400 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
401 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
402 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
403 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
404 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
405 },
406 {
407 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
408 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
409 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
410 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
411 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
412 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
413 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
414 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
415 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
416 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
417 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
418 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
419 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
420 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
421 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
422 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
423 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
424 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
425 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
426 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
427 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
428 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
429 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
430 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
431 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
432 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
433 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
434 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
435 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
436 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
437 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
438 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
439 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
440 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
441 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
442 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
443 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
444 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
445 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
446 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
447 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
448 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
449 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
450 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
451 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
452 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
453 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
454 }
455};
456
457static const size_t test_lengths[2] =
458{
459 64U,
460 375U
461};
462
Ouss4e0b26872020-08-11 16:07:09 +0100463/* Make sure no other definition is already present. */
464#undef ASSERT
465
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200466#define ASSERT( cond, args ) \
467 do \
468 { \
469 if( ! ( cond ) ) \
470 { \
471 if( verbose != 0 ) \
472 mbedtls_printf args; \
473 \
474 return( -1 ); \
475 } \
476 } \
477 while( 0 )
478
Daniel King34b822c2016-05-15 17:28:08 -0300479int mbedtls_chacha20_self_test( int verbose )
480{
481 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200482 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000483 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300484
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200485 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300486 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200487 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200488 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300489
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200490 ret = mbedtls_chacha20_crypt( test_keys[i],
491 test_nonces[i],
492 test_counters[i],
493 test_lengths[i],
494 test_input[i],
495 output );
Daniel King34b822c2016-05-15 17:28:08 -0300496
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200497 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300498
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200499 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
500 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300501
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200502 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300503 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300504 }
505
506 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300507 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300508
509 return( 0 );
510}
511
512#endif /* MBEDTLS_SELF_TEST */
513
514#endif /* !MBEDTLS_CHACHA20_C */