blob: f6d6e252230bf7597c606c91b14a83c6633552d1 [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
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020051#define ROTL32( value, amount ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010052 ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
Daniel King34b822c2016-05-15 17:28:08 -030053
54#define CHACHA20_CTR_INDEX ( 12U )
55
56#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
57
Daniel King34b822c2016-05-15 17:28:08 -030058/**
59 * \brief ChaCha20 quarter round operation.
60 *
61 * The quarter round is defined as follows (from RFC 7539):
62 * 1. a += b; d ^= a; d <<<= 16;
63 * 2. c += d; b ^= c; b <<<= 12;
64 * 3. a += b; d ^= a; d <<<= 8;
65 * 4. c += d; b ^= c; b <<<= 7;
66 *
67 * \param state ChaCha20 state to modify.
68 * \param a The index of 'a' in the state.
69 * \param b The index of 'b' in the state.
70 * \param c The index of 'c' in the state.
71 * \param d The index of 'd' in the state.
72 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020073static inline void chacha20_quarter_round( uint32_t state[16],
74 size_t a,
75 size_t b,
76 size_t c,
77 size_t d )
Daniel King34b822c2016-05-15 17:28:08 -030078{
79 /* a += b; d ^= a; d <<<= 16; */
80 state[a] += state[b];
81 state[d] ^= state[a];
82 state[d] = ROTL32( state[d], 16 );
83
84 /* c += d; b ^= c; b <<<= 12 */
85 state[c] += state[d];
86 state[b] ^= state[c];
87 state[b] = ROTL32( state[b], 12 );
88
89 /* a += b; d ^= a; d <<<= 8; */
90 state[a] += state[b];
91 state[d] ^= state[a];
92 state[d] = ROTL32( state[d], 8 );
93
94 /* c += d; b ^= c; b <<<= 7; */
95 state[c] += state[d];
96 state[b] ^= state[c];
97 state[b] = ROTL32( state[b], 7 );
98}
99
100/**
101 * \brief Perform the ChaCha20 inner block operation.
102 *
103 * This function performs two rounds: the column round and the
104 * diagonal round.
105 *
106 * \param state The ChaCha20 state to update.
107 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200108static void chacha20_inner_block( uint32_t state[16] )
Daniel King34b822c2016-05-15 17:28:08 -0300109{
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200110 chacha20_quarter_round( state, 0, 4, 8, 12 );
111 chacha20_quarter_round( state, 1, 5, 9, 13 );
112 chacha20_quarter_round( state, 2, 6, 10, 14 );
113 chacha20_quarter_round( state, 3, 7, 11, 15 );
Daniel King34b822c2016-05-15 17:28:08 -0300114
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200115 chacha20_quarter_round( state, 0, 5, 10, 15 );
116 chacha20_quarter_round( state, 1, 6, 11, 12 );
117 chacha20_quarter_round( state, 2, 7, 8, 13 );
118 chacha20_quarter_round( state, 3, 4, 9, 14 );
Daniel King34b822c2016-05-15 17:28:08 -0300119}
120
121/**
122 * \brief Generates a keystream block.
123 *
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200124 * \param initial_state The initial ChaCha20 state (key, nonce, counter).
Daniel King34b822c2016-05-15 17:28:08 -0300125 * \param keystream Generated keystream bytes are written to this buffer.
126 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200127static void chacha20_block( const uint32_t initial_state[16],
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200128 unsigned char keystream[64] )
Daniel King34b822c2016-05-15 17:28:08 -0300129{
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200130 uint32_t working_state[16];
Daniel King34b822c2016-05-15 17:28:08 -0300131 size_t i;
Daniel King34b822c2016-05-15 17:28:08 -0300132
Daniel Kingb8025c52016-05-17 14:43:01 -0300133 memcpy( working_state,
134 initial_state,
135 CHACHA20_BLOCK_SIZE_BYTES );
Daniel King34b822c2016-05-15 17:28:08 -0300136
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200137 for( i = 0U; i < 10U; i++ )
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200138 chacha20_inner_block( working_state );
Daniel King34b822c2016-05-15 17:28:08 -0300139
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200140 working_state[ 0] += initial_state[ 0];
141 working_state[ 1] += initial_state[ 1];
142 working_state[ 2] += initial_state[ 2];
143 working_state[ 3] += initial_state[ 3];
144 working_state[ 4] += initial_state[ 4];
145 working_state[ 5] += initial_state[ 5];
146 working_state[ 6] += initial_state[ 6];
147 working_state[ 7] += initial_state[ 7];
148 working_state[ 8] += initial_state[ 8];
149 working_state[ 9] += initial_state[ 9];
Daniel Kingb8025c52016-05-17 14:43:01 -0300150 working_state[10] += initial_state[10];
151 working_state[11] += initial_state[11];
152 working_state[12] += initial_state[12];
153 working_state[13] += initial_state[13];
154 working_state[14] += initial_state[14];
155 working_state[15] += initial_state[15];
Daniel King34b822c2016-05-15 17:28:08 -0300156
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200157 for( i = 0U; i < 16; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300158 {
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200159 size_t offset = i * 4U;
Daniel King34b822c2016-05-15 17:28:08 -0300160
Joe Subbianib6511b02021-07-16 15:02:55 +0100161 MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
Daniel King34b822c2016-05-15 17:28:08 -0300162 }
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200163
164 mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
Daniel King34b822c2016-05-15 17:28:08 -0300165}
166
167void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
168{
Hanno Becker305e4e42018-12-11 15:03:16 +0000169 mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
170 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
171
172 /* Initially, there's no keystream bytes available */
173 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300174}
175
176void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
177{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200178 if( ctx != NULL )
Daniel King34b822c2016-05-15 17:28:08 -0300179 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200180 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
Daniel King34b822c2016-05-15 17:28:08 -0300181 }
182}
183
184int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
185 const unsigned char key[32] )
186{
Daniel King34b822c2016-05-15 17:28:08 -0300187 /* ChaCha20 constants - the string "expand 32-byte k" */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200188 ctx->state[0] = 0x61707865;
189 ctx->state[1] = 0x3320646e;
190 ctx->state[2] = 0x79622d32;
191 ctx->state[3] = 0x6b206574;
Daniel King34b822c2016-05-15 17:28:08 -0300192
193 /* Set key */
Joe Subbiani6a506312021-07-07 16:56:29 +0100194 ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
195 ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
196 ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
197 ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
198 ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
199 ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
200 ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
201 ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel King34b822c2016-05-15 17:28:08 -0300202
203 return( 0 );
204}
205
206int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
207 const unsigned char nonce[12],
208 uint32_t counter )
209{
Daniel King34b822c2016-05-15 17:28:08 -0300210 /* Counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200211 ctx->state[12] = counter;
Daniel King34b822c2016-05-15 17:28:08 -0300212
213 /* Nonce */
Joe Subbiani6a506312021-07-07 16:56:29 +0100214 ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
215 ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
216 ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
Daniel King34b822c2016-05-15 17:28:08 -0300217
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200218 mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
Manuel Pégourié-Gonnard55c0d092018-05-09 12:37:58 +0200219
220 /* Initially, there's no keystream bytes available */
221 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
222
Daniel King34b822c2016-05-15 17:28:08 -0300223 return( 0 );
224}
225
Daniel Kingbd920622016-05-15 19:56:20 -0300226int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
Daniel King34b822c2016-05-15 17:28:08 -0300227 size_t size,
228 const unsigned char *input,
229 unsigned char *output )
230{
231 size_t offset = 0U;
232 size_t i;
233
Daniel King34b822c2016-05-15 17:28:08 -0300234 /* Use leftover keystream bytes, if available */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200235 while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300236 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200237 output[offset] = input[offset]
238 ^ ctx->keystream8[ctx->keystream_bytes_used];
Daniel King34b822c2016-05-15 17:28:08 -0300239
240 ctx->keystream_bytes_used++;
241 offset++;
242 size--;
243 }
244
245 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200246 while( size >= CHACHA20_BLOCK_SIZE_BYTES )
Daniel King34b822c2016-05-15 17:28:08 -0300247 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200248 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200249 chacha20_block( ctx->state, ctx->keystream8 );
250 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300251
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200252 for( i = 0U; i < 64U; i += 8U )
Daniel King34b822c2016-05-15 17:28:08 -0300253 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200254 output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
255 output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
256 output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
257 output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
258 output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
259 output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
260 output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
261 output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
Daniel King34b822c2016-05-15 17:28:08 -0300262 }
263
Daniel Kingb8025c52016-05-17 14:43:01 -0300264 offset += CHACHA20_BLOCK_SIZE_BYTES;
265 size -= CHACHA20_BLOCK_SIZE_BYTES;
Daniel King34b822c2016-05-15 17:28:08 -0300266 }
267
268 /* Last (partial) block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200269 if( size > 0U )
Daniel King34b822c2016-05-15 17:28:08 -0300270 {
Manuel Pégourié-Gonnard502f1892018-05-07 11:57:05 +0200271 /* Generate new keystream block and increment counter */
Manuel Pégourié-Gonnard98fae6d2018-05-24 17:23:41 +0200272 chacha20_block( ctx->state, ctx->keystream8 );
273 ctx->state[CHACHA20_CTR_INDEX]++;
Daniel King34b822c2016-05-15 17:28:08 -0300274
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200275 for( i = 0U; i < size; i++)
Daniel King34b822c2016-05-15 17:28:08 -0300276 {
277 output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
278 }
279
280 ctx->keystream_bytes_used = size;
281
Daniel King34b822c2016-05-15 17:28:08 -0300282 }
283
Daniel Kinge6e79682016-05-24 11:16:17 -0300284 return( 0 );
Daniel King34b822c2016-05-15 17:28:08 -0300285}
286
Daniel King34b822c2016-05-15 17:28:08 -0300287int mbedtls_chacha20_crypt( const unsigned char key[32],
288 const unsigned char nonce[12],
289 uint32_t counter,
290 size_t data_len,
291 const unsigned char* input,
292 unsigned char* output )
293{
294 mbedtls_chacha20_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000295 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300296
297 mbedtls_chacha20_init( &ctx );
298
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200299 ret = mbedtls_chacha20_setkey( &ctx, key );
300 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300301 goto cleanup;
302
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200303 ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
304 if( ret != 0 )
Daniel King34b822c2016-05-15 17:28:08 -0300305 goto cleanup;
306
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200307 ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
Daniel King34b822c2016-05-15 17:28:08 -0300308
309cleanup:
310 mbedtls_chacha20_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200311 return( ret );
Daniel King34b822c2016-05-15 17:28:08 -0300312}
313
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200314#endif /* !MBEDTLS_CHACHA20_ALT */
315
Daniel King34b822c2016-05-15 17:28:08 -0300316#if defined(MBEDTLS_SELF_TEST)
317
318static const unsigned char test_keys[2][32] =
319{
320 {
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
325 },
326 {
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
331 }
332};
333
334static const unsigned char test_nonces[2][12] =
335{
336 {
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00
339 },
340 {
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x02
343 }
344};
345
346static const uint32_t test_counters[2] =
347{
348 0U,
349 1U
350};
351
352static const unsigned char test_input[2][375] =
353{
354 {
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
363 },
364 {
365 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
366 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
367 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
368 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
369 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
370 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
371 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
372 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
373 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
374 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
375 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
376 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
377 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
378 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
379 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
380 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
381 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
382 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
383 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
384 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
385 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
386 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
387 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
388 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
389 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
390 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
391 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
392 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
393 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
394 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
395 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
396 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
397 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
398 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
399 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
400 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
401 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
402 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
403 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
404 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
405 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
406 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
407 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
408 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
409 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
410 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
411 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
412 }
413};
414
415static const unsigned char test_output[2][375] =
416{
417 {
418 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
419 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
420 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
421 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
422 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
423 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
424 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
425 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
426 },
427 {
428 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
429 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
430 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
431 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
432 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
433 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
434 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
435 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
436 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
437 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
438 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
439 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
440 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
441 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
442 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
443 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
444 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
445 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
446 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
447 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
448 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
449 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
450 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
451 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
452 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
453 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
454 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
455 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
456 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
457 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
458 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
459 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
460 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
461 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
462 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
463 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
464 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
465 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
466 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
467 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
468 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
469 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
470 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
471 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
472 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
473 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
474 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
475 }
476};
477
478static const size_t test_lengths[2] =
479{
480 64U,
481 375U
482};
483
Ouss4e0b26872020-08-11 16:07:09 +0100484/* Make sure no other definition is already present. */
485#undef ASSERT
486
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200487#define ASSERT( cond, args ) \
488 do \
489 { \
490 if( ! ( cond ) ) \
491 { \
492 if( verbose != 0 ) \
493 mbedtls_printf args; \
494 \
495 return( -1 ); \
496 } \
497 } \
498 while( 0 )
499
Daniel King34b822c2016-05-15 17:28:08 -0300500int mbedtls_chacha20_self_test( int verbose )
501{
502 unsigned char output[381];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200503 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel King34b822c2016-05-15 17:28:08 -0300505
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200506 for( i = 0U; i < 2U; i++ )
Daniel King34b822c2016-05-15 17:28:08 -0300507 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200508 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200509 mbedtls_printf( " ChaCha20 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300510
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200511 ret = mbedtls_chacha20_crypt( test_keys[i],
512 test_nonces[i],
513 test_counters[i],
514 test_lengths[i],
515 test_input[i],
516 output );
Daniel King34b822c2016-05-15 17:28:08 -0300517
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200518 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel King34b822c2016-05-15 17:28:08 -0300519
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200520 ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
521 ( "failed (output)\n" ) );
Daniel King34b822c2016-05-15 17:28:08 -0300522
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200523 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300524 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300525 }
526
527 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300528 mbedtls_printf( "\n" );
Daniel King34b822c2016-05-15 17:28:08 -0300529
530 return( 0 );
531}
532
533#endif /* MBEDTLS_SELF_TEST */
534
535#endif /* !MBEDTLS_CHACHA20_C */