blob: 295997f2bc18e1ed7da897aa3e9fadd871847d57 [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
Bence Szépkútif744bd72020-06-05 13:02:18 +02007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8 *
9 * This file is provided under the Apache License 2.0, or the
10 * GNU General Public License v2.0 or later.
11 *
12 * **********
13 * Apache License 2.0:
Daniel Kingadc32c02016-05-16 18:25:45 -030014 *
15 * Licensed under the Apache License, Version 2.0 (the "License"); you may
16 * not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
23 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020027 * **********
28 *
29 * **********
30 * GNU General Public License v2.0 or later:
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License along
43 * with this program; if not, write to the Free Software Foundation, Inc.,
44 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
45 *
46 * **********
47 *
Daniel Kingadc32c02016-05-16 18:25:45 -030048 * This file is part of mbed TLS (https://tls.mbed.org)
49 */
50#if !defined(MBEDTLS_CONFIG_FILE)
51#include "mbedtls/config.h"
52#else
53#include MBEDTLS_CONFIG_FILE
54#endif
55
56#if defined(MBEDTLS_POLY1305_C)
57
Daniel Kingadc32c02016-05-16 18:25:45 -030058#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020059#include "mbedtls/platform_util.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030060
61#include <string.h>
62
63#if defined(MBEDTLS_SELF_TEST)
64#if defined(MBEDTLS_PLATFORM_C)
65#include "mbedtls/platform.h"
66#else
67#include <stdio.h>
68#define mbedtls_printf printf
69#endif /* MBEDTLS_PLATFORM_C */
70#endif /* MBEDTLS_SELF_TEST */
71
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020072#if !defined(MBEDTLS_POLY1305_ALT)
73
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020074#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
75 !defined(inline) && !defined(__cplusplus)
76#define inline __inline
77#endif
78
Hanno Becker305e4e42018-12-11 15:03:16 +000079/* Parameter validation macros */
80#define POLY1305_VALIDATE_RET( cond ) \
81 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
82#define POLY1305_VALIDATE( cond ) \
83 MBEDTLS_INTERNAL_VALIDATE( cond )
84
Daniel Kingadc32c02016-05-16 18:25:45 -030085#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
86
Daniel Kinge6e79682016-05-24 11:16:17 -030087#define BYTES_TO_U32_LE( data, offset ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010088 ( (uint32_t) (data)[offset] \
89 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
90 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
91 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel Kingadc32c02016-05-16 18:25:45 -030092 )
93
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020094/*
95 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
96 * However we provided an alternative for platforms without such a multiplier.
97 */
98#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
99static uint64_t mul64( uint32_t a, uint32_t b )
100{
101 /* a = al + 2**16 ah, b = bl + 2**16 bh */
102 const uint16_t al = (uint16_t) a;
103 const uint16_t bl = (uint16_t) b;
104 const uint16_t ah = a >> 16;
105 const uint16_t bh = b >> 16;
106
107 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
108 const uint32_t lo = (uint32_t) al * bl;
109 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
110 const uint32_t hi = (uint32_t) ah * bh;
111
112 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
113}
114#else
115static inline uint64_t mul64( uint32_t a, uint32_t b )
116{
117 return( (uint64_t) a * b );
118}
119#endif
120
121
Daniel Kingadc32c02016-05-16 18:25:45 -0300122/**
123 * \brief Process blocks with Poly1305.
124 *
125 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200126 * \param nblocks Number of blocks to process. Note that this
127 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -0300128 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200129 * \param needs_padding Set to 0 if the padding bit has already been
130 * applied to the input data before calling this
131 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -0300132 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200133static void poly1305_process( mbedtls_poly1305_context *ctx,
134 size_t nblocks,
135 const unsigned char *input,
136 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -0300137{
138 uint64_t d0, d1, d2, d3;
139 uint32_t acc0, acc1, acc2, acc3, acc4;
140 uint32_t r0, r1, r2, r3;
141 uint32_t rs1, rs2, rs3;
142 size_t offset = 0U;
143 size_t i;
144
145 r0 = ctx->r[0];
146 r1 = ctx->r[1];
147 r2 = ctx->r[2];
148 r3 = ctx->r[3];
149
150 rs1 = r1 + ( r1 >> 2U );
151 rs2 = r2 + ( r2 >> 2U );
152 rs3 = r3 + ( r3 >> 2U );
153
154 acc0 = ctx->acc[0];
155 acc1 = ctx->acc[1];
156 acc2 = ctx->acc[2];
157 acc3 = ctx->acc[3];
158 acc4 = ctx->acc[4];
159
160 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200161 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300162 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200163 /* The input block is treated as a 128-bit little-endian integer */
164 d0 = BYTES_TO_U32_LE( input, offset + 0 );
165 d1 = BYTES_TO_U32_LE( input, offset + 4 );
166 d2 = BYTES_TO_U32_LE( input, offset + 8 );
167 d3 = BYTES_TO_U32_LE( input, offset + 12 );
168
169 /* Compute: acc += (padded) block as a 130-bit integer */
170 d0 += (uint64_t) acc0;
171 d1 += (uint64_t) acc1 + ( d0 >> 32U );
172 d2 += (uint64_t) acc2 + ( d1 >> 32U );
173 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300174 acc0 = (uint32_t) d0;
175 acc1 = (uint32_t) d1;
176 acc2 = (uint32_t) d2;
177 acc3 = (uint32_t) d3;
178 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300179
180 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200181 d0 = mul64( acc0, r0 ) +
182 mul64( acc1, rs3 ) +
183 mul64( acc2, rs2 ) +
184 mul64( acc3, rs1 );
185 d1 = mul64( acc0, r1 ) +
186 mul64( acc1, r0 ) +
187 mul64( acc2, rs3 ) +
188 mul64( acc3, rs2 ) +
189 mul64( acc4, rs1 );
190 d2 = mul64( acc0, r2 ) +
191 mul64( acc1, r1 ) +
192 mul64( acc2, r0 ) +
193 mul64( acc3, rs3 ) +
194 mul64( acc4, rs2 );
195 d3 = mul64( acc0, r3 ) +
196 mul64( acc1, r2 ) +
197 mul64( acc2, r1 ) +
198 mul64( acc3, r0 ) +
199 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300200 acc4 *= r0;
201
202 /* Compute: acc %= (2^130 - 5) (partial remainder) */
203 d1 += ( d0 >> 32 );
204 d2 += ( d1 >> 32 );
205 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300206 acc0 = (uint32_t) d0;
207 acc1 = (uint32_t) d1;
208 acc2 = (uint32_t) d2;
209 acc3 = (uint32_t) d3;
210 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300211
Daniel Kinge6e79682016-05-24 11:16:17 -0300212 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300213 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300214 acc0 = (uint32_t) d0;
215 d0 = (uint64_t) acc1 + ( d0 >> 32U );
216 acc1 = (uint32_t) d0;
217 d0 = (uint64_t) acc2 + ( d0 >> 32U );
218 acc2 = (uint32_t) d0;
219 d0 = (uint64_t) acc3 + ( d0 >> 32U );
220 acc3 = (uint32_t) d0;
221 d0 = (uint64_t) acc4 + ( d0 >> 32U );
222 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300223
224 offset += POLY1305_BLOCK_SIZE_BYTES;
225 }
226
227 ctx->acc[0] = acc0;
228 ctx->acc[1] = acc1;
229 ctx->acc[2] = acc2;
230 ctx->acc[3] = acc3;
231 ctx->acc[4] = acc4;
232}
233
234/**
235 * \brief Compute the Poly1305 MAC
236 *
237 * \param ctx The Poly1305 context.
238 * \param mac The buffer to where the MAC is written. Must be
239 * big enough to contain the 16-byte MAC.
240 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200241static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
242 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300243{
244 uint64_t d;
245 uint32_t g0, g1, g2, g3, g4;
246 uint32_t acc0, acc1, acc2, acc3, acc4;
247 uint32_t mask;
248 uint32_t mask_inv;
249
250 acc0 = ctx->acc[0];
251 acc1 = ctx->acc[1];
252 acc2 = ctx->acc[2];
253 acc3 = ctx->acc[3];
254 acc4 = ctx->acc[4];
255
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200256 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300257 * We do this by calculating acc - (2^130 - 5), then checking if
258 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
259 */
260
261 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300262 d = ( (uint64_t) acc0 + 5U );
263 g0 = (uint32_t) d;
264 d = ( (uint64_t) acc1 + ( d >> 32 ) );
265 g1 = (uint32_t) d;
266 d = ( (uint64_t) acc2 + ( d >> 32 ) );
267 g2 = (uint32_t) d;
268 d = ( (uint64_t) acc3 + ( d >> 32 ) );
269 g3 = (uint32_t) d;
270 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300271
272 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300273 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300274 mask_inv = ~mask;
275
276 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
277 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
278 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
279 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
280 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
281
282 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300283 d = (uint64_t) acc0 + ctx->s[0];
284 acc0 = (uint32_t) d;
285 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
286 acc1 = (uint32_t) d;
287 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
288 acc2 = (uint32_t) d;
289 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300290
291 /* Compute MAC (128 least significant bits of the accumulator) */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200292 mac[ 0] = (unsigned char)( acc0 );
293 mac[ 1] = (unsigned char)( acc0 >> 8 );
294 mac[ 2] = (unsigned char)( acc0 >> 16 );
295 mac[ 3] = (unsigned char)( acc0 >> 24 );
296 mac[ 4] = (unsigned char)( acc1 );
297 mac[ 5] = (unsigned char)( acc1 >> 8 );
298 mac[ 6] = (unsigned char)( acc1 >> 16 );
299 mac[ 7] = (unsigned char)( acc1 >> 24 );
300 mac[ 8] = (unsigned char)( acc2 );
301 mac[ 9] = (unsigned char)( acc2 >> 8 );
302 mac[10] = (unsigned char)( acc2 >> 16 );
303 mac[11] = (unsigned char)( acc2 >> 24 );
304 mac[12] = (unsigned char)( acc3 );
305 mac[13] = (unsigned char)( acc3 >> 8 );
306 mac[14] = (unsigned char)( acc3 >> 16 );
307 mac[15] = (unsigned char)( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300308}
309
310void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
311{
Hanno Becker305e4e42018-12-11 15:03:16 +0000312 POLY1305_VALIDATE( ctx != NULL );
313
314 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300315}
316
317void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
318{
Hanno Becker236ea162018-12-12 14:00:34 +0000319 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000320 return;
321
322 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300323}
324
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200325int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300326 const unsigned char key[32] )
327{
Hanno Becker305e4e42018-12-11 15:03:16 +0000328 POLY1305_VALIDATE_RET( ctx != NULL );
329 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300330
331 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
332 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
333 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
334 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
335 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
336
337 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
338 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
339 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
340 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
341
342 /* Initial accumulator state */
343 ctx->acc[0] = 0U;
344 ctx->acc[1] = 0U;
345 ctx->acc[2] = 0U;
346 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200347 ctx->acc[4] = 0U;
348
349 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200350 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200351 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300352
Daniel Kinge6e79682016-05-24 11:16:17 -0300353 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300354}
355
356int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200357 const unsigned char *input,
358 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300359{
360 size_t offset = 0U;
361 size_t remaining = ilen;
362 size_t queue_free_len;
363 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000364 POLY1305_VALIDATE_RET( ctx != NULL );
365 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300366
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200367 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300368 {
369 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
370
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200371 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300372 {
373 /* Not enough data to complete the block.
374 * Store this data with the other leftovers.
375 */
376 memcpy( &ctx->queue[ctx->queue_len],
377 input,
378 ilen );
379
380 ctx->queue_len += ilen;
381
382 remaining = 0U;
383 }
384 else
385 {
386 /* Enough data to produce a complete block */
387 memcpy( &ctx->queue[ctx->queue_len],
388 input,
389 queue_free_len );
390
391 ctx->queue_len = 0U;
392
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200393 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300394
395 offset += queue_free_len;
396 remaining -= queue_free_len;
397 }
398 }
399
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200400 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300401 {
402 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
403
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200404 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300405
406 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
407 remaining %= POLY1305_BLOCK_SIZE_BYTES;
408 }
409
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200410 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300411 {
412 /* Store partial block */
413 ctx->queue_len = remaining;
414 memcpy( ctx->queue, &input[offset], remaining );
415 }
416
417 return( 0 );
418}
419
420int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
421 unsigned char mac[16] )
422{
Hanno Becker305e4e42018-12-11 15:03:16 +0000423 POLY1305_VALIDATE_RET( ctx != NULL );
424 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300425
426 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200427 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300428 {
429 /* Add padding bit */
430 ctx->queue[ctx->queue_len] = 1U;
431 ctx->queue_len++;
432
433 /* Pad with zeroes */
434 memset( &ctx->queue[ctx->queue_len],
435 0,
436 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
437
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200438 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200439 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300440 }
441
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200442 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300443
444 return( 0 );
445}
446
Daniel Kingadc32c02016-05-16 18:25:45 -0300447int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200448 const unsigned char *input,
449 size_t ilen,
450 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300451{
452 mbedtls_poly1305_context ctx;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200453 int ret;
Hanno Becker305e4e42018-12-11 15:03:16 +0000454 POLY1305_VALIDATE_RET( key != NULL );
455 POLY1305_VALIDATE_RET( mac != NULL );
456 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300457
458 mbedtls_poly1305_init( &ctx );
459
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200460 ret = mbedtls_poly1305_starts( &ctx, key );
461 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300462 goto cleanup;
463
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200464 ret = mbedtls_poly1305_update( &ctx, input, ilen );
465 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300466 goto cleanup;
467
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200468 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300469
470cleanup:
471 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200472 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300473}
474
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200475#endif /* MBEDTLS_POLY1305_ALT */
476
Daniel Kingadc32c02016-05-16 18:25:45 -0300477#if defined(MBEDTLS_SELF_TEST)
478
479static const unsigned char test_keys[2][32] =
480{
481 {
482 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
483 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
484 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
485 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
486 },
487 {
488 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
489 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
490 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
491 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
492 }
493};
494
495static const unsigned char test_data[2][127] =
496{
497 {
498 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
499 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
500 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
501 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
502 0x75, 0x70
503 },
504 {
505 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
506 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
507 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
508 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
509 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
510 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
511 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
512 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
513 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
514 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
515 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
516 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
517 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
518 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
519 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
520 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
521 }
522};
523
524static const size_t test_data_len[2] =
525{
526 34U,
527 127U
528};
529
530static const unsigned char test_mac[2][16] =
531{
532 {
533 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
534 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
535 },
536 {
537 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
538 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
539 }
540};
541
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200542#define ASSERT( cond, args ) \
543 do \
544 { \
545 if( ! ( cond ) ) \
546 { \
547 if( verbose != 0 ) \
548 mbedtls_printf args; \
549 \
550 return( -1 ); \
551 } \
552 } \
553 while( 0 )
554
Daniel Kingadc32c02016-05-16 18:25:45 -0300555int mbedtls_poly1305_self_test( int verbose )
556{
Daniel Kinge6e79682016-05-24 11:16:17 -0300557 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200558 unsigned i;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200559 int ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300560
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200561 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300562 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200563 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200564 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300565
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200566 ret = mbedtls_poly1305_mac( test_keys[i],
567 test_data[i],
568 test_data_len[i],
569 mac );
570 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300571
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200572 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300573
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200574 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300575 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300576 }
577
578 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300579 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300580
581 return( 0 );
582}
583
584#endif /* MBEDTLS_SELF_TEST */
585
586#endif /* MBEDTLS_POLY1305_C */