blob: bc1e8a64967df013261e28b1f77cf8ab53a279a1 [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"
Janos Follath24eed8d2019-11-22 13:21:35 +000033#include "mbedtls/error.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030034
35#include <string.h>
36
37#if defined(MBEDTLS_SELF_TEST)
38#if defined(MBEDTLS_PLATFORM_C)
39#include "mbedtls/platform.h"
40#else
41#include <stdio.h>
42#define mbedtls_printf printf
43#endif /* MBEDTLS_PLATFORM_C */
44#endif /* MBEDTLS_SELF_TEST */
45
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020046#if !defined(MBEDTLS_POLY1305_ALT)
47
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020048#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
49 !defined(inline) && !defined(__cplusplus)
50#define inline __inline
51#endif
52
Hanno Becker305e4e42018-12-11 15:03:16 +000053/* Parameter validation macros */
54#define POLY1305_VALIDATE_RET( cond ) \
55 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
56#define POLY1305_VALIDATE( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE( cond )
58
Daniel Kingadc32c02016-05-16 18:25:45 -030059#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
60
Daniel Kinge6e79682016-05-24 11:16:17 -030061#define BYTES_TO_U32_LE( data, offset ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010062 ( (uint32_t) (data)[offset] \
63 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
64 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
65 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel Kingadc32c02016-05-16 18:25:45 -030066 )
67
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020068/*
69 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
70 * However we provided an alternative for platforms without such a multiplier.
71 */
72#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
73static uint64_t mul64( uint32_t a, uint32_t b )
74{
75 /* a = al + 2**16 ah, b = bl + 2**16 bh */
76 const uint16_t al = (uint16_t) a;
77 const uint16_t bl = (uint16_t) b;
78 const uint16_t ah = a >> 16;
79 const uint16_t bh = b >> 16;
80
81 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
82 const uint32_t lo = (uint32_t) al * bl;
83 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
84 const uint32_t hi = (uint32_t) ah * bh;
85
86 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
87}
88#else
89static inline uint64_t mul64( uint32_t a, uint32_t b )
90{
91 return( (uint64_t) a * b );
92}
93#endif
94
95
Daniel Kingadc32c02016-05-16 18:25:45 -030096/**
97 * \brief Process blocks with Poly1305.
98 *
99 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200100 * \param nblocks Number of blocks to process. Note that this
101 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -0300102 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200103 * \param needs_padding Set to 0 if the padding bit has already been
104 * applied to the input data before calling this
105 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -0300106 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200107static void poly1305_process( mbedtls_poly1305_context *ctx,
108 size_t nblocks,
109 const unsigned char *input,
110 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -0300111{
112 uint64_t d0, d1, d2, d3;
113 uint32_t acc0, acc1, acc2, acc3, acc4;
114 uint32_t r0, r1, r2, r3;
115 uint32_t rs1, rs2, rs3;
116 size_t offset = 0U;
117 size_t i;
118
119 r0 = ctx->r[0];
120 r1 = ctx->r[1];
121 r2 = ctx->r[2];
122 r3 = ctx->r[3];
123
124 rs1 = r1 + ( r1 >> 2U );
125 rs2 = r2 + ( r2 >> 2U );
126 rs3 = r3 + ( r3 >> 2U );
127
128 acc0 = ctx->acc[0];
129 acc1 = ctx->acc[1];
130 acc2 = ctx->acc[2];
131 acc3 = ctx->acc[3];
132 acc4 = ctx->acc[4];
133
134 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200135 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300136 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200137 /* The input block is treated as a 128-bit little-endian integer */
138 d0 = BYTES_TO_U32_LE( input, offset + 0 );
139 d1 = BYTES_TO_U32_LE( input, offset + 4 );
140 d2 = BYTES_TO_U32_LE( input, offset + 8 );
141 d3 = BYTES_TO_U32_LE( input, offset + 12 );
142
143 /* Compute: acc += (padded) block as a 130-bit integer */
144 d0 += (uint64_t) acc0;
145 d1 += (uint64_t) acc1 + ( d0 >> 32U );
146 d2 += (uint64_t) acc2 + ( d1 >> 32U );
147 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300148 acc0 = (uint32_t) d0;
149 acc1 = (uint32_t) d1;
150 acc2 = (uint32_t) d2;
151 acc3 = (uint32_t) d3;
152 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300153
154 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200155 d0 = mul64( acc0, r0 ) +
156 mul64( acc1, rs3 ) +
157 mul64( acc2, rs2 ) +
158 mul64( acc3, rs1 );
159 d1 = mul64( acc0, r1 ) +
160 mul64( acc1, r0 ) +
161 mul64( acc2, rs3 ) +
162 mul64( acc3, rs2 ) +
163 mul64( acc4, rs1 );
164 d2 = mul64( acc0, r2 ) +
165 mul64( acc1, r1 ) +
166 mul64( acc2, r0 ) +
167 mul64( acc3, rs3 ) +
168 mul64( acc4, rs2 );
169 d3 = mul64( acc0, r3 ) +
170 mul64( acc1, r2 ) +
171 mul64( acc2, r1 ) +
172 mul64( acc3, r0 ) +
173 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300174 acc4 *= r0;
175
176 /* Compute: acc %= (2^130 - 5) (partial remainder) */
177 d1 += ( d0 >> 32 );
178 d2 += ( d1 >> 32 );
179 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300180 acc0 = (uint32_t) d0;
181 acc1 = (uint32_t) d1;
182 acc2 = (uint32_t) d2;
183 acc3 = (uint32_t) d3;
184 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300185
Daniel Kinge6e79682016-05-24 11:16:17 -0300186 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300187 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300188 acc0 = (uint32_t) d0;
189 d0 = (uint64_t) acc1 + ( d0 >> 32U );
190 acc1 = (uint32_t) d0;
191 d0 = (uint64_t) acc2 + ( d0 >> 32U );
192 acc2 = (uint32_t) d0;
193 d0 = (uint64_t) acc3 + ( d0 >> 32U );
194 acc3 = (uint32_t) d0;
195 d0 = (uint64_t) acc4 + ( d0 >> 32U );
196 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300197
198 offset += POLY1305_BLOCK_SIZE_BYTES;
199 }
200
201 ctx->acc[0] = acc0;
202 ctx->acc[1] = acc1;
203 ctx->acc[2] = acc2;
204 ctx->acc[3] = acc3;
205 ctx->acc[4] = acc4;
206}
207
208/**
209 * \brief Compute the Poly1305 MAC
210 *
211 * \param ctx The Poly1305 context.
212 * \param mac The buffer to where the MAC is written. Must be
213 * big enough to contain the 16-byte MAC.
214 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200215static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
216 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300217{
218 uint64_t d;
219 uint32_t g0, g1, g2, g3, g4;
220 uint32_t acc0, acc1, acc2, acc3, acc4;
221 uint32_t mask;
222 uint32_t mask_inv;
223
224 acc0 = ctx->acc[0];
225 acc1 = ctx->acc[1];
226 acc2 = ctx->acc[2];
227 acc3 = ctx->acc[3];
228 acc4 = ctx->acc[4];
229
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200230 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300231 * We do this by calculating acc - (2^130 - 5), then checking if
232 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
233 */
234
235 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300236 d = ( (uint64_t) acc0 + 5U );
237 g0 = (uint32_t) d;
238 d = ( (uint64_t) acc1 + ( d >> 32 ) );
239 g1 = (uint32_t) d;
240 d = ( (uint64_t) acc2 + ( d >> 32 ) );
241 g2 = (uint32_t) d;
242 d = ( (uint64_t) acc3 + ( d >> 32 ) );
243 g3 = (uint32_t) d;
244 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300245
246 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300247 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300248 mask_inv = ~mask;
249
250 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
251 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
252 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
253 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
254 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
255
256 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300257 d = (uint64_t) acc0 + ctx->s[0];
258 acc0 = (uint32_t) d;
259 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
260 acc1 = (uint32_t) d;
261 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
262 acc2 = (uint32_t) d;
263 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300264
265 /* Compute MAC (128 least significant bits of the accumulator) */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200266 mac[ 0] = (unsigned char)( acc0 );
267 mac[ 1] = (unsigned char)( acc0 >> 8 );
268 mac[ 2] = (unsigned char)( acc0 >> 16 );
269 mac[ 3] = (unsigned char)( acc0 >> 24 );
270 mac[ 4] = (unsigned char)( acc1 );
271 mac[ 5] = (unsigned char)( acc1 >> 8 );
272 mac[ 6] = (unsigned char)( acc1 >> 16 );
273 mac[ 7] = (unsigned char)( acc1 >> 24 );
274 mac[ 8] = (unsigned char)( acc2 );
275 mac[ 9] = (unsigned char)( acc2 >> 8 );
276 mac[10] = (unsigned char)( acc2 >> 16 );
277 mac[11] = (unsigned char)( acc2 >> 24 );
278 mac[12] = (unsigned char)( acc3 );
279 mac[13] = (unsigned char)( acc3 >> 8 );
280 mac[14] = (unsigned char)( acc3 >> 16 );
281 mac[15] = (unsigned char)( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300282}
283
284void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
285{
Hanno Becker305e4e42018-12-11 15:03:16 +0000286 POLY1305_VALIDATE( ctx != NULL );
287
288 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300289}
290
291void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
292{
Hanno Becker236ea162018-12-12 14:00:34 +0000293 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000294 return;
295
296 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300297}
298
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200299int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300300 const unsigned char key[32] )
301{
Hanno Becker305e4e42018-12-11 15:03:16 +0000302 POLY1305_VALIDATE_RET( ctx != NULL );
303 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300304
305 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
306 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
307 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
308 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
309 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
310
311 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
312 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
313 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
314 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
315
316 /* Initial accumulator state */
317 ctx->acc[0] = 0U;
318 ctx->acc[1] = 0U;
319 ctx->acc[2] = 0U;
320 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200321 ctx->acc[4] = 0U;
322
323 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200324 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200325 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300326
Daniel Kinge6e79682016-05-24 11:16:17 -0300327 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300328}
329
330int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200331 const unsigned char *input,
332 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300333{
334 size_t offset = 0U;
335 size_t remaining = ilen;
336 size_t queue_free_len;
337 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000338 POLY1305_VALIDATE_RET( ctx != NULL );
339 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300340
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200341 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300342 {
343 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
344
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200345 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300346 {
347 /* Not enough data to complete the block.
348 * Store this data with the other leftovers.
349 */
350 memcpy( &ctx->queue[ctx->queue_len],
351 input,
352 ilen );
353
354 ctx->queue_len += ilen;
355
356 remaining = 0U;
357 }
358 else
359 {
360 /* Enough data to produce a complete block */
361 memcpy( &ctx->queue[ctx->queue_len],
362 input,
363 queue_free_len );
364
365 ctx->queue_len = 0U;
366
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200367 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300368
369 offset += queue_free_len;
370 remaining -= queue_free_len;
371 }
372 }
373
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200374 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300375 {
376 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
377
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200378 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300379
380 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
381 remaining %= POLY1305_BLOCK_SIZE_BYTES;
382 }
383
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200384 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300385 {
386 /* Store partial block */
387 ctx->queue_len = remaining;
388 memcpy( ctx->queue, &input[offset], remaining );
389 }
390
391 return( 0 );
392}
393
394int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
395 unsigned char mac[16] )
396{
Hanno Becker305e4e42018-12-11 15:03:16 +0000397 POLY1305_VALIDATE_RET( ctx != NULL );
398 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300399
400 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200401 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300402 {
403 /* Add padding bit */
404 ctx->queue[ctx->queue_len] = 1U;
405 ctx->queue_len++;
406
407 /* Pad with zeroes */
408 memset( &ctx->queue[ctx->queue_len],
409 0,
410 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
411
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200412 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200413 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300414 }
415
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200416 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300417
418 return( 0 );
419}
420
Daniel Kingadc32c02016-05-16 18:25:45 -0300421int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200422 const unsigned char *input,
423 size_t ilen,
424 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300425{
426 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000427 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000428 POLY1305_VALIDATE_RET( key != NULL );
429 POLY1305_VALIDATE_RET( mac != NULL );
430 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300431
432 mbedtls_poly1305_init( &ctx );
433
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200434 ret = mbedtls_poly1305_starts( &ctx, key );
435 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300436 goto cleanup;
437
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200438 ret = mbedtls_poly1305_update( &ctx, input, ilen );
439 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300440 goto cleanup;
441
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200442 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300443
444cleanup:
445 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200446 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300447}
448
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200449#endif /* MBEDTLS_POLY1305_ALT */
450
Daniel Kingadc32c02016-05-16 18:25:45 -0300451#if defined(MBEDTLS_SELF_TEST)
452
453static const unsigned char test_keys[2][32] =
454{
455 {
456 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
457 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
458 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
459 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
460 },
461 {
462 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
463 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
464 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
465 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
466 }
467};
468
469static const unsigned char test_data[2][127] =
470{
471 {
472 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
473 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
474 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
475 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
476 0x75, 0x70
477 },
478 {
479 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
480 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
481 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
482 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
483 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
484 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
485 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
486 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
487 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
488 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
489 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
490 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
491 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
492 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
493 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
494 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
495 }
496};
497
498static const size_t test_data_len[2] =
499{
500 34U,
501 127U
502};
503
504static const unsigned char test_mac[2][16] =
505{
506 {
507 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
508 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
509 },
510 {
511 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
512 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
513 }
514};
515
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200516#define ASSERT( cond, args ) \
517 do \
518 { \
519 if( ! ( cond ) ) \
520 { \
521 if( verbose != 0 ) \
522 mbedtls_printf args; \
523 \
524 return( -1 ); \
525 } \
526 } \
527 while( 0 )
528
Daniel Kingadc32c02016-05-16 18:25:45 -0300529int mbedtls_poly1305_self_test( int verbose )
530{
Daniel Kinge6e79682016-05-24 11:16:17 -0300531 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200532 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000533 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300534
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200535 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300536 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200537 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200538 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300539
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200540 ret = mbedtls_poly1305_mac( test_keys[i],
541 test_data[i],
542 test_data_len[i],
543 mac );
544 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300545
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200546 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300547
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200548 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300549 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300550 }
551
552 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300553 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300554
555 return( 0 );
556}
557
558#endif /* MBEDTLS_SELF_TEST */
559
560#endif /* MBEDTLS_POLY1305_C */