blob: 0e057f0e3c75bb7073aa4e2d95c9560bac9506cc [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
35#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#else
39#include <stdio.h>
40#define mbedtls_printf printf
41#endif /* MBEDTLS_PLATFORM_C */
42#endif /* MBEDTLS_SELF_TEST */
43
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020044#if !defined(MBEDTLS_CHACHA20_ALT)
45
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020046#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
47 !defined(inline) && !defined(__cplusplus)
48#define inline __inline
49#endif
50
Hanno Becker305e4e42018-12-11 15:03:16 +000051/* Parameter validation macros */
52#define CHACHA20_VALIDATE_RET( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
54#define CHACHA20_VALIDATE( cond ) \
55 MBEDTLS_INTERNAL_VALIDATE( cond )
56
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020057#define ROTL32( value, amount ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010058 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030059
60#define CHACHA20_CTR_INDEX ( 12U )
61
62#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
63
Daniel King34b822c2016-05-15 17:28:08 -030064/**
65 * \brief ChaCha20 quarter round operation.
66 *
67 * The quarter round is defined as follows (from RFC 7539):
68 * 1. a += b; d ^= a; d <<<= 16;
69 * 2. c += d; b ^= c; b <<<= 12;
70 * 3. a += b; d ^= a; d <<<= 8;
71 * 4. c += d; b ^= c; b <<<= 7;
72 *
73 * \param state ChaCha20 state to modify.
74 * \param a The index of 'a' in the state.
75 * \param b The index of 'b' in the state.
76 * \param c The index of 'c' in the state.
77 * \param d The index of 'd' in the state.
78 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020079static inline void chacha20_quarter_round( uint32_t state[16],
80 size_t a,
81 size_t b,
82 size_t c,
83 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -030084{
85 /* a += b; d ^= a; d <<<= 16; */
86 state[a] += state[b];
87 state[d] ^= state[a];
88 state[d] = ROTL32( state[d], 16 );
89
90 /* c += d; b ^= c; b <<<= 12 */
91 state[c] += state[d];
92 state[b] ^= state[c];
93 state[b] = ROTL32( state[b], 12 );
94
95 /* a += b; d ^= a; d <<<= 8; */
96 state[a] += state[b];
97 state[d] ^= state[a];
98 state[d] = ROTL32( state[d], 8 );
99
100 /* c += d; b ^= c; b <<<= 7; */
101 state[c] += state[d];
102 state[b] ^= state[c];
103 state[b] = ROTL32( state[b], 7 );
104}
105
106/**
107 * \brief Perform the ChaCha20 inner block operation.
108 *
109 * This function performs two rounds: the column round and the
110 * diagonal round.
111 *
112 * \param state The ChaCha20 state to update.
113 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200114static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300115{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200116 chacha20_quarter_round( state, 0, 4, 8, 12 );
117 chacha20_quarter_round( state, 1, 5, 9, 13 );
118 chacha20_quarter_round( state, 2, 6, 10, 14 );
119 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300120
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200121 chacha20_quarter_round( state, 0, 5, 10, 15 );
122 chacha20_quarter_round( state, 1, 6, 11, 12 );
123 chacha20_quarter_round( state, 2, 7, 8, 13 );
124 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300125}
126
127/**
128 * \brief Generates a keystream block.
129 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200130 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300131 * \param keystream Generated keystream bytes are written to this buffer.
132 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200133static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200134 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300135{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200136 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300137 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300138
Daniel Kingb8025c52016-05-17 14:43:01 -0300139 memcpy( working_state,
140 initial_state,
141 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300142
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200143 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200144 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300145
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200146 working_state[ 0] += initial_state[ 0];
147 working_state[ 1] += initial_state[ 1];
148 working_state[ 2] += initial_state[ 2];
149 working_state[ 3] += initial_state[ 3];
150 working_state[ 4] += initial_state[ 4];
151 working_state[ 5] += initial_state[ 5];
152 working_state[ 6] += initial_state[ 6];
153 working_state[ 7] += initial_state[ 7];
154 working_state[ 8] += initial_state[ 8];
155 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300156 working_state[10] += initial_state[10];
157 working_state[11] += initial_state[11];
158 working_state[12] += initial_state[12];
159 working_state[13] += initial_state[13];
160 working_state[14] += initial_state[14];
161 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300162
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200163 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300164 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200165 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300166
Joe Subbianifbeb6922021-07-16 14:27:50 +0100167 keystream[offset ] = MBEDTLS_BYTE_0( working_state[i] );
168 keystream[offset + 1U] = MBEDTLS_BYTE_1( working_state[i] );
169 keystream[offset + 2U] = MBEDTLS_BYTE_2( working_state[i] );
170 keystream[offset + 3U] = MBEDTLS_BYTE_3( working_state[i] );
Daniel King34b822c2016-05-15 17:28:08 -0300171 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200172
173 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300174}
175
176void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
177{
Hanno Becker305e4e42018-12-11 15:03:16 +0000178 CHACHA20_VALIDATE( ctx != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300179
Hanno Becker305e4e42018-12-11 15:03:16 +0000180 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
181 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
182
183 /* Initially, there's no keystream bytes available */
184 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300185}
186
187void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
188{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200189 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300190 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200191 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300192 }
193}
194
195int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
196 const unsigned char key[32] )
197{
Hanno Becker305e4e42018-12-11 15:03:16 +0000198 CHACHA20_VALIDATE_RET( ctx != NULL );
199 CHACHA20_VALIDATE_RET( key != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300200
201 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200202 ctx->state[0] = 0x61707865;
203 ctx->state[1] = 0x3320646e;
204 ctx->state[2] = 0x79622d32;
205 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300206
207 /* Set key */
Joe Subbiani6a506312021-07-07 16:56:29 +0100208 ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
209 ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
210 ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
211 ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
212 ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
213 ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
214 ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
215 ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300216
217 return( 0 );
218}
219
220int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
221 const unsigned char nonce[12],
222 uint32_t counter )
223{
Hanno Becker305e4e42018-12-11 15:03:16 +0000224 CHACHA20_VALIDATE_RET( ctx != NULL );
225 CHACHA20_VALIDATE_RET( nonce != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300226
227 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200228 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300229
230 /* Nonce */
Joe Subbiani6a506312021-07-07 16:56:29 +0100231 ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
232 ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
233 ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300234
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200235 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200236
237 /* Initially, there's no keystream bytes available */
238 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
239
Daniel King34b822c2016-05-15 17:28:08 -0300240 return( 0 );
241}
242
Daniel Kingbd920622016-05-15 19:56:20 -0300243int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300244 size_t size,
245 const unsigned char *input,
246 unsigned char *output )
247{
248 size_t offset = 0U;
249 size_t i;
250
Hanno Becker305e4e42018-12-11 15:03:16 +0000251 CHACHA20_VALIDATE_RET( ctx != NULL );
252 CHACHA20_VALIDATE_RET( size == 0 || input != NULL );
253 CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
Daniel King34b822c2016-05-15 17:28:08 -0300254
255 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200256 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300257 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200258 output[offset] = input[offset]
259 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300260
261 ctx->keystream_bytes_used++;
262 offset++;
263 size--;
264 }
265
266 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200267 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300268 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200269 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200270 chacha20_block( ctx->state, ctx->keystream8 );
271 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300272
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200273 for( i = 0U; i < 64U; i += 8U )
Daniel King34b822c2016-05-15 17:28:08 -0300274 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200275 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
276 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
277 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
278 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
279 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
280 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
281 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
282 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
Daniel King34b822c2016-05-15 17:28:08 -0300283 }
284
Daniel Kingb8025c52016-05-17 14:43:01 -0300285 offset += CHACHA20_BLOCK_SIZE_BYTES;
286 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300287 }
288
289 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200290 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300291 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200292 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200293 chacha20_block( ctx->state, ctx->keystream8 );
294 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300295
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200296 for( i = 0U; i < size; i++)
Daniel King34b822c2016-05-15 17:28:08 -0300297 {
298 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
299 }
300
301 ctx->keystream_bytes_used = size;
302
Daniel King34b822c2016-05-15 17:28:08 -0300303 }
304
Daniel Kinge6e79682016-05-24 11:16:17 -0300305 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300306}
307
Daniel King34b822c2016-05-15 17:28:08 -0300308int mbedtls_chacha20_crypt( const unsigned char key[32],
309 const unsigned char nonce[12],
310 uint32_t counter,
311 size_t data_len,
312 const unsigned char* input,
313 unsigned char* output )
314{
315 mbedtls_chacha20_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000316 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300317
Hanno Becker305e4e42018-12-11 15:03:16 +0000318 CHACHA20_VALIDATE_RET( key != NULL );
319 CHACHA20_VALIDATE_RET( nonce != NULL );
320 CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL );
321 CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
322
Daniel King34b822c2016-05-15 17:28:08 -0300323 mbedtls_chacha20_init( &ctx );
324
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200325 ret = mbedtls_chacha20_setkey( &ctx, key );
326 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300327 goto cleanup;
328
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200329 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
330 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300331 goto cleanup;
332
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200333 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300334
335cleanup:
336 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200337 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300338}
339
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200340#endif /* !MBEDTLS_CHACHA20_ALT */
341
Daniel King34b822c2016-05-15 17:28:08 -0300342#if defined(MBEDTLS_SELF_TEST)
343
344static const unsigned char test_keys[2][32] =
345{
346 {
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
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, 0x01
357 }
358};
359
360static const unsigned char test_nonces[2][12] =
361{
362 {
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00
365 },
366 {
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x02
369 }
370};
371
372static const uint32_t test_counters[2] =
373{
374 0U,
375 1U
376};
377
378static const unsigned char test_input[2][375] =
379{
380 {
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
389 },
390 {
391 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
392 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
393 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
394 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
395 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
396 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
397 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
398 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
399 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
400 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
401 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
402 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
403 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
404 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
405 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
406 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
407 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
408 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
409 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
410 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
411 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
412 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
413 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
414 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
415 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
416 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
417 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
418 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
419 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
420 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
421 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
422 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
423 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
424 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
425 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
426 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
427 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
428 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
429 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
430 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
431 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
432 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
433 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
434 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
435 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
436 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
437 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
438 }
439};
440
441static const unsigned char test_output[2][375] =
442{
443 {
444 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
445 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
446 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
447 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
448 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
449 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
450 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
451 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
452 },
453 {
454 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
455 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
456 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
457 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
458 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
459 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
460 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
461 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
462 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
463 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
464 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
465 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
466 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
467 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
468 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
469 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
470 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
471 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
472 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
473 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
474 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
475 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
476 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
477 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
478 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
479 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
480 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
481 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
482 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
483 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
484 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
485 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
486 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
487 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
488 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
489 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
490 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
491 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
492 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
493 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
494 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
495 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
496 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
497 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
498 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
499 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
500 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
501 }
502};
503
504static const size_t test_lengths[2] =
505{
506 64U,
507 375U
508};
509
Ouss4e0b26872020-08-11 16:07:09 +0100510/* Make sure no other definition is already present. */
511#undef ASSERT
512
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200513#define ASSERT( cond, args ) \
514 do \
515 { \
516 if( ! ( cond ) ) \
517 { \
518 if( verbose != 0 ) \
519 mbedtls_printf args; \
520 \
521 return( -1 ); \
522 } \
523 } \
524 while( 0 )
525
Daniel King34b822c2016-05-15 17:28:08 -0300526int mbedtls_chacha20_self_test( int verbose )
527{
528 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200529 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000530 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300531
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200532 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300533 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200534 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200535 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300536
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200537 ret = mbedtls_chacha20_crypt( test_keys[i],
538 test_nonces[i],
539 test_counters[i],
540 test_lengths[i],
541 test_input[i],
542 output );
Daniel King34b822c2016-05-15 17:28:08 -0300543
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200544 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300545
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200546 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
547 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300548
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200549 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300550 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300551 }
552
553 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300554 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300555
556 return( 0 );
557}
558
559#endif /* MBEDTLS_SELF_TEST */
560
561#endif /* !MBEDTLS_CHACHA20_C */