xref: /optee_os/lib/libmbedtls/mbedtls/library/chacha20.c (revision 3d3b05918ec9052ba13de82fbcaba204766eb636)
1*3d3b0591SJens Wiklander /*  SPDX-License-Identifier: Apache-2.0 */
2*3d3b0591SJens Wiklander /**
3*3d3b0591SJens Wiklander  * \file chacha20.c
4*3d3b0591SJens Wiklander  *
5*3d3b0591SJens Wiklander  * \brief ChaCha20 cipher.
6*3d3b0591SJens Wiklander  *
7*3d3b0591SJens Wiklander  * \author Daniel King <damaki.gh@gmail.com>
8*3d3b0591SJens Wiklander  *
9*3d3b0591SJens Wiklander  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
10*3d3b0591SJens Wiklander  *
11*3d3b0591SJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
12*3d3b0591SJens Wiklander  *  not use this file except in compliance with the License.
13*3d3b0591SJens Wiklander  *  You may obtain a copy of the License at
14*3d3b0591SJens Wiklander  *
15*3d3b0591SJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
16*3d3b0591SJens Wiklander  *
17*3d3b0591SJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
18*3d3b0591SJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19*3d3b0591SJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20*3d3b0591SJens Wiklander  *  See the License for the specific language governing permissions and
21*3d3b0591SJens Wiklander  *  limitations under the License.
22*3d3b0591SJens Wiklander  *
23*3d3b0591SJens Wiklander  *  This file is part of mbed TLS (https://tls.mbed.org)
24*3d3b0591SJens Wiklander  */
25*3d3b0591SJens Wiklander 
26*3d3b0591SJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE)
27*3d3b0591SJens Wiklander #include "mbedtls/config.h"
28*3d3b0591SJens Wiklander #else
29*3d3b0591SJens Wiklander #include MBEDTLS_CONFIG_FILE
30*3d3b0591SJens Wiklander #endif
31*3d3b0591SJens Wiklander 
32*3d3b0591SJens Wiklander #if defined(MBEDTLS_CHACHA20_C)
33*3d3b0591SJens Wiklander 
34*3d3b0591SJens Wiklander #include "mbedtls/chacha20.h"
35*3d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
36*3d3b0591SJens Wiklander 
37*3d3b0591SJens Wiklander #include <stddef.h>
38*3d3b0591SJens Wiklander #include <string.h>
39*3d3b0591SJens Wiklander 
40*3d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST)
41*3d3b0591SJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
42*3d3b0591SJens Wiklander #include "mbedtls/platform.h"
43*3d3b0591SJens Wiklander #else
44*3d3b0591SJens Wiklander #include <stdio.h>
45*3d3b0591SJens Wiklander #define mbedtls_printf printf
46*3d3b0591SJens Wiklander #endif /* MBEDTLS_PLATFORM_C */
47*3d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */
48*3d3b0591SJens Wiklander 
49*3d3b0591SJens Wiklander #if !defined(MBEDTLS_CHACHA20_ALT)
50*3d3b0591SJens Wiklander 
51*3d3b0591SJens Wiklander #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
52*3d3b0591SJens Wiklander     !defined(inline) && !defined(__cplusplus)
53*3d3b0591SJens Wiklander #define inline __inline
54*3d3b0591SJens Wiklander #endif
55*3d3b0591SJens Wiklander 
56*3d3b0591SJens Wiklander /* Parameter validation macros */
57*3d3b0591SJens Wiklander #define CHACHA20_VALIDATE_RET( cond )                                       \
58*3d3b0591SJens Wiklander     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
59*3d3b0591SJens Wiklander #define CHACHA20_VALIDATE( cond )                                           \
60*3d3b0591SJens Wiklander     MBEDTLS_INTERNAL_VALIDATE( cond )
61*3d3b0591SJens Wiklander 
62*3d3b0591SJens Wiklander #define BYTES_TO_U32_LE( data, offset )                           \
63*3d3b0591SJens Wiklander     ( (uint32_t) data[offset]                                     \
64*3d3b0591SJens Wiklander           | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 )   \
65*3d3b0591SJens Wiklander           | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 )  \
66*3d3b0591SJens Wiklander           | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 )  \
67*3d3b0591SJens Wiklander     )
68*3d3b0591SJens Wiklander 
69*3d3b0591SJens Wiklander #define ROTL32( value, amount ) \
70*3d3b0591SJens Wiklander         ( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) )
71*3d3b0591SJens Wiklander 
72*3d3b0591SJens Wiklander #define CHACHA20_CTR_INDEX ( 12U )
73*3d3b0591SJens Wiklander 
74*3d3b0591SJens Wiklander #define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
75*3d3b0591SJens Wiklander 
76*3d3b0591SJens Wiklander /**
77*3d3b0591SJens Wiklander  * \brief           ChaCha20 quarter round operation.
78*3d3b0591SJens Wiklander  *
79*3d3b0591SJens Wiklander  *                  The quarter round is defined as follows (from RFC 7539):
80*3d3b0591SJens Wiklander  *                      1.  a += b; d ^= a; d <<<= 16;
81*3d3b0591SJens Wiklander  *                      2.  c += d; b ^= c; b <<<= 12;
82*3d3b0591SJens Wiklander  *                      3.  a += b; d ^= a; d <<<= 8;
83*3d3b0591SJens Wiklander  *                      4.  c += d; b ^= c; b <<<= 7;
84*3d3b0591SJens Wiklander  *
85*3d3b0591SJens Wiklander  * \param state     ChaCha20 state to modify.
86*3d3b0591SJens Wiklander  * \param a         The index of 'a' in the state.
87*3d3b0591SJens Wiklander  * \param b         The index of 'b' in the state.
88*3d3b0591SJens Wiklander  * \param c         The index of 'c' in the state.
89*3d3b0591SJens Wiklander  * \param d         The index of 'd' in the state.
90*3d3b0591SJens Wiklander  */
91*3d3b0591SJens Wiklander static inline void chacha20_quarter_round( uint32_t state[16],
92*3d3b0591SJens Wiklander                                            size_t a,
93*3d3b0591SJens Wiklander                                            size_t b,
94*3d3b0591SJens Wiklander                                            size_t c,
95*3d3b0591SJens Wiklander                                            size_t d )
96*3d3b0591SJens Wiklander {
97*3d3b0591SJens Wiklander     /* a += b; d ^= a; d <<<= 16; */
98*3d3b0591SJens Wiklander     state[a] += state[b];
99*3d3b0591SJens Wiklander     state[d] ^= state[a];
100*3d3b0591SJens Wiklander     state[d] = ROTL32( state[d], 16 );
101*3d3b0591SJens Wiklander 
102*3d3b0591SJens Wiklander     /* c += d; b ^= c; b <<<= 12 */
103*3d3b0591SJens Wiklander     state[c] += state[d];
104*3d3b0591SJens Wiklander     state[b] ^= state[c];
105*3d3b0591SJens Wiklander     state[b] = ROTL32( state[b], 12 );
106*3d3b0591SJens Wiklander 
107*3d3b0591SJens Wiklander     /* a += b; d ^= a; d <<<= 8; */
108*3d3b0591SJens Wiklander     state[a] += state[b];
109*3d3b0591SJens Wiklander     state[d] ^= state[a];
110*3d3b0591SJens Wiklander     state[d] = ROTL32( state[d], 8 );
111*3d3b0591SJens Wiklander 
112*3d3b0591SJens Wiklander     /* c += d; b ^= c; b <<<= 7; */
113*3d3b0591SJens Wiklander     state[c] += state[d];
114*3d3b0591SJens Wiklander     state[b] ^= state[c];
115*3d3b0591SJens Wiklander     state[b] = ROTL32( state[b], 7 );
116*3d3b0591SJens Wiklander }
117*3d3b0591SJens Wiklander 
118*3d3b0591SJens Wiklander /**
119*3d3b0591SJens Wiklander  * \brief           Perform the ChaCha20 inner block operation.
120*3d3b0591SJens Wiklander  *
121*3d3b0591SJens Wiklander  *                  This function performs two rounds: the column round and the
122*3d3b0591SJens Wiklander  *                  diagonal round.
123*3d3b0591SJens Wiklander  *
124*3d3b0591SJens Wiklander  * \param state     The ChaCha20 state to update.
125*3d3b0591SJens Wiklander  */
126*3d3b0591SJens Wiklander static void chacha20_inner_block( uint32_t state[16] )
127*3d3b0591SJens Wiklander {
128*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 0, 4, 8,  12 );
129*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 1, 5, 9,  13 );
130*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 2, 6, 10, 14 );
131*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 3, 7, 11, 15 );
132*3d3b0591SJens Wiklander 
133*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 0, 5, 10, 15 );
134*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 1, 6, 11, 12 );
135*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 2, 7, 8,  13 );
136*3d3b0591SJens Wiklander     chacha20_quarter_round( state, 3, 4, 9,  14 );
137*3d3b0591SJens Wiklander }
138*3d3b0591SJens Wiklander 
139*3d3b0591SJens Wiklander /**
140*3d3b0591SJens Wiklander  * \brief               Generates a keystream block.
141*3d3b0591SJens Wiklander  *
142*3d3b0591SJens Wiklander  * \param initial_state The initial ChaCha20 state (key, nonce, counter).
143*3d3b0591SJens Wiklander  * \param keystream     Generated keystream bytes are written to this buffer.
144*3d3b0591SJens Wiklander  */
145*3d3b0591SJens Wiklander static void chacha20_block( const uint32_t initial_state[16],
146*3d3b0591SJens Wiklander                             unsigned char keystream[64] )
147*3d3b0591SJens Wiklander {
148*3d3b0591SJens Wiklander     uint32_t working_state[16];
149*3d3b0591SJens Wiklander     size_t i;
150*3d3b0591SJens Wiklander 
151*3d3b0591SJens Wiklander     memcpy( working_state,
152*3d3b0591SJens Wiklander             initial_state,
153*3d3b0591SJens Wiklander             CHACHA20_BLOCK_SIZE_BYTES );
154*3d3b0591SJens Wiklander 
155*3d3b0591SJens Wiklander     for( i = 0U; i < 10U; i++ )
156*3d3b0591SJens Wiklander         chacha20_inner_block( working_state );
157*3d3b0591SJens Wiklander 
158*3d3b0591SJens Wiklander     working_state[ 0] += initial_state[ 0];
159*3d3b0591SJens Wiklander     working_state[ 1] += initial_state[ 1];
160*3d3b0591SJens Wiklander     working_state[ 2] += initial_state[ 2];
161*3d3b0591SJens Wiklander     working_state[ 3] += initial_state[ 3];
162*3d3b0591SJens Wiklander     working_state[ 4] += initial_state[ 4];
163*3d3b0591SJens Wiklander     working_state[ 5] += initial_state[ 5];
164*3d3b0591SJens Wiklander     working_state[ 6] += initial_state[ 6];
165*3d3b0591SJens Wiklander     working_state[ 7] += initial_state[ 7];
166*3d3b0591SJens Wiklander     working_state[ 8] += initial_state[ 8];
167*3d3b0591SJens Wiklander     working_state[ 9] += initial_state[ 9];
168*3d3b0591SJens Wiklander     working_state[10] += initial_state[10];
169*3d3b0591SJens Wiklander     working_state[11] += initial_state[11];
170*3d3b0591SJens Wiklander     working_state[12] += initial_state[12];
171*3d3b0591SJens Wiklander     working_state[13] += initial_state[13];
172*3d3b0591SJens Wiklander     working_state[14] += initial_state[14];
173*3d3b0591SJens Wiklander     working_state[15] += initial_state[15];
174*3d3b0591SJens Wiklander 
175*3d3b0591SJens Wiklander     for( i = 0U; i < 16; i++ )
176*3d3b0591SJens Wiklander     {
177*3d3b0591SJens Wiklander         size_t offset = i * 4U;
178*3d3b0591SJens Wiklander 
179*3d3b0591SJens Wiklander         keystream[offset     ] = (unsigned char)( working_state[i]       );
180*3d3b0591SJens Wiklander         keystream[offset + 1U] = (unsigned char)( working_state[i] >>  8 );
181*3d3b0591SJens Wiklander         keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
182*3d3b0591SJens Wiklander         keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
183*3d3b0591SJens Wiklander     }
184*3d3b0591SJens Wiklander 
185*3d3b0591SJens Wiklander     mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
186*3d3b0591SJens Wiklander }
187*3d3b0591SJens Wiklander 
188*3d3b0591SJens Wiklander void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
189*3d3b0591SJens Wiklander {
190*3d3b0591SJens Wiklander     CHACHA20_VALIDATE( ctx != NULL );
191*3d3b0591SJens Wiklander 
192*3d3b0591SJens Wiklander     mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
193*3d3b0591SJens Wiklander     mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
194*3d3b0591SJens Wiklander 
195*3d3b0591SJens Wiklander     /* Initially, there's no keystream bytes available */
196*3d3b0591SJens Wiklander     ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
197*3d3b0591SJens Wiklander }
198*3d3b0591SJens Wiklander 
199*3d3b0591SJens Wiklander void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
200*3d3b0591SJens Wiklander {
201*3d3b0591SJens Wiklander     if( ctx != NULL )
202*3d3b0591SJens Wiklander     {
203*3d3b0591SJens Wiklander         mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
204*3d3b0591SJens Wiklander     }
205*3d3b0591SJens Wiklander }
206*3d3b0591SJens Wiklander 
207*3d3b0591SJens Wiklander int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
208*3d3b0591SJens Wiklander                             const unsigned char key[32] )
209*3d3b0591SJens Wiklander {
210*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( ctx != NULL );
211*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( key != NULL );
212*3d3b0591SJens Wiklander 
213*3d3b0591SJens Wiklander     /* ChaCha20 constants - the string "expand 32-byte k" */
214*3d3b0591SJens Wiklander     ctx->state[0] = 0x61707865;
215*3d3b0591SJens Wiklander     ctx->state[1] = 0x3320646e;
216*3d3b0591SJens Wiklander     ctx->state[2] = 0x79622d32;
217*3d3b0591SJens Wiklander     ctx->state[3] = 0x6b206574;
218*3d3b0591SJens Wiklander 
219*3d3b0591SJens Wiklander     /* Set key */
220*3d3b0591SJens Wiklander     ctx->state[4]  = BYTES_TO_U32_LE( key, 0 );
221*3d3b0591SJens Wiklander     ctx->state[5]  = BYTES_TO_U32_LE( key, 4 );
222*3d3b0591SJens Wiklander     ctx->state[6]  = BYTES_TO_U32_LE( key, 8 );
223*3d3b0591SJens Wiklander     ctx->state[7]  = BYTES_TO_U32_LE( key, 12 );
224*3d3b0591SJens Wiklander     ctx->state[8]  = BYTES_TO_U32_LE( key, 16 );
225*3d3b0591SJens Wiklander     ctx->state[9]  = BYTES_TO_U32_LE( key, 20 );
226*3d3b0591SJens Wiklander     ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
227*3d3b0591SJens Wiklander     ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
228*3d3b0591SJens Wiklander 
229*3d3b0591SJens Wiklander     return( 0 );
230*3d3b0591SJens Wiklander }
231*3d3b0591SJens Wiklander 
232*3d3b0591SJens Wiklander int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
233*3d3b0591SJens Wiklander                              const unsigned char nonce[12],
234*3d3b0591SJens Wiklander                              uint32_t counter )
235*3d3b0591SJens Wiklander {
236*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( ctx != NULL );
237*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( nonce != NULL );
238*3d3b0591SJens Wiklander 
239*3d3b0591SJens Wiklander     /* Counter */
240*3d3b0591SJens Wiklander     ctx->state[12] = counter;
241*3d3b0591SJens Wiklander 
242*3d3b0591SJens Wiklander     /* Nonce */
243*3d3b0591SJens Wiklander     ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
244*3d3b0591SJens Wiklander     ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
245*3d3b0591SJens Wiklander     ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
246*3d3b0591SJens Wiklander 
247*3d3b0591SJens Wiklander     mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
248*3d3b0591SJens Wiklander 
249*3d3b0591SJens Wiklander     /* Initially, there's no keystream bytes available */
250*3d3b0591SJens Wiklander     ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
251*3d3b0591SJens Wiklander 
252*3d3b0591SJens Wiklander     return( 0 );
253*3d3b0591SJens Wiklander }
254*3d3b0591SJens Wiklander 
255*3d3b0591SJens Wiklander int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
256*3d3b0591SJens Wiklander                               size_t size,
257*3d3b0591SJens Wiklander                               const unsigned char *input,
258*3d3b0591SJens Wiklander                               unsigned char *output )
259*3d3b0591SJens Wiklander {
260*3d3b0591SJens Wiklander     size_t offset = 0U;
261*3d3b0591SJens Wiklander     size_t i;
262*3d3b0591SJens Wiklander 
263*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( ctx != NULL );
264*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( size == 0 || input  != NULL );
265*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
266*3d3b0591SJens Wiklander 
267*3d3b0591SJens Wiklander     /* Use leftover keystream bytes, if available */
268*3d3b0591SJens Wiklander     while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
269*3d3b0591SJens Wiklander     {
270*3d3b0591SJens Wiklander         output[offset] = input[offset]
271*3d3b0591SJens Wiklander                        ^ ctx->keystream8[ctx->keystream_bytes_used];
272*3d3b0591SJens Wiklander 
273*3d3b0591SJens Wiklander         ctx->keystream_bytes_used++;
274*3d3b0591SJens Wiklander         offset++;
275*3d3b0591SJens Wiklander         size--;
276*3d3b0591SJens Wiklander     }
277*3d3b0591SJens Wiklander 
278*3d3b0591SJens Wiklander     /* Process full blocks */
279*3d3b0591SJens Wiklander     while( size >= CHACHA20_BLOCK_SIZE_BYTES )
280*3d3b0591SJens Wiklander     {
281*3d3b0591SJens Wiklander         /* Generate new keystream block and increment counter */
282*3d3b0591SJens Wiklander         chacha20_block( ctx->state, ctx->keystream8 );
283*3d3b0591SJens Wiklander         ctx->state[CHACHA20_CTR_INDEX]++;
284*3d3b0591SJens Wiklander 
285*3d3b0591SJens Wiklander         for( i = 0U; i < 64U; i += 8U )
286*3d3b0591SJens Wiklander         {
287*3d3b0591SJens Wiklander             output[offset + i  ] = input[offset + i  ] ^ ctx->keystream8[i  ];
288*3d3b0591SJens Wiklander             output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
289*3d3b0591SJens Wiklander             output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
290*3d3b0591SJens Wiklander             output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
291*3d3b0591SJens Wiklander             output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
292*3d3b0591SJens Wiklander             output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
293*3d3b0591SJens Wiklander             output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
294*3d3b0591SJens Wiklander             output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
295*3d3b0591SJens Wiklander         }
296*3d3b0591SJens Wiklander 
297*3d3b0591SJens Wiklander         offset += CHACHA20_BLOCK_SIZE_BYTES;
298*3d3b0591SJens Wiklander         size   -= CHACHA20_BLOCK_SIZE_BYTES;
299*3d3b0591SJens Wiklander     }
300*3d3b0591SJens Wiklander 
301*3d3b0591SJens Wiklander     /* Last (partial) block */
302*3d3b0591SJens Wiklander     if( size > 0U )
303*3d3b0591SJens Wiklander     {
304*3d3b0591SJens Wiklander         /* Generate new keystream block and increment counter */
305*3d3b0591SJens Wiklander         chacha20_block( ctx->state, ctx->keystream8 );
306*3d3b0591SJens Wiklander         ctx->state[CHACHA20_CTR_INDEX]++;
307*3d3b0591SJens Wiklander 
308*3d3b0591SJens Wiklander         for( i = 0U; i < size; i++)
309*3d3b0591SJens Wiklander         {
310*3d3b0591SJens Wiklander             output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
311*3d3b0591SJens Wiklander         }
312*3d3b0591SJens Wiklander 
313*3d3b0591SJens Wiklander         ctx->keystream_bytes_used = size;
314*3d3b0591SJens Wiklander 
315*3d3b0591SJens Wiklander     }
316*3d3b0591SJens Wiklander 
317*3d3b0591SJens Wiklander     return( 0 );
318*3d3b0591SJens Wiklander }
319*3d3b0591SJens Wiklander 
320*3d3b0591SJens Wiklander int mbedtls_chacha20_crypt( const unsigned char key[32],
321*3d3b0591SJens Wiklander                             const unsigned char nonce[12],
322*3d3b0591SJens Wiklander                             uint32_t counter,
323*3d3b0591SJens Wiklander                             size_t data_len,
324*3d3b0591SJens Wiklander                             const unsigned char* input,
325*3d3b0591SJens Wiklander                             unsigned char* output )
326*3d3b0591SJens Wiklander {
327*3d3b0591SJens Wiklander     mbedtls_chacha20_context ctx;
328*3d3b0591SJens Wiklander     int ret;
329*3d3b0591SJens Wiklander 
330*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( key != NULL );
331*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( nonce != NULL );
332*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( data_len == 0 || input  != NULL );
333*3d3b0591SJens Wiklander     CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
334*3d3b0591SJens Wiklander 
335*3d3b0591SJens Wiklander     mbedtls_chacha20_init( &ctx );
336*3d3b0591SJens Wiklander 
337*3d3b0591SJens Wiklander     ret = mbedtls_chacha20_setkey( &ctx, key );
338*3d3b0591SJens Wiklander     if( ret != 0 )
339*3d3b0591SJens Wiklander         goto cleanup;
340*3d3b0591SJens Wiklander 
341*3d3b0591SJens Wiklander     ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
342*3d3b0591SJens Wiklander     if( ret != 0 )
343*3d3b0591SJens Wiklander         goto cleanup;
344*3d3b0591SJens Wiklander 
345*3d3b0591SJens Wiklander     ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
346*3d3b0591SJens Wiklander 
347*3d3b0591SJens Wiklander cleanup:
348*3d3b0591SJens Wiklander     mbedtls_chacha20_free( &ctx );
349*3d3b0591SJens Wiklander     return( ret );
350*3d3b0591SJens Wiklander }
351*3d3b0591SJens Wiklander 
352*3d3b0591SJens Wiklander #endif /* !MBEDTLS_CHACHA20_ALT */
353*3d3b0591SJens Wiklander 
354*3d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST)
355*3d3b0591SJens Wiklander 
356*3d3b0591SJens Wiklander static const unsigned char test_keys[2][32] =
357*3d3b0591SJens Wiklander {
358*3d3b0591SJens Wiklander     {
359*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
363*3d3b0591SJens Wiklander     },
364*3d3b0591SJens Wiklander     {
365*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
369*3d3b0591SJens Wiklander     }
370*3d3b0591SJens Wiklander };
371*3d3b0591SJens Wiklander 
372*3d3b0591SJens Wiklander static const unsigned char test_nonces[2][12] =
373*3d3b0591SJens Wiklander {
374*3d3b0591SJens Wiklander     {
375*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00
377*3d3b0591SJens Wiklander     },
378*3d3b0591SJens Wiklander     {
379*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x02
381*3d3b0591SJens Wiklander     }
382*3d3b0591SJens Wiklander };
383*3d3b0591SJens Wiklander 
384*3d3b0591SJens Wiklander static const uint32_t test_counters[2] =
385*3d3b0591SJens Wiklander {
386*3d3b0591SJens Wiklander     0U,
387*3d3b0591SJens Wiklander     1U
388*3d3b0591SJens Wiklander };
389*3d3b0591SJens Wiklander 
390*3d3b0591SJens Wiklander static const unsigned char test_input[2][375] =
391*3d3b0591SJens Wiklander {
392*3d3b0591SJens Wiklander     {
393*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400*3d3b0591SJens Wiklander         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
401*3d3b0591SJens Wiklander     },
402*3d3b0591SJens Wiklander     {
403*3d3b0591SJens Wiklander         0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
404*3d3b0591SJens Wiklander         0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
405*3d3b0591SJens Wiklander         0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
406*3d3b0591SJens Wiklander         0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
407*3d3b0591SJens Wiklander         0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
408*3d3b0591SJens Wiklander         0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
409*3d3b0591SJens Wiklander         0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
410*3d3b0591SJens Wiklander         0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
411*3d3b0591SJens Wiklander         0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
412*3d3b0591SJens Wiklander         0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
413*3d3b0591SJens Wiklander         0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
414*3d3b0591SJens Wiklander         0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
415*3d3b0591SJens Wiklander         0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
416*3d3b0591SJens Wiklander         0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
417*3d3b0591SJens Wiklander         0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
418*3d3b0591SJens Wiklander         0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
419*3d3b0591SJens Wiklander         0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
420*3d3b0591SJens Wiklander         0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
421*3d3b0591SJens Wiklander         0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
422*3d3b0591SJens Wiklander         0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
423*3d3b0591SJens Wiklander         0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
424*3d3b0591SJens Wiklander         0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
425*3d3b0591SJens Wiklander         0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
426*3d3b0591SJens Wiklander         0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
427*3d3b0591SJens Wiklander         0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
428*3d3b0591SJens Wiklander         0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
429*3d3b0591SJens Wiklander         0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
430*3d3b0591SJens Wiklander         0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
431*3d3b0591SJens Wiklander         0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
432*3d3b0591SJens Wiklander         0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
433*3d3b0591SJens Wiklander         0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
434*3d3b0591SJens Wiklander         0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
435*3d3b0591SJens Wiklander         0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
436*3d3b0591SJens Wiklander         0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
437*3d3b0591SJens Wiklander         0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
438*3d3b0591SJens Wiklander         0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
439*3d3b0591SJens Wiklander         0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
440*3d3b0591SJens Wiklander         0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
441*3d3b0591SJens Wiklander         0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
442*3d3b0591SJens Wiklander         0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
443*3d3b0591SJens Wiklander         0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
444*3d3b0591SJens Wiklander         0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
445*3d3b0591SJens Wiklander         0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
446*3d3b0591SJens Wiklander         0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
447*3d3b0591SJens Wiklander         0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
448*3d3b0591SJens Wiklander         0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
449*3d3b0591SJens Wiklander         0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
450*3d3b0591SJens Wiklander     }
451*3d3b0591SJens Wiklander };
452*3d3b0591SJens Wiklander 
453*3d3b0591SJens Wiklander static const unsigned char test_output[2][375] =
454*3d3b0591SJens Wiklander {
455*3d3b0591SJens Wiklander     {
456*3d3b0591SJens Wiklander         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
457*3d3b0591SJens Wiklander         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
458*3d3b0591SJens Wiklander         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
459*3d3b0591SJens Wiklander         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
460*3d3b0591SJens Wiklander         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
461*3d3b0591SJens Wiklander         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
462*3d3b0591SJens Wiklander         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
463*3d3b0591SJens Wiklander         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
464*3d3b0591SJens Wiklander     },
465*3d3b0591SJens Wiklander     {
466*3d3b0591SJens Wiklander         0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
467*3d3b0591SJens Wiklander         0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
468*3d3b0591SJens Wiklander         0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
469*3d3b0591SJens Wiklander         0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
470*3d3b0591SJens Wiklander         0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
471*3d3b0591SJens Wiklander         0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
472*3d3b0591SJens Wiklander         0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
473*3d3b0591SJens Wiklander         0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
474*3d3b0591SJens Wiklander         0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
475*3d3b0591SJens Wiklander         0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
476*3d3b0591SJens Wiklander         0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
477*3d3b0591SJens Wiklander         0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
478*3d3b0591SJens Wiklander         0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
479*3d3b0591SJens Wiklander         0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
480*3d3b0591SJens Wiklander         0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
481*3d3b0591SJens Wiklander         0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
482*3d3b0591SJens Wiklander         0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
483*3d3b0591SJens Wiklander         0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
484*3d3b0591SJens Wiklander         0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
485*3d3b0591SJens Wiklander         0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
486*3d3b0591SJens Wiklander         0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
487*3d3b0591SJens Wiklander         0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
488*3d3b0591SJens Wiklander         0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
489*3d3b0591SJens Wiklander         0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
490*3d3b0591SJens Wiklander         0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
491*3d3b0591SJens Wiklander         0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
492*3d3b0591SJens Wiklander         0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
493*3d3b0591SJens Wiklander         0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
494*3d3b0591SJens Wiklander         0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
495*3d3b0591SJens Wiklander         0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
496*3d3b0591SJens Wiklander         0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
497*3d3b0591SJens Wiklander         0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
498*3d3b0591SJens Wiklander         0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
499*3d3b0591SJens Wiklander         0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
500*3d3b0591SJens Wiklander         0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
501*3d3b0591SJens Wiklander         0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
502*3d3b0591SJens Wiklander         0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
503*3d3b0591SJens Wiklander         0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
504*3d3b0591SJens Wiklander         0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
505*3d3b0591SJens Wiklander         0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
506*3d3b0591SJens Wiklander         0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
507*3d3b0591SJens Wiklander         0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
508*3d3b0591SJens Wiklander         0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
509*3d3b0591SJens Wiklander         0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
510*3d3b0591SJens Wiklander         0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
511*3d3b0591SJens Wiklander         0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
512*3d3b0591SJens Wiklander         0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
513*3d3b0591SJens Wiklander     }
514*3d3b0591SJens Wiklander };
515*3d3b0591SJens Wiklander 
516*3d3b0591SJens Wiklander static const size_t test_lengths[2] =
517*3d3b0591SJens Wiklander {
518*3d3b0591SJens Wiklander     64U,
519*3d3b0591SJens Wiklander     375U
520*3d3b0591SJens Wiklander };
521*3d3b0591SJens Wiklander 
522*3d3b0591SJens Wiklander #define ASSERT( cond, args )            \
523*3d3b0591SJens Wiklander     do                                  \
524*3d3b0591SJens Wiklander     {                                   \
525*3d3b0591SJens Wiklander         if( ! ( cond ) )                \
526*3d3b0591SJens Wiklander         {                               \
527*3d3b0591SJens Wiklander             if( verbose != 0 )          \
528*3d3b0591SJens Wiklander                 mbedtls_printf args;    \
529*3d3b0591SJens Wiklander                                         \
530*3d3b0591SJens Wiklander             return( -1 );               \
531*3d3b0591SJens Wiklander         }                               \
532*3d3b0591SJens Wiklander     }                                   \
533*3d3b0591SJens Wiklander     while( 0 )
534*3d3b0591SJens Wiklander 
535*3d3b0591SJens Wiklander int mbedtls_chacha20_self_test( int verbose )
536*3d3b0591SJens Wiklander {
537*3d3b0591SJens Wiklander     unsigned char output[381];
538*3d3b0591SJens Wiklander     unsigned i;
539*3d3b0591SJens Wiklander     int ret;
540*3d3b0591SJens Wiklander 
541*3d3b0591SJens Wiklander     for( i = 0U; i < 2U; i++ )
542*3d3b0591SJens Wiklander     {
543*3d3b0591SJens Wiklander         if( verbose != 0 )
544*3d3b0591SJens Wiklander             mbedtls_printf( "  ChaCha20 test %u ", i );
545*3d3b0591SJens Wiklander 
546*3d3b0591SJens Wiklander         ret = mbedtls_chacha20_crypt( test_keys[i],
547*3d3b0591SJens Wiklander                                       test_nonces[i],
548*3d3b0591SJens Wiklander                                       test_counters[i],
549*3d3b0591SJens Wiklander                                       test_lengths[i],
550*3d3b0591SJens Wiklander                                       test_input[i],
551*3d3b0591SJens Wiklander                                       output );
552*3d3b0591SJens Wiklander 
553*3d3b0591SJens Wiklander         ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
554*3d3b0591SJens Wiklander 
555*3d3b0591SJens Wiklander         ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
556*3d3b0591SJens Wiklander                 ( "failed (output)\n" ) );
557*3d3b0591SJens Wiklander 
558*3d3b0591SJens Wiklander         if( verbose != 0 )
559*3d3b0591SJens Wiklander             mbedtls_printf( "passed\n" );
560*3d3b0591SJens Wiklander     }
561*3d3b0591SJens Wiklander 
562*3d3b0591SJens Wiklander     if( verbose != 0 )
563*3d3b0591SJens Wiklander         mbedtls_printf( "\n" );
564*3d3b0591SJens Wiklander 
565*3d3b0591SJens Wiklander     return( 0 );
566*3d3b0591SJens Wiklander }
567*3d3b0591SJens Wiklander 
568*3d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */
569*3d3b0591SJens Wiklander 
570*3d3b0591SJens Wiklander #endif /* !MBEDTLS_CHACHA20_C */
571