blob: bafe6138091131c04997ff1a25f647c89b7e1aef [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
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020056/*
57 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
58 * However we provided an alternative for platforms without such a multiplier.
59 */
60#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
61static uint64_t mul64( uint32_t a, uint32_t b )
62{
63 /* a = al + 2**16 ah, b = bl + 2**16 bh */
64 const uint16_t al = (uint16_t) a;
65 const uint16_t bl = (uint16_t) b;
66 const uint16_t ah = a >> 16;
67 const uint16_t bh = b >> 16;
68
69 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
70 const uint32_t lo = (uint32_t) al * bl;
71 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
72 const uint32_t hi = (uint32_t) ah * bh;
73
74 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
75}
76#else
77static inline uint64_t mul64( uint32_t a, uint32_t b )
78{
79 return( (uint64_t) a * b );
80}
81#endif
82
83
Daniel Kingadc32c02016-05-16 18:25:45 -030084/**
85 * \brief Process blocks with Poly1305.
86 *
87 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020088 * \param nblocks Number of blocks to process. Note that this
89 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030090 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020091 * \param needs_padding Set to 0 if the padding bit has already been
92 * applied to the input data before calling this
93 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030094 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020095static void poly1305_process( mbedtls_poly1305_context *ctx,
96 size_t nblocks,
97 const unsigned char *input,
98 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030099{
100 uint64_t d0, d1, d2, d3;
101 uint32_t acc0, acc1, acc2, acc3, acc4;
102 uint32_t r0, r1, r2, r3;
103 uint32_t rs1, rs2, rs3;
104 size_t offset = 0U;
105 size_t i;
106
107 r0 = ctx->r[0];
108 r1 = ctx->r[1];
109 r2 = ctx->r[2];
110 r3 = ctx->r[3];
111
112 rs1 = r1 + ( r1 >> 2U );
113 rs2 = r2 + ( r2 >> 2U );
114 rs3 = r3 + ( r3 >> 2U );
115
116 acc0 = ctx->acc[0];
117 acc1 = ctx->acc[1];
118 acc2 = ctx->acc[2];
119 acc3 = ctx->acc[3];
120 acc4 = ctx->acc[4];
121
122 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200123 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300124 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200125 /* The input block is treated as a 128-bit little-endian integer */
126 d0 = BYTES_TO_U32_LE( input, offset + 0 );
127 d1 = BYTES_TO_U32_LE( input, offset + 4 );
128 d2 = BYTES_TO_U32_LE( input, offset + 8 );
129 d3 = BYTES_TO_U32_LE( input, offset + 12 );
130
131 /* Compute: acc += (padded) block as a 130-bit integer */
132 d0 += (uint64_t) acc0;
133 d1 += (uint64_t) acc1 + ( d0 >> 32U );
134 d2 += (uint64_t) acc2 + ( d1 >> 32U );
135 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300136 acc0 = (uint32_t) d0;
137 acc1 = (uint32_t) d1;
138 acc2 = (uint32_t) d2;
139 acc3 = (uint32_t) d3;
140 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300141
142 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200143 d0 = mul64( acc0, r0 ) +
144 mul64( acc1, rs3 ) +
145 mul64( acc2, rs2 ) +
146 mul64( acc3, rs1 );
147 d1 = mul64( acc0, r1 ) +
148 mul64( acc1, r0 ) +
149 mul64( acc2, rs3 ) +
150 mul64( acc3, rs2 ) +
151 mul64( acc4, rs1 );
152 d2 = mul64( acc0, r2 ) +
153 mul64( acc1, r1 ) +
154 mul64( acc2, r0 ) +
155 mul64( acc3, rs3 ) +
156 mul64( acc4, rs2 );
157 d3 = mul64( acc0, r3 ) +
158 mul64( acc1, r2 ) +
159 mul64( acc2, r1 ) +
160 mul64( acc3, r0 ) +
161 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300162 acc4 *= r0;
163
164 /* Compute: acc %= (2^130 - 5) (partial remainder) */
165 d1 += ( d0 >> 32 );
166 d2 += ( d1 >> 32 );
167 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300168 acc0 = (uint32_t) d0;
169 acc1 = (uint32_t) d1;
170 acc2 = (uint32_t) d2;
171 acc3 = (uint32_t) d3;
172 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300173
Daniel Kinge6e79682016-05-24 11:16:17 -0300174 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300175 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300176 acc0 = (uint32_t) d0;
177 d0 = (uint64_t) acc1 + ( d0 >> 32U );
178 acc1 = (uint32_t) d0;
179 d0 = (uint64_t) acc2 + ( d0 >> 32U );
180 acc2 = (uint32_t) d0;
181 d0 = (uint64_t) acc3 + ( d0 >> 32U );
182 acc3 = (uint32_t) d0;
183 d0 = (uint64_t) acc4 + ( d0 >> 32U );
184 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300185
186 offset += POLY1305_BLOCK_SIZE_BYTES;
187 }
188
189 ctx->acc[0] = acc0;
190 ctx->acc[1] = acc1;
191 ctx->acc[2] = acc2;
192 ctx->acc[3] = acc3;
193 ctx->acc[4] = acc4;
194}
195
196/**
197 * \brief Compute the Poly1305 MAC
198 *
199 * \param ctx The Poly1305 context.
200 * \param mac The buffer to where the MAC is written. Must be
201 * big enough to contain the 16-byte MAC.
202 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200203static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
204 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300205{
206 uint64_t d;
207 uint32_t g0, g1, g2, g3, g4;
208 uint32_t acc0, acc1, acc2, acc3, acc4;
209 uint32_t mask;
210 uint32_t mask_inv;
211
212 acc0 = ctx->acc[0];
213 acc1 = ctx->acc[1];
214 acc2 = ctx->acc[2];
215 acc3 = ctx->acc[3];
216 acc4 = ctx->acc[4];
217
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200218 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300219 * We do this by calculating acc - (2^130 - 5), then checking if
220 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
221 */
222
223 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300224 d = ( (uint64_t) acc0 + 5U );
225 g0 = (uint32_t) d;
226 d = ( (uint64_t) acc1 + ( d >> 32 ) );
227 g1 = (uint32_t) d;
228 d = ( (uint64_t) acc2 + ( d >> 32 ) );
229 g2 = (uint32_t) d;
230 d = ( (uint64_t) acc3 + ( d >> 32 ) );
231 g3 = (uint32_t) d;
232 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300233
234 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300235 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300236 mask_inv = ~mask;
237
238 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
239 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
240 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
241 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
242 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
243
244 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300245 d = (uint64_t) acc0 + ctx->s[0];
246 acc0 = (uint32_t) d;
247 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
248 acc1 = (uint32_t) d;
249 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
250 acc2 = (uint32_t) d;
251 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300252
253 /* Compute MAC (128 least significant bits of the accumulator) */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200254 mac[ 0] = (unsigned char)( acc0 );
255 mac[ 1] = (unsigned char)( acc0 >> 8 );
256 mac[ 2] = (unsigned char)( acc0 >> 16 );
257 mac[ 3] = (unsigned char)( acc0 >> 24 );
258 mac[ 4] = (unsigned char)( acc1 );
259 mac[ 5] = (unsigned char)( acc1 >> 8 );
260 mac[ 6] = (unsigned char)( acc1 >> 16 );
261 mac[ 7] = (unsigned char)( acc1 >> 24 );
262 mac[ 8] = (unsigned char)( acc2 );
263 mac[ 9] = (unsigned char)( acc2 >> 8 );
264 mac[10] = (unsigned char)( acc2 >> 16 );
265 mac[11] = (unsigned char)( acc2 >> 24 );
266 mac[12] = (unsigned char)( acc3 );
267 mac[13] = (unsigned char)( acc3 >> 8 );
268 mac[14] = (unsigned char)( acc3 >> 16 );
269 mac[15] = (unsigned char)( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300270}
271
272void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
273{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200274 if( ctx != NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300275 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200276 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300277 }
278}
279
280void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
281{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200282 if( ctx != NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300283 {
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200284 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300285 }
286}
287
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200288int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300289 const unsigned char key[32] )
290{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200291 if( ctx == NULL || key == NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300292 {
293 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
294 }
295
296 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
297 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
298 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
299 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
300 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
301
302 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
303 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
304 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
305 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
306
307 /* Initial accumulator state */
308 ctx->acc[0] = 0U;
309 ctx->acc[1] = 0U;
310 ctx->acc[2] = 0U;
311 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200312 ctx->acc[4] = 0U;
313
314 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200315 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200316 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300317
Daniel Kinge6e79682016-05-24 11:16:17 -0300318 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300319}
320
321int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200322 const unsigned char *input,
323 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300324{
325 size_t offset = 0U;
326 size_t remaining = ilen;
327 size_t queue_free_len;
328 size_t nblocks;
329
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200330 if( ctx == NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300331 {
332 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
333 }
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200334 else if( ( ilen > 0U ) && ( input == NULL ) )
Daniel Kinga310c5e2016-05-17 15:56:26 -0300335 {
336 /* input pointer is allowed to be NULL only if ilen == 0 */
337 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
338 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300339
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200340 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300341 {
342 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
343
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200344 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300345 {
346 /* Not enough data to complete the block.
347 * Store this data with the other leftovers.
348 */
349 memcpy( &ctx->queue[ctx->queue_len],
350 input,
351 ilen );
352
353 ctx->queue_len += ilen;
354
355 remaining = 0U;
356 }
357 else
358 {
359 /* Enough data to produce a complete block */
360 memcpy( &ctx->queue[ctx->queue_len],
361 input,
362 queue_free_len );
363
364 ctx->queue_len = 0U;
365
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200366 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300367
368 offset += queue_free_len;
369 remaining -= queue_free_len;
370 }
371 }
372
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200373 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300374 {
375 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
376
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200377 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300378
379 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
380 remaining %= POLY1305_BLOCK_SIZE_BYTES;
381 }
382
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200383 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300384 {
385 /* Store partial block */
386 ctx->queue_len = remaining;
387 memcpy( ctx->queue, &input[offset], remaining );
388 }
389
390 return( 0 );
391}
392
393int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
394 unsigned char mac[16] )
395{
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200396 if( ( ctx == NULL ) || ( mac == NULL ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300397 {
398 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
399 }
400
401 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200402 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300403 {
404 /* Add padding bit */
405 ctx->queue[ctx->queue_len] = 1U;
406 ctx->queue_len++;
407
408 /* Pad with zeroes */
409 memset( &ctx->queue[ctx->queue_len],
410 0,
411 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
412
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200413 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200414 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300415 }
416
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200417 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300418
419 return( 0 );
420}
421
Daniel Kingadc32c02016-05-16 18:25:45 -0300422int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200423 const unsigned char *input,
424 size_t ilen,
425 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300426{
427 mbedtls_poly1305_context ctx;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200428 int ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300429
430 mbedtls_poly1305_init( &ctx );
431
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200432 ret = mbedtls_poly1305_starts( &ctx, key );
433 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300434 goto cleanup;
435
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200436 ret = mbedtls_poly1305_update( &ctx, input, ilen );
437 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300438 goto cleanup;
439
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200440 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300441
442cleanup:
443 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200444 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300445}
446
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200447#endif /* MBEDTLS_POLY1305_ALT */
448
Daniel Kingadc32c02016-05-16 18:25:45 -0300449#if defined(MBEDTLS_SELF_TEST)
450
451static const unsigned char test_keys[2][32] =
452{
453 {
454 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
455 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
456 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
457 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
458 },
459 {
460 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
461 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
462 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
463 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
464 }
465};
466
467static const unsigned char test_data[2][127] =
468{
469 {
470 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
471 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
472 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
473 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
474 0x75, 0x70
475 },
476 {
477 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
478 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
479 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
480 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
481 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
482 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
483 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
484 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
485 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
486 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
487 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
488 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
489 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
490 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
491 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
492 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
493 }
494};
495
496static const size_t test_data_len[2] =
497{
498 34U,
499 127U
500};
501
502static const unsigned char test_mac[2][16] =
503{
504 {
505 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
506 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
507 },
508 {
509 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
510 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
511 }
512};
513
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200514#define ASSERT( cond, args ) \
515 do \
516 { \
517 if( ! ( cond ) ) \
518 { \
519 if( verbose != 0 ) \
520 mbedtls_printf args; \
521 \
522 return( -1 ); \
523 } \
524 } \
525 while( 0 )
526
Daniel Kingadc32c02016-05-16 18:25:45 -0300527int mbedtls_poly1305_self_test( int verbose )
528{
Daniel Kinge6e79682016-05-24 11:16:17 -0300529 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200530 unsigned i;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200531 int ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300532
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200533 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300534 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200535 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200536 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300537
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200538 ret = mbedtls_poly1305_mac( test_keys[i],
539 test_data[i],
540 test_data_len[i],
541 mac );
542 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300543
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200544 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300545
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200546 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300547 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300548 }
549
550 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300551 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300552
553 return( 0 );
554}
555
556#endif /* MBEDTLS_SELF_TEST */
557
558#endif /* MBEDTLS_POLY1305_C */