]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/mbedtls/library/chachapoly.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / mbedtls / library / chachapoly.c
1 /**\r
2  * \file chachapoly.c\r
3  *\r
4  * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.\r
5  *\r
6  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved\r
7  *  SPDX-License-Identifier: Apache-2.0\r
8  *\r
9  *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
10  *  not use this file except in compliance with the License.\r
11  *  You may obtain a copy of the License at\r
12  *\r
13  *  http://www.apache.org/licenses/LICENSE-2.0\r
14  *\r
15  *  Unless required by applicable law or agreed to in writing, software\r
16  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
17  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
18  *  See the License for the specific language governing permissions and\r
19  *  limitations under the License.\r
20  *\r
21  *  This file is part of mbed TLS (https://tls.mbed.org)\r
22  */\r
23 #if !defined(MBEDTLS_CONFIG_FILE)\r
24 #include "mbedtls/config.h"\r
25 #else\r
26 #include MBEDTLS_CONFIG_FILE\r
27 #endif\r
28 \r
29 #if defined(MBEDTLS_CHACHAPOLY_C)\r
30 \r
31 #include "mbedtls/chachapoly.h"\r
32 #include "mbedtls/platform_util.h"\r
33 \r
34 #include <string.h>\r
35 \r
36 #if defined(MBEDTLS_SELF_TEST)\r
37 #if defined(MBEDTLS_PLATFORM_C)\r
38 #include "mbedtls/platform.h"\r
39 #else\r
40 #include <stdio.h>\r
41 #define mbedtls_printf printf\r
42 #endif /* MBEDTLS_PLATFORM_C */\r
43 #endif /* MBEDTLS_SELF_TEST */\r
44 \r
45 #if !defined(MBEDTLS_CHACHAPOLY_ALT)\r
46 \r
47 /* Parameter validation macros */\r
48 #define CHACHAPOLY_VALIDATE_RET( cond )                                       \\r
49     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )\r
50 #define CHACHAPOLY_VALIDATE( cond )                                           \\r
51     MBEDTLS_INTERNAL_VALIDATE( cond )\r
52 \r
53 #define CHACHAPOLY_STATE_INIT       ( 0 )\r
54 #define CHACHAPOLY_STATE_AAD        ( 1 )\r
55 #define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */\r
56 #define CHACHAPOLY_STATE_FINISHED   ( 3 )\r
57 \r
58 /**\r
59  * \brief           Adds nul bytes to pad the AAD for Poly1305.\r
60  *\r
61  * \param ctx       The ChaCha20-Poly1305 context.\r
62  */\r
63 static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )\r
64 {\r
65     uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );\r
66     unsigned char zeroes[15];\r
67 \r
68     if( partial_block_len == 0U )\r
69         return( 0 );\r
70 \r
71     memset( zeroes, 0, sizeof( zeroes ) );\r
72 \r
73     return( mbedtls_poly1305_update( &ctx->poly1305_ctx,\r
74                                      zeroes,\r
75                                      16U - partial_block_len ) );\r
76 }\r
77 \r
78 /**\r
79  * \brief           Adds nul bytes to pad the ciphertext for Poly1305.\r
80  *\r
81  * \param ctx       The ChaCha20-Poly1305 context.\r
82  */\r
83 static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )\r
84 {\r
85     uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );\r
86     unsigned char zeroes[15];\r
87 \r
88     if( partial_block_len == 0U )\r
89         return( 0 );\r
90 \r
91     memset( zeroes, 0, sizeof( zeroes ) );\r
92     return( mbedtls_poly1305_update( &ctx->poly1305_ctx,\r
93                                      zeroes,\r
94                                      16U - partial_block_len ) );\r
95 }\r
96 \r
97 void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )\r
98 {\r
99     CHACHAPOLY_VALIDATE( ctx != NULL );\r
100 \r
101     mbedtls_chacha20_init( &ctx->chacha20_ctx );\r
102     mbedtls_poly1305_init( &ctx->poly1305_ctx );\r
103     ctx->aad_len        = 0U;\r
104     ctx->ciphertext_len = 0U;\r
105     ctx->state          = CHACHAPOLY_STATE_INIT;\r
106     ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;\r
107 }\r
108 \r
109 void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )\r
110 {\r
111     if( ctx == NULL )\r
112         return;\r
113 \r
114     mbedtls_chacha20_free( &ctx->chacha20_ctx );\r
115     mbedtls_poly1305_free( &ctx->poly1305_ctx );\r
116     ctx->aad_len        = 0U;\r
117     ctx->ciphertext_len = 0U;\r
118     ctx->state          = CHACHAPOLY_STATE_INIT;\r
119     ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;\r
120 }\r
121 \r
122 int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,\r
123                                const unsigned char key[32] )\r
124 {\r
125     int ret;\r
126     CHACHAPOLY_VALIDATE_RET( ctx != NULL );\r
127     CHACHAPOLY_VALIDATE_RET( key != NULL );\r
128 \r
129     ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );\r
130 \r
131     return( ret );\r
132 }\r
133 \r
134 int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,\r
135                                const unsigned char nonce[12],\r
136                                mbedtls_chachapoly_mode_t mode  )\r
137 {\r
138     int ret;\r
139     unsigned char poly1305_key[64];\r
140     CHACHAPOLY_VALIDATE_RET( ctx != NULL );\r
141     CHACHAPOLY_VALIDATE_RET( nonce != NULL );\r
142 \r
143     /* Set counter = 0, will be update to 1 when generating Poly1305 key */\r
144     ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );\r
145     if( ret != 0 )\r
146         goto cleanup;\r
147 \r
148     /* Generate the Poly1305 key by getting the ChaCha20 keystream output with\r
149      * counter = 0.  This is the same as encrypting a buffer of zeroes.\r
150      * Only the first 256-bits (32 bytes) of the key is used for Poly1305.\r
151      * The other 256 bits are discarded.\r
152      */\r
153     memset( poly1305_key, 0, sizeof( poly1305_key ) );\r
154     ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),\r
155                                       poly1305_key, poly1305_key );\r
156     if( ret != 0 )\r
157         goto cleanup;\r
158 \r
159     ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );\r
160 \r
161     if( ret == 0 )\r
162     {\r
163         ctx->aad_len        = 0U;\r
164         ctx->ciphertext_len = 0U;\r
165         ctx->state          = CHACHAPOLY_STATE_AAD;\r
166         ctx->mode           = mode;\r
167     }\r
168 \r
169 cleanup:\r
170     mbedtls_platform_zeroize( poly1305_key, 64U );\r
171     return( ret );\r
172 }\r
173 \r
174 int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,\r
175                                    const unsigned char *aad,\r
176                                    size_t aad_len )\r
177 {\r
178     CHACHAPOLY_VALIDATE_RET( ctx != NULL );\r
179     CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );\r
180 \r
181     if( ctx->state != CHACHAPOLY_STATE_AAD )\r
182         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );\r
183 \r
184     ctx->aad_len += aad_len;\r
185 \r
186     return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );\r
187 }\r
188 \r
189 int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,\r
190                                size_t len,\r
191                                const unsigned char *input,\r
192                                unsigned char *output )\r
193 {\r
194     int ret;\r
195     CHACHAPOLY_VALIDATE_RET( ctx != NULL );\r
196     CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );\r
197     CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );\r
198 \r
199     if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&\r
200         ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )\r
201     {\r
202         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );\r
203     }\r
204 \r
205     if( ctx->state == CHACHAPOLY_STATE_AAD )\r
206     {\r
207         ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;\r
208 \r
209         ret = chachapoly_pad_aad( ctx );\r
210         if( ret != 0 )\r
211             return( ret );\r
212     }\r
213 \r
214     ctx->ciphertext_len += len;\r
215 \r
216     if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )\r
217     {\r
218         ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );\r
219         if( ret != 0 )\r
220             return( ret );\r
221 \r
222         ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );\r
223         if( ret != 0 )\r
224             return( ret );\r
225     }\r
226     else /* DECRYPT */\r
227     {\r
228         ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );\r
229         if( ret != 0 )\r
230             return( ret );\r
231 \r
232         ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );\r
233         if( ret != 0 )\r
234             return( ret );\r
235     }\r
236 \r
237     return( 0 );\r
238 }\r
239 \r
240 int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,\r
241                                unsigned char mac[16] )\r
242 {\r
243     int ret;\r
244     unsigned char len_block[16];\r
245     CHACHAPOLY_VALIDATE_RET( ctx != NULL );\r
246     CHACHAPOLY_VALIDATE_RET( mac != NULL );\r
247 \r
248     if( ctx->state == CHACHAPOLY_STATE_INIT )\r
249     {\r
250         return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );\r
251     }\r
252 \r
253     if( ctx->state == CHACHAPOLY_STATE_AAD )\r
254     {\r
255         ret = chachapoly_pad_aad( ctx );\r
256         if( ret != 0 )\r
257             return( ret );\r
258     }\r
259     else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )\r
260     {\r
261         ret = chachapoly_pad_ciphertext( ctx );\r
262         if( ret != 0 )\r
263             return( ret );\r
264     }\r
265 \r
266     ctx->state = CHACHAPOLY_STATE_FINISHED;\r
267 \r
268     /* The lengths of the AAD and ciphertext are processed by\r
269      * Poly1305 as the final 128-bit block, encoded as little-endian integers.\r
270      */\r
271     len_block[ 0] = (unsigned char)( ctx->aad_len       );\r
272     len_block[ 1] = (unsigned char)( ctx->aad_len >>  8 );\r
273     len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );\r
274     len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );\r
275     len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );\r
276     len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );\r
277     len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );\r
278     len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );\r
279     len_block[ 8] = (unsigned char)( ctx->ciphertext_len       );\r
280     len_block[ 9] = (unsigned char)( ctx->ciphertext_len >>  8 );\r
281     len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );\r
282     len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );\r
283     len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );\r
284     len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );\r
285     len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );\r
286     len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );\r
287 \r
288     ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );\r
289     if( ret != 0 )\r
290         return( ret );\r
291 \r
292     ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );\r
293 \r
294     return( ret );\r
295 }\r
296 \r
297 static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,\r
298                                      mbedtls_chachapoly_mode_t mode,\r
299                                      size_t length,\r
300                                      const unsigned char nonce[12],\r
301                                      const unsigned char *aad,\r
302                                      size_t aad_len,\r
303                                      const unsigned char *input,\r
304                                      unsigned char *output,\r
305                                      unsigned char tag[16] )\r
306 {\r
307     int ret;\r
308 \r
309     ret = mbedtls_chachapoly_starts( ctx, nonce, mode );\r
310     if( ret != 0 )\r
311         goto cleanup;\r
312 \r
313     ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );\r
314     if( ret != 0 )\r
315         goto cleanup;\r
316 \r
317     ret = mbedtls_chachapoly_update( ctx, length, input, output );\r
318     if( ret != 0 )\r
319         goto cleanup;\r
320 \r
321     ret = mbedtls_chachapoly_finish( ctx, tag );\r
322 \r
323 cleanup:\r
324     return( ret );\r
325 }\r
326 \r
327 int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,\r
328                                         size_t length,\r
329                                         const unsigned char nonce[12],\r
330                                         const unsigned char *aad,\r
331                                         size_t aad_len,\r
332                                         const unsigned char *input,\r
333                                         unsigned char *output,\r
334                                         unsigned char tag[16] )\r
335 {\r
336     CHACHAPOLY_VALIDATE_RET( ctx   != NULL );\r
337     CHACHAPOLY_VALIDATE_RET( nonce != NULL );\r
338     CHACHAPOLY_VALIDATE_RET( tag   != NULL );\r
339     CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );\r
340     CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );\r
341     CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );\r
342 \r
343     return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,\r
344                                       length, nonce, aad, aad_len,\r
345                                       input, output, tag ) );\r
346 }\r
347 \r
348 int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,\r
349                                      size_t length,\r
350                                      const unsigned char nonce[12],\r
351                                      const unsigned char *aad,\r
352                                      size_t aad_len,\r
353                                      const unsigned char tag[16],\r
354                                      const unsigned char *input,\r
355                                      unsigned char *output )\r
356 {\r
357     int ret;\r
358     unsigned char check_tag[16];\r
359     size_t i;\r
360     int diff;\r
361     CHACHAPOLY_VALIDATE_RET( ctx   != NULL );\r
362     CHACHAPOLY_VALIDATE_RET( nonce != NULL );\r
363     CHACHAPOLY_VALIDATE_RET( tag   != NULL );\r
364     CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );\r
365     CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );\r
366     CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );\r
367 \r
368     if( ( ret = chachapoly_crypt_and_tag( ctx,\r
369                         MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,\r
370                         aad, aad_len, input, output, check_tag ) ) != 0 )\r
371     {\r
372         return( ret );\r
373     }\r
374 \r
375     /* Check tag in "constant-time" */\r
376     for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )\r
377         diff |= tag[i] ^ check_tag[i];\r
378 \r
379     if( diff != 0 )\r
380     {\r
381         mbedtls_platform_zeroize( output, length );\r
382         return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );\r
383     }\r
384 \r
385     return( 0 );\r
386 }\r
387 \r
388 #endif /* MBEDTLS_CHACHAPOLY_ALT */\r
389 \r
390 #if defined(MBEDTLS_SELF_TEST)\r
391 \r
392 static const unsigned char test_key[1][32] =\r
393 {\r
394     {\r
395         0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,\r
396         0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\r
397         0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,\r
398         0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f\r
399     }\r
400 };\r
401 \r
402 static const unsigned char test_nonce[1][12] =\r
403 {\r
404     {\r
405         0x07, 0x00, 0x00, 0x00,                         /* 32-bit common part */\r
406         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47  /* 64-bit IV */\r
407     }\r
408 };\r
409 \r
410 static const unsigned char test_aad[1][12] =\r
411 {\r
412     {\r
413         0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,\r
414         0xc4, 0xc5, 0xc6, 0xc7\r
415     }\r
416 };\r
417 \r
418 static const size_t test_aad_len[1] =\r
419 {\r
420     12U\r
421 };\r
422 \r
423 static const unsigned char test_input[1][114] =\r
424 {\r
425     {\r
426         0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,\r
427         0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,\r
428         0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,\r
429         0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,\r
430         0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,\r
431         0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,\r
432         0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,\r
433         0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,\r
434         0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,\r
435         0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,\r
436         0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,\r
437         0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,\r
438         0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,\r
439         0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,\r
440         0x74, 0x2e\r
441     }\r
442 };\r
443 \r
444 static const unsigned char test_output[1][114] =\r
445 {\r
446     {\r
447         0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,\r
448         0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,\r
449         0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,\r
450         0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,\r
451         0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,\r
452         0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,\r
453         0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,\r
454         0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,\r
455         0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,\r
456         0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,\r
457         0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,\r
458         0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,\r
459         0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,\r
460         0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,\r
461         0x61, 0x16\r
462     }\r
463 };\r
464 \r
465 static const size_t test_input_len[1] =\r
466 {\r
467     114U\r
468 };\r
469 \r
470 static const unsigned char test_mac[1][16] =\r
471 {\r
472     {\r
473         0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,\r
474         0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91\r
475     }\r
476 };\r
477 \r
478 #define ASSERT( cond, args )            \\r
479     do                                  \\r
480     {                                   \\r
481         if( ! ( cond ) )                \\r
482         {                               \\r
483             if( verbose != 0 )          \\r
484                 mbedtls_printf args;    \\r
485                                         \\r
486             return( -1 );               \\r
487         }                               \\r
488     }                                   \\r
489     while( 0 )\r
490 \r
491 int mbedtls_chachapoly_self_test( int verbose )\r
492 {\r
493     mbedtls_chachapoly_context ctx;\r
494     unsigned i;\r
495     int ret;\r
496     unsigned char output[200];\r
497     unsigned char mac[16];\r
498 \r
499     for( i = 0U; i < 1U; i++ )\r
500     {\r
501         if( verbose != 0 )\r
502             mbedtls_printf( "  ChaCha20-Poly1305 test %u ", i );\r
503 \r
504         mbedtls_chachapoly_init( &ctx );\r
505 \r
506         ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );\r
507         ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );\r
508 \r
509         ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,\r
510                                                   test_input_len[i],\r
511                                                   test_nonce[i],\r
512                                                   test_aad[i],\r
513                                                   test_aad_len[i],\r
514                                                   test_input[i],\r
515                                                   output,\r
516                                                   mac );\r
517 \r
518         ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );\r
519 \r
520         ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),\r
521                 ( "failure (wrong output)\n" ) );\r
522 \r
523         ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),\r
524                 ( "failure (wrong MAC)\n" ) );\r
525 \r
526         mbedtls_chachapoly_free( &ctx );\r
527 \r
528         if( verbose != 0 )\r
529             mbedtls_printf( "passed\n" );\r
530     }\r
531 \r
532     if( verbose != 0 )\r
533         mbedtls_printf( "\n" );\r
534 \r
535     return( 0 );\r
536 }\r
537 \r
538 #endif /* MBEDTLS_SELF_TEST */\r
539 \r
540 #endif /* MBEDTLS_CHACHAPOLY_C */\r