blob: 9fc79a9cfe19127a111e763b8f28ed0c53e1d740 [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 */
Gilles Peskinedb09ef62020-06-03 01:43:33 +020023#include "common.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030024
25#if defined(MBEDTLS_POLY1305_C)
26
Daniel Kingadc32c02016-05-16 18:25:45 -030027#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020028#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000029#include "mbedtls/error.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030030
31#include <string.h>
32
33#if defined(MBEDTLS_SELF_TEST)
34#if defined(MBEDTLS_PLATFORM_C)
35#include "mbedtls/platform.h"
36#else
37#include <stdio.h>
38#define mbedtls_printf printf
39#endif /* MBEDTLS_PLATFORM_C */
40#endif /* MBEDTLS_SELF_TEST */
41
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020042#if !defined(MBEDTLS_POLY1305_ALT)
43
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020044#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
45 !defined(inline) && !defined(__cplusplus)
46#define inline __inline
47#endif
48
Hanno Becker305e4e42018-12-11 15:03:16 +000049/* Parameter validation macros */
50#define POLY1305_VALIDATE_RET( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
52#define POLY1305_VALIDATE( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE( cond )
54
Daniel Kingadc32c02016-05-16 18:25:45 -030055#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
56
Daniel Kinge6e79682016-05-24 11:16:17 -030057#define BYTES_TO_U32_LE( data, offset ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010058 ( (uint32_t) (data)[offset] \
59 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
60 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
61 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel Kingadc32c02016-05-16 18:25:45 -030062 )
63
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020064/*
65 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
66 * However we provided an alternative for platforms without such a multiplier.
67 */
68#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
69static uint64_t mul64( uint32_t a, uint32_t b )
70{
71 /* a = al + 2**16 ah, b = bl + 2**16 bh */
72 const uint16_t al = (uint16_t) a;
73 const uint16_t bl = (uint16_t) b;
74 const uint16_t ah = a >> 16;
75 const uint16_t bh = b >> 16;
76
77 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
78 const uint32_t lo = (uint32_t) al * bl;
79 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
80 const uint32_t hi = (uint32_t) ah * bh;
81
82 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
83}
84#else
85static inline uint64_t mul64( uint32_t a, uint32_t b )
86{
87 return( (uint64_t) a * b );
88}
89#endif
90
91
Daniel Kingadc32c02016-05-16 18:25:45 -030092/**
93 * \brief Process blocks with Poly1305.
94 *
95 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020096 * \param nblocks Number of blocks to process. Note that this
97 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030098 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020099 * \param needs_padding Set to 0 if the padding bit has already been
100 * applied to the input data before calling this
101 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -0300102 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200103static void poly1305_process( mbedtls_poly1305_context *ctx,
104 size_t nblocks,
105 const unsigned char *input,
106 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -0300107{
108 uint64_t d0, d1, d2, d3;
109 uint32_t acc0, acc1, acc2, acc3, acc4;
110 uint32_t r0, r1, r2, r3;
111 uint32_t rs1, rs2, rs3;
112 size_t offset = 0U;
113 size_t i;
114
115 r0 = ctx->r[0];
116 r1 = ctx->r[1];
117 r2 = ctx->r[2];
118 r3 = ctx->r[3];
119
120 rs1 = r1 + ( r1 >> 2U );
121 rs2 = r2 + ( r2 >> 2U );
122 rs3 = r3 + ( r3 >> 2U );
123
124 acc0 = ctx->acc[0];
125 acc1 = ctx->acc[1];
126 acc2 = ctx->acc[2];
127 acc3 = ctx->acc[3];
128 acc4 = ctx->acc[4];
129
130 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200131 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300132 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200133 /* The input block is treated as a 128-bit little-endian integer */
134 d0 = BYTES_TO_U32_LE( input, offset + 0 );
135 d1 = BYTES_TO_U32_LE( input, offset + 4 );
136 d2 = BYTES_TO_U32_LE( input, offset + 8 );
137 d3 = BYTES_TO_U32_LE( input, offset + 12 );
138
139 /* Compute: acc += (padded) block as a 130-bit integer */
140 d0 += (uint64_t) acc0;
141 d1 += (uint64_t) acc1 + ( d0 >> 32U );
142 d2 += (uint64_t) acc2 + ( d1 >> 32U );
143 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300144 acc0 = (uint32_t) d0;
145 acc1 = (uint32_t) d1;
146 acc2 = (uint32_t) d2;
147 acc3 = (uint32_t) d3;
148 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300149
150 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200151 d0 = mul64( acc0, r0 ) +
152 mul64( acc1, rs3 ) +
153 mul64( acc2, rs2 ) +
154 mul64( acc3, rs1 );
155 d1 = mul64( acc0, r1 ) +
156 mul64( acc1, r0 ) +
157 mul64( acc2, rs3 ) +
158 mul64( acc3, rs2 ) +
159 mul64( acc4, rs1 );
160 d2 = mul64( acc0, r2 ) +
161 mul64( acc1, r1 ) +
162 mul64( acc2, r0 ) +
163 mul64( acc3, rs3 ) +
164 mul64( acc4, rs2 );
165 d3 = mul64( acc0, r3 ) +
166 mul64( acc1, r2 ) +
167 mul64( acc2, r1 ) +
168 mul64( acc3, r0 ) +
169 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300170 acc4 *= r0;
171
172 /* Compute: acc %= (2^130 - 5) (partial remainder) */
173 d1 += ( d0 >> 32 );
174 d2 += ( d1 >> 32 );
175 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300176 acc0 = (uint32_t) d0;
177 acc1 = (uint32_t) d1;
178 acc2 = (uint32_t) d2;
179 acc3 = (uint32_t) d3;
180 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300181
Daniel Kinge6e79682016-05-24 11:16:17 -0300182 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300183 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300184 acc0 = (uint32_t) d0;
185 d0 = (uint64_t) acc1 + ( d0 >> 32U );
186 acc1 = (uint32_t) d0;
187 d0 = (uint64_t) acc2 + ( d0 >> 32U );
188 acc2 = (uint32_t) d0;
189 d0 = (uint64_t) acc3 + ( d0 >> 32U );
190 acc3 = (uint32_t) d0;
191 d0 = (uint64_t) acc4 + ( d0 >> 32U );
192 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300193
194 offset += POLY1305_BLOCK_SIZE_BYTES;
195 }
196
197 ctx->acc[0] = acc0;
198 ctx->acc[1] = acc1;
199 ctx->acc[2] = acc2;
200 ctx->acc[3] = acc3;
201 ctx->acc[4] = acc4;
202}
203
204/**
205 * \brief Compute the Poly1305 MAC
206 *
207 * \param ctx The Poly1305 context.
208 * \param mac The buffer to where the MAC is written. Must be
209 * big enough to contain the 16-byte MAC.
210 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200211static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
212 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300213{
214 uint64_t d;
215 uint32_t g0, g1, g2, g3, g4;
216 uint32_t acc0, acc1, acc2, acc3, acc4;
217 uint32_t mask;
218 uint32_t mask_inv;
219
220 acc0 = ctx->acc[0];
221 acc1 = ctx->acc[1];
222 acc2 = ctx->acc[2];
223 acc3 = ctx->acc[3];
224 acc4 = ctx->acc[4];
225
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200226 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300227 * We do this by calculating acc - (2^130 - 5), then checking if
228 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
229 */
230
231 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300232 d = ( (uint64_t) acc0 + 5U );
233 g0 = (uint32_t) d;
234 d = ( (uint64_t) acc1 + ( d >> 32 ) );
235 g1 = (uint32_t) d;
236 d = ( (uint64_t) acc2 + ( d >> 32 ) );
237 g2 = (uint32_t) d;
238 d = ( (uint64_t) acc3 + ( d >> 32 ) );
239 g3 = (uint32_t) d;
240 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300241
242 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300243 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300244 mask_inv = ~mask;
245
246 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
247 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
248 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
249 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
250 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
251
252 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300253 d = (uint64_t) acc0 + ctx->s[0];
254 acc0 = (uint32_t) d;
255 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
256 acc1 = (uint32_t) d;
257 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
258 acc2 = (uint32_t) d;
259 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300260
261 /* Compute MAC (128 least significant bits of the accumulator) */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200262 mac[ 0] = (unsigned char)( acc0 );
263 mac[ 1] = (unsigned char)( acc0 >> 8 );
264 mac[ 2] = (unsigned char)( acc0 >> 16 );
265 mac[ 3] = (unsigned char)( acc0 >> 24 );
266 mac[ 4] = (unsigned char)( acc1 );
267 mac[ 5] = (unsigned char)( acc1 >> 8 );
268 mac[ 6] = (unsigned char)( acc1 >> 16 );
269 mac[ 7] = (unsigned char)( acc1 >> 24 );
270 mac[ 8] = (unsigned char)( acc2 );
271 mac[ 9] = (unsigned char)( acc2 >> 8 );
272 mac[10] = (unsigned char)( acc2 >> 16 );
273 mac[11] = (unsigned char)( acc2 >> 24 );
274 mac[12] = (unsigned char)( acc3 );
275 mac[13] = (unsigned char)( acc3 >> 8 );
276 mac[14] = (unsigned char)( acc3 >> 16 );
277 mac[15] = (unsigned char)( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300278}
279
280void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
281{
Hanno Becker305e4e42018-12-11 15:03:16 +0000282 POLY1305_VALIDATE( ctx != NULL );
283
284 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300285}
286
287void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
288{
Hanno Becker236ea162018-12-12 14:00:34 +0000289 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000290 return;
291
292 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300293}
294
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200295int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300296 const unsigned char key[32] )
297{
Hanno Becker305e4e42018-12-11 15:03:16 +0000298 POLY1305_VALIDATE_RET( ctx != NULL );
299 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300300
301 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
302 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
303 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
304 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
305 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
306
307 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
308 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
309 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
310 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
311
312 /* Initial accumulator state */
313 ctx->acc[0] = 0U;
314 ctx->acc[1] = 0U;
315 ctx->acc[2] = 0U;
316 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200317 ctx->acc[4] = 0U;
318
319 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200320 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200321 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300322
Daniel Kinge6e79682016-05-24 11:16:17 -0300323 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300324}
325
326int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200327 const unsigned char *input,
328 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300329{
330 size_t offset = 0U;
331 size_t remaining = ilen;
332 size_t queue_free_len;
333 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000334 POLY1305_VALIDATE_RET( ctx != NULL );
335 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300336
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200337 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300338 {
339 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
340
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200341 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300342 {
343 /* Not enough data to complete the block.
344 * Store this data with the other leftovers.
345 */
346 memcpy( &ctx->queue[ctx->queue_len],
347 input,
348 ilen );
349
350 ctx->queue_len += ilen;
351
352 remaining = 0U;
353 }
354 else
355 {
356 /* Enough data to produce a complete block */
357 memcpy( &ctx->queue[ctx->queue_len],
358 input,
359 queue_free_len );
360
361 ctx->queue_len = 0U;
362
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200363 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300364
365 offset += queue_free_len;
366 remaining -= queue_free_len;
367 }
368 }
369
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200370 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300371 {
372 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
373
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200374 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300375
376 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
377 remaining %= POLY1305_BLOCK_SIZE_BYTES;
378 }
379
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200380 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300381 {
382 /* Store partial block */
383 ctx->queue_len = remaining;
384 memcpy( ctx->queue, &input[offset], remaining );
385 }
386
387 return( 0 );
388}
389
390int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
391 unsigned char mac[16] )
392{
Hanno Becker305e4e42018-12-11 15:03:16 +0000393 POLY1305_VALIDATE_RET( ctx != NULL );
394 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300395
396 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200397 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300398 {
399 /* Add padding bit */
400 ctx->queue[ctx->queue_len] = 1U;
401 ctx->queue_len++;
402
403 /* Pad with zeroes */
404 memset( &ctx->queue[ctx->queue_len],
405 0,
406 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
407
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200408 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200409 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300410 }
411
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200412 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300413
414 return( 0 );
415}
416
Daniel Kingadc32c02016-05-16 18:25:45 -0300417int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200418 const unsigned char *input,
419 size_t ilen,
420 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300421{
422 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000423 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000424 POLY1305_VALIDATE_RET( key != NULL );
425 POLY1305_VALIDATE_RET( mac != NULL );
426 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300427
428 mbedtls_poly1305_init( &ctx );
429
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200430 ret = mbedtls_poly1305_starts( &ctx, key );
431 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300432 goto cleanup;
433
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200434 ret = mbedtls_poly1305_update( &ctx, input, ilen );
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_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300439
440cleanup:
441 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200442 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300443}
444
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200445#endif /* MBEDTLS_POLY1305_ALT */
446
Daniel Kingadc32c02016-05-16 18:25:45 -0300447#if defined(MBEDTLS_SELF_TEST)
448
449static const unsigned char test_keys[2][32] =
450{
451 {
452 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
453 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
454 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
455 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
456 },
457 {
458 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
459 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
460 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
461 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
462 }
463};
464
465static const unsigned char test_data[2][127] =
466{
467 {
468 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
469 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
470 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
471 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
472 0x75, 0x70
473 },
474 {
475 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
476 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
477 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
478 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
479 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
480 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
481 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
482 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
483 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
484 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
485 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
486 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
487 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
488 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
489 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
490 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
491 }
492};
493
494static const size_t test_data_len[2] =
495{
496 34U,
497 127U
498};
499
500static const unsigned char test_mac[2][16] =
501{
502 {
503 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
504 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
505 },
506 {
507 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
508 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
509 }
510};
511
Ouss4e0b26872020-08-11 16:07:09 +0100512/* Make sure no other definition is already present. */
513#undef ASSERT
514
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200515#define ASSERT( cond, args ) \
516 do \
517 { \
518 if( ! ( cond ) ) \
519 { \
520 if( verbose != 0 ) \
521 mbedtls_printf args; \
522 \
523 return( -1 ); \
524 } \
525 } \
526 while( 0 )
527
Daniel Kingadc32c02016-05-16 18:25:45 -0300528int mbedtls_poly1305_self_test( int verbose )
529{
Daniel Kinge6e79682016-05-24 11:16:17 -0300530 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200531 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000532 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300533
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200534 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300535 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200536 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200537 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300538
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200539 ret = mbedtls_poly1305_mac( test_keys[i],
540 test_data[i],
541 test_data_len[i],
542 mac );
543 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300544
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200545 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300546
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200547 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300548 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300549 }
550
551 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300552 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300553
554 return( 0 );
555}
556
557#endif /* MBEDTLS_SELF_TEST */
558
559#endif /* MBEDTLS_POLY1305_C */