]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/mbedtls/library/poly1305.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / mbedtls / library / poly1305.c
1 /**\r
2  * \file poly1305.c\r
3  *\r
4  * \brief Poly1305 authentication algorithm.\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_POLY1305_C)\r
30 \r
31 #include "mbedtls/poly1305.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_POLY1305_ALT)\r
46 \r
47 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \\r
48     !defined(inline) && !defined(__cplusplus)\r
49 #define inline __inline\r
50 #endif\r
51 \r
52 /* Parameter validation macros */\r
53 #define POLY1305_VALIDATE_RET( cond )                                       \\r
54     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )\r
55 #define POLY1305_VALIDATE( cond )                                           \\r
56     MBEDTLS_INTERNAL_VALIDATE( cond )\r
57 \r
58 #define POLY1305_BLOCK_SIZE_BYTES ( 16U )\r
59 \r
60 #define BYTES_TO_U32_LE( data, offset )                           \\r
61     ( (uint32_t) (data)[offset]                                     \\r
62           | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 )   \\r
63           | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 )  \\r
64           | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 )  \\r
65     )\r
66 \r
67 /*\r
68  * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.\r
69  * However we provided an alternative for platforms without such a multiplier.\r
70  */\r
71 #if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)\r
72 static uint64_t mul64( uint32_t a, uint32_t b )\r
73 {\r
74     /* a = al + 2**16 ah, b = bl + 2**16 bh */\r
75     const uint16_t al = (uint16_t) a;\r
76     const uint16_t bl = (uint16_t) b;\r
77     const uint16_t ah = a >> 16;\r
78     const uint16_t bh = b >> 16;\r
79 \r
80     /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */\r
81     const uint32_t lo = (uint32_t) al * bl;\r
82     const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;\r
83     const uint32_t hi = (uint32_t) ah * bh;\r
84 \r
85     return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );\r
86 }\r
87 #else\r
88 static inline uint64_t mul64( uint32_t a, uint32_t b )\r
89 {\r
90     return( (uint64_t) a * b );\r
91 }\r
92 #endif\r
93 \r
94 \r
95 /**\r
96  * \brief                   Process blocks with Poly1305.\r
97  *\r
98  * \param ctx               The Poly1305 context.\r
99  * \param nblocks           Number of blocks to process. Note that this\r
100  *                          function only processes full blocks.\r
101  * \param input             Buffer containing the input block(s).\r
102  * \param needs_padding     Set to 0 if the padding bit has already been\r
103  *                          applied to the input data before calling this\r
104  *                          function.  Otherwise, set this parameter to 1.\r
105  */\r
106 static void poly1305_process( mbedtls_poly1305_context *ctx,\r
107                               size_t nblocks,\r
108                               const unsigned char *input,\r
109                               uint32_t needs_padding )\r
110 {\r
111     uint64_t d0, d1, d2, d3;\r
112     uint32_t acc0, acc1, acc2, acc3, acc4;\r
113     uint32_t r0, r1, r2, r3;\r
114     uint32_t rs1, rs2, rs3;\r
115     size_t offset  = 0U;\r
116     size_t i;\r
117 \r
118     r0 = ctx->r[0];\r
119     r1 = ctx->r[1];\r
120     r2 = ctx->r[2];\r
121     r3 = ctx->r[3];\r
122 \r
123     rs1 = r1 + ( r1 >> 2U );\r
124     rs2 = r2 + ( r2 >> 2U );\r
125     rs3 = r3 + ( r3 >> 2U );\r
126 \r
127     acc0 = ctx->acc[0];\r
128     acc1 = ctx->acc[1];\r
129     acc2 = ctx->acc[2];\r
130     acc3 = ctx->acc[3];\r
131     acc4 = ctx->acc[4];\r
132 \r
133     /* Process full blocks */\r
134     for( i = 0U; i < nblocks; i++ )\r
135     {\r
136         /* The input block is treated as a 128-bit little-endian integer */\r
137         d0   = BYTES_TO_U32_LE( input, offset + 0  );\r
138         d1   = BYTES_TO_U32_LE( input, offset + 4  );\r
139         d2   = BYTES_TO_U32_LE( input, offset + 8  );\r
140         d3   = BYTES_TO_U32_LE( input, offset + 12 );\r
141 \r
142         /* Compute: acc += (padded) block as a 130-bit integer */\r
143         d0  += (uint64_t) acc0;\r
144         d1  += (uint64_t) acc1 + ( d0 >> 32U );\r
145         d2  += (uint64_t) acc2 + ( d1 >> 32U );\r
146         d3  += (uint64_t) acc3 + ( d2 >> 32U );\r
147         acc0 = (uint32_t) d0;\r
148         acc1 = (uint32_t) d1;\r
149         acc2 = (uint32_t) d2;\r
150         acc3 = (uint32_t) d3;\r
151         acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;\r
152 \r
153         /* Compute: acc *= r */\r
154         d0 = mul64( acc0, r0  ) +\r
155              mul64( acc1, rs3 ) +\r
156              mul64( acc2, rs2 ) +\r
157              mul64( acc3, rs1 );\r
158         d1 = mul64( acc0, r1  ) +\r
159              mul64( acc1, r0  ) +\r
160              mul64( acc2, rs3 ) +\r
161              mul64( acc3, rs2 ) +\r
162              mul64( acc4, rs1 );\r
163         d2 = mul64( acc0, r2  ) +\r
164              mul64( acc1, r1  ) +\r
165              mul64( acc2, r0  ) +\r
166              mul64( acc3, rs3 ) +\r
167              mul64( acc4, rs2 );\r
168         d3 = mul64( acc0, r3  ) +\r
169              mul64( acc1, r2  ) +\r
170              mul64( acc2, r1  ) +\r
171              mul64( acc3, r0  ) +\r
172              mul64( acc4, rs3 );\r
173         acc4 *= r0;\r
174 \r
175         /* Compute: acc %= (2^130 - 5) (partial remainder) */\r
176         d1 += ( d0 >> 32 );\r
177         d2 += ( d1 >> 32 );\r
178         d3 += ( d2 >> 32 );\r
179         acc0 = (uint32_t) d0;\r
180         acc1 = (uint32_t) d1;\r
181         acc2 = (uint32_t) d2;\r
182         acc3 = (uint32_t) d3;\r
183         acc4 = (uint32_t) ( d3 >> 32 ) + acc4;\r
184 \r
185         d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );\r
186         acc4 &= 3U;\r
187         acc0 = (uint32_t) d0;\r
188         d0 = (uint64_t) acc1 + ( d0 >> 32U );\r
189         acc1 = (uint32_t) d0;\r
190         d0 = (uint64_t) acc2 + ( d0 >> 32U );\r
191         acc2 = (uint32_t) d0;\r
192         d0 = (uint64_t) acc3 + ( d0 >> 32U );\r
193         acc3 = (uint32_t) d0;\r
194         d0 = (uint64_t) acc4 + ( d0 >> 32U );\r
195         acc4 = (uint32_t) d0;\r
196 \r
197         offset    += POLY1305_BLOCK_SIZE_BYTES;\r
198     }\r
199 \r
200     ctx->acc[0] = acc0;\r
201     ctx->acc[1] = acc1;\r
202     ctx->acc[2] = acc2;\r
203     ctx->acc[3] = acc3;\r
204     ctx->acc[4] = acc4;\r
205 }\r
206 \r
207 /**\r
208  * \brief                   Compute the Poly1305 MAC\r
209  *\r
210  * \param ctx               The Poly1305 context.\r
211  * \param mac               The buffer to where the MAC is written. Must be\r
212  *                          big enough to contain the 16-byte MAC.\r
213  */\r
214 static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,\r
215                                   unsigned char mac[16] )\r
216 {\r
217     uint64_t d;\r
218     uint32_t g0, g1, g2, g3, g4;\r
219     uint32_t acc0, acc1, acc2, acc3, acc4;\r
220     uint32_t mask;\r
221     uint32_t mask_inv;\r
222 \r
223     acc0 = ctx->acc[0];\r
224     acc1 = ctx->acc[1];\r
225     acc2 = ctx->acc[2];\r
226     acc3 = ctx->acc[3];\r
227     acc4 = ctx->acc[4];\r
228 \r
229     /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.\r
230      * We do this by calculating acc - (2^130 - 5), then checking if\r
231      * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)\r
232      */\r
233 \r
234     /* Calculate acc + -(2^130 - 5) */\r
235     d  = ( (uint64_t) acc0 + 5U );\r
236     g0 = (uint32_t) d;\r
237     d  = ( (uint64_t) acc1 + ( d >> 32 ) );\r
238     g1 = (uint32_t) d;\r
239     d  = ( (uint64_t) acc2 + ( d >> 32 ) );\r
240     g2 = (uint32_t) d;\r
241     d  = ( (uint64_t) acc3 + ( d >> 32 ) );\r
242     g3 = (uint32_t) d;\r
243     g4 = acc4 + (uint32_t) ( d >> 32U );\r
244 \r
245     /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */\r
246     mask = (uint32_t) 0U - ( g4 >> 2U );\r
247     mask_inv = ~mask;\r
248 \r
249     /* If 131st bit is set then acc=g, otherwise, acc is unmodified */\r
250     acc0 = ( acc0 & mask_inv ) | ( g0 & mask );\r
251     acc1 = ( acc1 & mask_inv ) | ( g1 & mask );\r
252     acc2 = ( acc2 & mask_inv ) | ( g2 & mask );\r
253     acc3 = ( acc3 & mask_inv ) | ( g3 & mask );\r
254 \r
255     /* Add 's' */\r
256     d = (uint64_t) acc0 + ctx->s[0];\r
257     acc0 = (uint32_t) d;\r
258     d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );\r
259     acc1 = (uint32_t) d;\r
260     d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );\r
261     acc2 = (uint32_t) d;\r
262     acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );\r
263 \r
264     /* Compute MAC (128 least significant bits of the accumulator) */\r
265     mac[ 0] = (unsigned char)( acc0       );\r
266     mac[ 1] = (unsigned char)( acc0 >>  8 );\r
267     mac[ 2] = (unsigned char)( acc0 >> 16 );\r
268     mac[ 3] = (unsigned char)( acc0 >> 24 );\r
269     mac[ 4] = (unsigned char)( acc1       );\r
270     mac[ 5] = (unsigned char)( acc1 >>  8 );\r
271     mac[ 6] = (unsigned char)( acc1 >> 16 );\r
272     mac[ 7] = (unsigned char)( acc1 >> 24 );\r
273     mac[ 8] = (unsigned char)( acc2       );\r
274     mac[ 9] = (unsigned char)( acc2 >>  8 );\r
275     mac[10] = (unsigned char)( acc2 >> 16 );\r
276     mac[11] = (unsigned char)( acc2 >> 24 );\r
277     mac[12] = (unsigned char)( acc3       );\r
278     mac[13] = (unsigned char)( acc3 >>  8 );\r
279     mac[14] = (unsigned char)( acc3 >> 16 );\r
280     mac[15] = (unsigned char)( acc3 >> 24 );\r
281 }\r
282 \r
283 void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )\r
284 {\r
285     POLY1305_VALIDATE( ctx != NULL );\r
286 \r
287     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );\r
288 }\r
289 \r
290 void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )\r
291 {\r
292     if( ctx == NULL )\r
293         return;\r
294 \r
295     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );\r
296 }\r
297 \r
298 int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,\r
299                              const unsigned char key[32] )\r
300 {\r
301     POLY1305_VALIDATE_RET( ctx != NULL );\r
302     POLY1305_VALIDATE_RET( key != NULL );\r
303 \r
304     /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */\r
305     ctx->r[0] = BYTES_TO_U32_LE( key, 0 )  & 0x0FFFFFFFU;\r
306     ctx->r[1] = BYTES_TO_U32_LE( key, 4 )  & 0x0FFFFFFCU;\r
307     ctx->r[2] = BYTES_TO_U32_LE( key, 8 )  & 0x0FFFFFFCU;\r
308     ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;\r
309 \r
310     ctx->s[0] = BYTES_TO_U32_LE( key, 16 );\r
311     ctx->s[1] = BYTES_TO_U32_LE( key, 20 );\r
312     ctx->s[2] = BYTES_TO_U32_LE( key, 24 );\r
313     ctx->s[3] = BYTES_TO_U32_LE( key, 28 );\r
314 \r
315     /* Initial accumulator state */\r
316     ctx->acc[0] = 0U;\r
317     ctx->acc[1] = 0U;\r
318     ctx->acc[2] = 0U;\r
319     ctx->acc[3] = 0U;\r
320     ctx->acc[4] = 0U;\r
321 \r
322     /* Queue initially empty */\r
323     mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );\r
324     ctx->queue_len = 0U;\r
325 \r
326     return( 0 );\r
327 }\r
328 \r
329 int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,\r
330                              const unsigned char *input,\r
331                              size_t ilen )\r
332 {\r
333     size_t offset    = 0U;\r
334     size_t remaining = ilen;\r
335     size_t queue_free_len;\r
336     size_t nblocks;\r
337     POLY1305_VALIDATE_RET( ctx != NULL );\r
338     POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );\r
339 \r
340     if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )\r
341     {\r
342         queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );\r
343 \r
344         if( ilen < queue_free_len )\r
345         {\r
346             /* Not enough data to complete the block.\r
347              * Store this data with the other leftovers.\r
348              */\r
349             memcpy( &ctx->queue[ctx->queue_len],\r
350                     input,\r
351                     ilen );\r
352 \r
353             ctx->queue_len += ilen;\r
354 \r
355             remaining = 0U;\r
356         }\r
357         else\r
358         {\r
359             /* Enough data to produce a complete block */\r
360             memcpy( &ctx->queue[ctx->queue_len],\r
361                     input,\r
362                     queue_free_len );\r
363 \r
364             ctx->queue_len = 0U;\r
365 \r
366             poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */\r
367 \r
368             offset    += queue_free_len;\r
369             remaining -= queue_free_len;\r
370         }\r
371     }\r
372 \r
373     if( remaining >= POLY1305_BLOCK_SIZE_BYTES )\r
374     {\r
375         nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;\r
376 \r
377         poly1305_process( ctx, nblocks, &input[offset], 1U );\r
378 \r
379         offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;\r
380         remaining %= POLY1305_BLOCK_SIZE_BYTES;\r
381     }\r
382 \r
383     if( remaining > 0U )\r
384     {\r
385         /* Store partial block */\r
386         ctx->queue_len = remaining;\r
387         memcpy( ctx->queue, &input[offset], remaining );\r
388     }\r
389 \r
390     return( 0 );\r
391 }\r
392 \r
393 int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,\r
394                              unsigned char mac[16] )\r
395 {\r
396     POLY1305_VALIDATE_RET( ctx != NULL );\r
397     POLY1305_VALIDATE_RET( mac != NULL );\r
398 \r
399     /* Process any leftover data */\r
400     if( ctx->queue_len > 0U )\r
401     {\r
402         /* Add padding bit */\r
403         ctx->queue[ctx->queue_len] = 1U;\r
404         ctx->queue_len++;\r
405 \r
406         /* Pad with zeroes */\r
407         memset( &ctx->queue[ctx->queue_len],\r
408                 0,\r
409                 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );\r
410 \r
411         poly1305_process( ctx, 1U,          /* Process 1 block */\r
412                           ctx->queue, 0U ); /* Already padded above */\r
413     }\r
414 \r
415     poly1305_compute_mac( ctx, mac );\r
416 \r
417     return( 0 );\r
418 }\r
419 \r
420 int mbedtls_poly1305_mac( const unsigned char key[32],\r
421                           const unsigned char *input,\r
422                           size_t ilen,\r
423                           unsigned char mac[16] )\r
424 {\r
425     mbedtls_poly1305_context ctx;\r
426     int ret;\r
427     POLY1305_VALIDATE_RET( key != NULL );\r
428     POLY1305_VALIDATE_RET( mac != NULL );\r
429     POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );\r
430 \r
431     mbedtls_poly1305_init( &ctx );\r
432 \r
433     ret = mbedtls_poly1305_starts( &ctx, key );\r
434     if( ret != 0 )\r
435         goto cleanup;\r
436 \r
437     ret = mbedtls_poly1305_update( &ctx, input, ilen );\r
438     if( ret != 0 )\r
439         goto cleanup;\r
440 \r
441     ret = mbedtls_poly1305_finish( &ctx, mac );\r
442 \r
443 cleanup:\r
444     mbedtls_poly1305_free( &ctx );\r
445     return( ret );\r
446 }\r
447 \r
448 #endif /* MBEDTLS_POLY1305_ALT */\r
449 \r
450 #if defined(MBEDTLS_SELF_TEST)\r
451 \r
452 static const unsigned char test_keys[2][32] =\r
453 {\r
454     {\r
455         0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,\r
456         0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,\r
457         0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,\r
458         0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b\r
459     },\r
460     {\r
461         0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,\r
462         0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,\r
463         0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,\r
464         0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0\r
465     }\r
466 };\r
467 \r
468 static const unsigned char test_data[2][127] =\r
469 {\r
470     {\r
471         0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,\r
472         0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,\r
473         0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,\r
474         0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,\r
475         0x75, 0x70\r
476     },\r
477     {\r
478         0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,\r
479         0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,\r
480         0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,\r
481         0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,\r
482         0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,\r
483         0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,\r
484         0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,\r
485         0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,\r
486         0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,\r
487         0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,\r
488         0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,\r
489         0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,\r
490         0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,\r
491         0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,\r
492         0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,\r
493         0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e\r
494     }\r
495 };\r
496 \r
497 static const size_t test_data_len[2] =\r
498 {\r
499     34U,\r
500     127U\r
501 };\r
502 \r
503 static const unsigned char test_mac[2][16] =\r
504 {\r
505     {\r
506         0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,\r
507         0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9\r
508     },\r
509     {\r
510         0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,\r
511         0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62\r
512     }\r
513 };\r
514 \r
515 #define ASSERT( cond, args )            \\r
516     do                                  \\r
517     {                                   \\r
518         if( ! ( cond ) )                \\r
519         {                               \\r
520             if( verbose != 0 )          \\r
521                 mbedtls_printf args;    \\r
522                                         \\r
523             return( -1 );               \\r
524         }                               \\r
525     }                                   \\r
526     while( 0 )\r
527 \r
528 int mbedtls_poly1305_self_test( int verbose )\r
529 {\r
530     unsigned char mac[16];\r
531     unsigned i;\r
532     int ret;\r
533 \r
534     for( i = 0U; i < 2U; i++ )\r
535     {\r
536         if( verbose != 0 )\r
537             mbedtls_printf( "  Poly1305 test %u ", i );\r
538 \r
539         ret = mbedtls_poly1305_mac( test_keys[i],\r
540                                     test_data[i],\r
541                                     test_data_len[i],\r
542                                     mac );\r
543         ASSERT( 0 == ret, ( "error code: %i\n", ret ) );\r
544 \r
545         ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );\r
546 \r
547         if( verbose != 0 )\r
548             mbedtls_printf( "passed\n" );\r
549     }\r
550 \r
551     if( verbose != 0 )\r
552         mbedtls_printf( "\n" );\r
553 \r
554     return( 0 );\r
555 }\r
556 \r
557 #endif /* MBEDTLS_SELF_TEST */\r
558 \r
559 #endif /* MBEDTLS_POLY1305_C */\r