blob: 091684e199bd31773c381fe6d435271933a16857 [file] [log] [blame]
Daniel Kingadc32c02016-05-16 18:25:45 -03001/**
2 * \file poly1305.c
3 *
4 * \brief Poly1305 authentication algorithm.
5 *
6 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23#if !defined(MBEDTLS_CONFIG_FILE)
24#include "mbedtls/config.h"
25#else
26#include MBEDTLS_CONFIG_FILE
27#endif
28
29#if defined(MBEDTLS_POLY1305_C)
30
Daniel Kingadc32c02016-05-16 18:25:45 -030031#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020032#include "mbedtls/platform_util.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030033
34#include <string.h>
35
36#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
38#include "mbedtls/platform.h"
39#else
40#include <stdio.h>
41#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
44
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020045#if !defined(MBEDTLS_POLY1305_ALT)
46
Daniel Kingadc32c02016-05-16 18:25:45 -030047#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
48
Daniel Kinge6e79682016-05-24 11:16:17 -030049#define BYTES_TO_U32_LE( data, offset ) \
50 ( (uint32_t) data[offset] \
51 | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \
52 | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \
53 | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \
Daniel Kingadc32c02016-05-16 18:25:45 -030054 )
55
Daniel Kingadc32c02016-05-16 18:25:45 -030056/**
57 * \brief Process blocks with Poly1305.
58 *
59 * \param ctx The Poly1305 context.
60 * \param nblocks Number of blocks to process. Note that this function
61 * only processes full blocks.
62 * \param input Buffer containing the input block(s).
63 * \param needs_padding Set to 0 if the padding bit has already been applied
64 * to the input data before calling this function.
65 * Otherwise, set this parameter to 1.
66 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020067static void poly1305_process( mbedtls_poly1305_context *ctx,
68 size_t nblocks,
69 const unsigned char *input,
70 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030071{
72 uint64_t d0, d1, d2, d3;
73 uint32_t acc0, acc1, acc2, acc3, acc4;
74 uint32_t r0, r1, r2, r3;
75 uint32_t rs1, rs2, rs3;
76 size_t offset = 0U;
77 size_t i;
78
79 r0 = ctx->r[0];
80 r1 = ctx->r[1];
81 r2 = ctx->r[2];
82 r3 = ctx->r[3];
83
84 rs1 = r1 + ( r1 >> 2U );
85 rs2 = r2 + ( r2 >> 2U );
86 rs3 = r3 + ( r3 >> 2U );
87
88 acc0 = ctx->acc[0];
89 acc1 = ctx->acc[1];
90 acc2 = ctx->acc[2];
91 acc3 = ctx->acc[3];
92 acc4 = ctx->acc[4];
93
94 /* Process full blocks */
95 for ( i = 0U; i < nblocks; i++ )
96 {
97 /* Compute: acc += block */
98 /* Note that the input block is treated as a 128-bit little-endian integer */
Daniel Kinge6e79682016-05-24 11:16:17 -030099 d0 = (uint64_t) acc0 + BYTES_TO_U32_LE( input, offset + 0 );
100 d1 = (uint64_t) acc1 + BYTES_TO_U32_LE( input, offset + 4 ) + ( d0 >> 32U );
101 d2 = (uint64_t) acc2 + BYTES_TO_U32_LE( input, offset + 8 ) + ( d1 >> 32U );
102 d3 = (uint64_t) acc3 + BYTES_TO_U32_LE( input, offset + 12 ) + ( d2 >> 32U );
103 acc0 = (uint32_t) d0;
104 acc1 = (uint32_t) d1;
105 acc2 = (uint32_t) d2;
106 acc3 = (uint32_t) d3;
107 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300108
109 /* Compute: acc *= r */
Daniel Kinge6e79682016-05-24 11:16:17 -0300110 d0 = ( (uint64_t) acc0 * r0 ) +
111 ( (uint64_t) acc1 * rs3 ) +
112 ( (uint64_t) acc2 * rs2 ) +
113 ( (uint64_t) acc3 * rs1 );
114 d1 = ( (uint64_t) acc0 * r1 ) +
115 ( (uint64_t) acc1 * r0 ) +
116 ( (uint64_t) acc2 * rs3 ) +
117 ( (uint64_t) acc3 * rs2 ) +
118 ( (uint64_t) acc4 * rs1 );
119 d2 = ( (uint64_t) acc0 * r2 ) +
120 ( (uint64_t) acc1 * r1 ) +
121 ( (uint64_t) acc2 * r0 ) +
122 ( (uint64_t) acc3 * rs3 ) +
123 ( (uint64_t) acc4 * rs2 );
124 d3 = ( (uint64_t) acc0 * r3 ) +
125 ( (uint64_t) acc1 * r2 ) +
126 ( (uint64_t) acc2 * r1 ) +
127 ( (uint64_t) acc3 * r0 ) +
128 ( (uint64_t) acc4 * rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300129 acc4 *= r0;
130
131 /* Compute: acc %= (2^130 - 5) (partial remainder) */
132 d1 += ( d0 >> 32 );
133 d2 += ( d1 >> 32 );
134 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300135 acc0 = (uint32_t) d0;
136 acc1 = (uint32_t) d1;
137 acc2 = (uint32_t) d2;
138 acc3 = (uint32_t) d3;
139 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300140
Daniel Kinge6e79682016-05-24 11:16:17 -0300141 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300142 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300143 acc0 = (uint32_t) d0;
144 d0 = (uint64_t) acc1 + ( d0 >> 32U );
145 acc1 = (uint32_t) d0;
146 d0 = (uint64_t) acc2 + ( d0 >> 32U );
147 acc2 = (uint32_t) d0;
148 d0 = (uint64_t) acc3 + ( d0 >> 32U );
149 acc3 = (uint32_t) d0;
150 d0 = (uint64_t) acc4 + ( d0 >> 32U );
151 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300152
153 offset += POLY1305_BLOCK_SIZE_BYTES;
154 }
155
156 ctx->acc[0] = acc0;
157 ctx->acc[1] = acc1;
158 ctx->acc[2] = acc2;
159 ctx->acc[3] = acc3;
160 ctx->acc[4] = acc4;
161}
162
163/**
164 * \brief Compute the Poly1305 MAC
165 *
166 * \param ctx The Poly1305 context.
167 * \param mac The buffer to where the MAC is written. Must be
168 * big enough to contain the 16-byte MAC.
169 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200170static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
171 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300172{
173 uint64_t d;
174 uint32_t g0, g1, g2, g3, g4;
175 uint32_t acc0, acc1, acc2, acc3, acc4;
176 uint32_t mask;
177 uint32_t mask_inv;
178
179 acc0 = ctx->acc[0];
180 acc1 = ctx->acc[1];
181 acc2 = ctx->acc[2];
182 acc3 = ctx->acc[3];
183 acc4 = ctx->acc[4];
184
185 /* Before adding 's' we need to ensure that the accumulator is mod 2^130 - 5.
186 * We do this by calculating acc - (2^130 - 5), then checking if
187 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
188 */
189
190 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300191 d = ( (uint64_t) acc0 + 5U );
192 g0 = (uint32_t) d;
193 d = ( (uint64_t) acc1 + ( d >> 32 ) );
194 g1 = (uint32_t) d;
195 d = ( (uint64_t) acc2 + ( d >> 32 ) );
196 g2 = (uint32_t) d;
197 d = ( (uint64_t) acc3 + ( d >> 32 ) );
198 g3 = (uint32_t) d;
199 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300200
201 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300202 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300203 mask_inv = ~mask;
204
205 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
206 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
207 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
208 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
209 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
210
211 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300212 d = (uint64_t) acc0 + ctx->s[0];
213 acc0 = (uint32_t) d;
214 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
215 acc1 = (uint32_t) d;
216 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
217 acc2 = (uint32_t) d;
218 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300219
220 /* Compute MAC (128 least significant bits of the accumulator) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300221 mac[0] = (unsigned char) acc0;
222 mac[1] = (unsigned char) ( acc0 >> 8 );
223 mac[2] = (unsigned char) ( acc0 >> 16 );
224 mac[3] = (unsigned char) ( acc0 >> 24 );
225 mac[4] = (unsigned char) acc1;
226 mac[5] = (unsigned char) ( acc1 >> 8 );
227 mac[6] = (unsigned char) ( acc1 >> 16 );
228 mac[7] = (unsigned char) ( acc1 >> 24 );
229 mac[8] = (unsigned char) acc2;
230 mac[9] = (unsigned char) ( acc2 >> 8 );
231 mac[10] = (unsigned char) ( acc2 >> 16 );
232 mac[11] = (unsigned char) ( acc2 >> 24 );
233 mac[12] = (unsigned char) acc3;
234 mac[13] = (unsigned char) ( acc3 >> 8 );
235 mac[14] = (unsigned char) ( acc3 >> 16 );
236 mac[15] = (unsigned char) ( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300237}
238
239void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
240{
241 if ( ctx != NULL )
242 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200243 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300244 }
245}
246
247void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
248{
249 if ( ctx != NULL )
250 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200251 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300252 }
253}
254
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200255int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300256 const unsigned char key[32] )
257{
Manuel Pégourié-Gonnarda8fa8b82018-05-10 10:12:36 +0200258 if ( ctx == NULL || key == NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300259 {
260 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
261 }
262
263 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
264 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
265 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
266 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
267 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
268
269 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
270 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
271 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
272 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
273
274 /* Initial accumulator state */
275 ctx->acc[0] = 0U;
276 ctx->acc[1] = 0U;
277 ctx->acc[2] = 0U;
278 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200279 ctx->acc[4] = 0U;
280
281 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200282 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200283 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300284
Daniel Kinge6e79682016-05-24 11:16:17 -0300285 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300286}
287
288int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200289 const unsigned char *input,
290 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300291{
292 size_t offset = 0U;
293 size_t remaining = ilen;
294 size_t queue_free_len;
295 size_t nblocks;
296
Daniel Kinga310c5e2016-05-17 15:56:26 -0300297 if ( ctx == NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300298 {
299 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
300 }
Daniel Kinga310c5e2016-05-17 15:56:26 -0300301 else if ( ( ilen > 0U ) && ( input == NULL ) )
302 {
303 /* input pointer is allowed to be NULL only if ilen == 0 */
304 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
305 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300306
Daniel Kinga310c5e2016-05-17 15:56:26 -0300307 if ( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300308 {
309 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
310
311 if ( ilen < queue_free_len )
312 {
313 /* Not enough data to complete the block.
314 * Store this data with the other leftovers.
315 */
316 memcpy( &ctx->queue[ctx->queue_len],
317 input,
318 ilen );
319
320 ctx->queue_len += ilen;
321
322 remaining = 0U;
323 }
324 else
325 {
326 /* Enough data to produce a complete block */
327 memcpy( &ctx->queue[ctx->queue_len],
328 input,
329 queue_free_len );
330
331 ctx->queue_len = 0U;
332
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200333 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300334
335 offset += queue_free_len;
336 remaining -= queue_free_len;
337 }
338 }
339
340 if ( remaining >= POLY1305_BLOCK_SIZE_BYTES )
341 {
342 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
343
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200344 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300345
346 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
347 remaining %= POLY1305_BLOCK_SIZE_BYTES;
348 }
349
350 if ( remaining > 0U )
351 {
352 /* Store partial block */
353 ctx->queue_len = remaining;
354 memcpy( ctx->queue, &input[offset], remaining );
355 }
356
357 return( 0 );
358}
359
360int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
361 unsigned char mac[16] )
362{
363 if ( ( ctx == NULL ) || ( mac == NULL ) )
364 {
365 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
366 }
367
368 /* Process any leftover data */
369 if ( ctx->queue_len > 0U )
370 {
371 /* Add padding bit */
372 ctx->queue[ctx->queue_len] = 1U;
373 ctx->queue_len++;
374
375 /* Pad with zeroes */
376 memset( &ctx->queue[ctx->queue_len],
377 0,
378 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
379
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200380 poly1305_process( ctx, 1U, /* Process 1 block */
381 ctx->queue, 0U ); /* Don't add padding bit (it was just added above) */
Daniel Kingadc32c02016-05-16 18:25:45 -0300382 }
383
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200384 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300385
386 return( 0 );
387}
388
Daniel Kingadc32c02016-05-16 18:25:45 -0300389int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200390 const unsigned char *input,
391 size_t ilen,
392 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300393{
394 mbedtls_poly1305_context ctx;
395 int result;
396
397 mbedtls_poly1305_init( &ctx );
398
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200399 result = mbedtls_poly1305_starts( &ctx, key );
Daniel Kingadc32c02016-05-16 18:25:45 -0300400 if ( result != 0 )
401 goto cleanup;
402
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200403 result = mbedtls_poly1305_update( &ctx, input, ilen );
Daniel Kingadc32c02016-05-16 18:25:45 -0300404 if ( result != 0 )
405 goto cleanup;
406
407 result = mbedtls_poly1305_finish( &ctx, mac );
408
409cleanup:
410 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnarda8fa8b82018-05-10 10:12:36 +0200411 return( result );
Daniel Kingadc32c02016-05-16 18:25:45 -0300412}
413
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200414#endif /* MBEDTLS_POLY1305_ALT */
415
Daniel Kingadc32c02016-05-16 18:25:45 -0300416#if defined(MBEDTLS_SELF_TEST)
417
418static const unsigned char test_keys[2][32] =
419{
420 {
421 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
422 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
423 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
424 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
425 },
426 {
427 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
428 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
429 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
430 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
431 }
432};
433
434static const unsigned char test_data[2][127] =
435{
436 {
437 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
438 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
439 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
440 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
441 0x75, 0x70
442 },
443 {
444 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
445 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
446 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
447 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
448 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
449 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
450 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
451 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
452 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
453 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
454 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
455 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
456 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
457 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
458 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
459 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
460 }
461};
462
463static const size_t test_data_len[2] =
464{
465 34U,
466 127U
467};
468
469static const unsigned char test_mac[2][16] =
470{
471 {
472 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
473 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
474 },
475 {
476 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
477 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
478 }
479};
480
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200481#define ASSERT( cond, args ) \
482 do \
483 { \
484 if( ! ( cond ) ) \
485 { \
486 if( verbose != 0 ) \
487 mbedtls_printf args; \
488 \
489 return( -1 ); \
490 } \
491 } \
492 while( 0 )
493
Daniel Kingadc32c02016-05-16 18:25:45 -0300494int mbedtls_poly1305_self_test( int verbose )
495{
Daniel Kinge6e79682016-05-24 11:16:17 -0300496 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200497 unsigned i;
Daniel Kingadc32c02016-05-16 18:25:45 -0300498 int result;
499
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200500 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300501 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200502 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200503 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300504
Daniel Kingadc32c02016-05-16 18:25:45 -0300505 result = mbedtls_poly1305_mac( test_keys[i],
Daniel Kinge6e79682016-05-24 11:16:17 -0300506 test_data[i],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200507 test_data_len[i],
Daniel Kinge6e79682016-05-24 11:16:17 -0300508 mac );
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200509 ASSERT( 0 == result, ( "error code: %i\n", result ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300510
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200511 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300512
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200513 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300514 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300515 }
516
517 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300518 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300519
520 return( 0 );
521}
522
523#endif /* MBEDTLS_SELF_TEST */
524
525#endif /* MBEDTLS_POLY1305_C */