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