blob: 5b023f04e4a185b3676964068a7d8e1b65a92f16 [file] [log] [blame]
Daniel Kingadc32c02016-05-16 18:25:45 -03001/**
2 * \file poly1305.c
3 *
4 * \brief Poly1305 authentication algorithm.
5 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02006 * Copyright The Mbed TLS Contributors
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 * **********
Daniel Kingadc32c02016-05-16 18:25:45 -030047 */
48#if !defined(MBEDTLS_CONFIG_FILE)
49#include "mbedtls/config.h"
50#else
51#include MBEDTLS_CONFIG_FILE
52#endif
53
54#if defined(MBEDTLS_POLY1305_C)
55
Daniel Kingadc32c02016-05-16 18:25:45 -030056#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020057#include "mbedtls/platform_util.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030058
59#include <string.h>
60
61#if defined(MBEDTLS_SELF_TEST)
62#if defined(MBEDTLS_PLATFORM_C)
63#include "mbedtls/platform.h"
64#else
65#include <stdio.h>
66#define mbedtls_printf printf
67#endif /* MBEDTLS_PLATFORM_C */
68#endif /* MBEDTLS_SELF_TEST */
69
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020070#if !defined(MBEDTLS_POLY1305_ALT)
71
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020072#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
73 !defined(inline) && !defined(__cplusplus)
74#define inline __inline
75#endif
76
Hanno Becker305e4e42018-12-11 15:03:16 +000077/* Parameter validation macros */
78#define POLY1305_VALIDATE_RET( cond ) \
79 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
80#define POLY1305_VALIDATE( cond ) \
81 MBEDTLS_INTERNAL_VALIDATE( cond )
82
Daniel Kingadc32c02016-05-16 18:25:45 -030083#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
84
Daniel Kinge6e79682016-05-24 11:16:17 -030085#define BYTES_TO_U32_LE( data, offset ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010086 ( (uint32_t) (data)[offset] \
87 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
88 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
89 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
Daniel Kingadc32c02016-05-16 18:25:45 -030090 )
91
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020092/*
93 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
94 * However we provided an alternative for platforms without such a multiplier.
95 */
96#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
97static uint64_t mul64( uint32_t a, uint32_t b )
98{
99 /* a = al + 2**16 ah, b = bl + 2**16 bh */
100 const uint16_t al = (uint16_t) a;
101 const uint16_t bl = (uint16_t) b;
102 const uint16_t ah = a >> 16;
103 const uint16_t bh = b >> 16;
104
105 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
106 const uint32_t lo = (uint32_t) al * bl;
107 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
108 const uint32_t hi = (uint32_t) ah * bh;
109
110 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
111}
112#else
113static inline uint64_t mul64( uint32_t a, uint32_t b )
114{
115 return( (uint64_t) a * b );
116}
117#endif
118
119
Daniel Kingadc32c02016-05-16 18:25:45 -0300120/**
121 * \brief Process blocks with Poly1305.
122 *
123 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200124 * \param nblocks Number of blocks to process. Note that this
125 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -0300126 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200127 * \param needs_padding Set to 0 if the padding bit has already been
128 * applied to the input data before calling this
129 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -0300130 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200131static void poly1305_process( mbedtls_poly1305_context *ctx,
132 size_t nblocks,
133 const unsigned char *input,
134 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -0300135{
136 uint64_t d0, d1, d2, d3;
137 uint32_t acc0, acc1, acc2, acc3, acc4;
138 uint32_t r0, r1, r2, r3;
139 uint32_t rs1, rs2, rs3;
140 size_t offset = 0U;
141 size_t i;
142
143 r0 = ctx->r[0];
144 r1 = ctx->r[1];
145 r2 = ctx->r[2];
146 r3 = ctx->r[3];
147
148 rs1 = r1 + ( r1 >> 2U );
149 rs2 = r2 + ( r2 >> 2U );
150 rs3 = r3 + ( r3 >> 2U );
151
152 acc0 = ctx->acc[0];
153 acc1 = ctx->acc[1];
154 acc2 = ctx->acc[2];
155 acc3 = ctx->acc[3];
156 acc4 = ctx->acc[4];
157
158 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200159 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300160 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200161 /* The input block is treated as a 128-bit little-endian integer */
162 d0 = BYTES_TO_U32_LE( input, offset + 0 );
163 d1 = BYTES_TO_U32_LE( input, offset + 4 );
164 d2 = BYTES_TO_U32_LE( input, offset + 8 );
165 d3 = BYTES_TO_U32_LE( input, offset + 12 );
166
167 /* Compute: acc += (padded) block as a 130-bit integer */
168 d0 += (uint64_t) acc0;
169 d1 += (uint64_t) acc1 + ( d0 >> 32U );
170 d2 += (uint64_t) acc2 + ( d1 >> 32U );
171 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300172 acc0 = (uint32_t) d0;
173 acc1 = (uint32_t) d1;
174 acc2 = (uint32_t) d2;
175 acc3 = (uint32_t) d3;
176 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300177
178 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200179 d0 = mul64( acc0, r0 ) +
180 mul64( acc1, rs3 ) +
181 mul64( acc2, rs2 ) +
182 mul64( acc3, rs1 );
183 d1 = mul64( acc0, r1 ) +
184 mul64( acc1, r0 ) +
185 mul64( acc2, rs3 ) +
186 mul64( acc3, rs2 ) +
187 mul64( acc4, rs1 );
188 d2 = mul64( acc0, r2 ) +
189 mul64( acc1, r1 ) +
190 mul64( acc2, r0 ) +
191 mul64( acc3, rs3 ) +
192 mul64( acc4, rs2 );
193 d3 = mul64( acc0, r3 ) +
194 mul64( acc1, r2 ) +
195 mul64( acc2, r1 ) +
196 mul64( acc3, r0 ) +
197 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300198 acc4 *= r0;
199
200 /* Compute: acc %= (2^130 - 5) (partial remainder) */
201 d1 += ( d0 >> 32 );
202 d2 += ( d1 >> 32 );
203 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300204 acc0 = (uint32_t) d0;
205 acc1 = (uint32_t) d1;
206 acc2 = (uint32_t) d2;
207 acc3 = (uint32_t) d3;
208 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300209
Daniel Kinge6e79682016-05-24 11:16:17 -0300210 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300211 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300212 acc0 = (uint32_t) d0;
213 d0 = (uint64_t) acc1 + ( d0 >> 32U );
214 acc1 = (uint32_t) d0;
215 d0 = (uint64_t) acc2 + ( d0 >> 32U );
216 acc2 = (uint32_t) d0;
217 d0 = (uint64_t) acc3 + ( d0 >> 32U );
218 acc3 = (uint32_t) d0;
219 d0 = (uint64_t) acc4 + ( d0 >> 32U );
220 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300221
222 offset += POLY1305_BLOCK_SIZE_BYTES;
223 }
224
225 ctx->acc[0] = acc0;
226 ctx->acc[1] = acc1;
227 ctx->acc[2] = acc2;
228 ctx->acc[3] = acc3;
229 ctx->acc[4] = acc4;
230}
231
232/**
233 * \brief Compute the Poly1305 MAC
234 *
235 * \param ctx The Poly1305 context.
236 * \param mac The buffer to where the MAC is written. Must be
237 * big enough to contain the 16-byte MAC.
238 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200239static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
240 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300241{
242 uint64_t d;
243 uint32_t g0, g1, g2, g3, g4;
244 uint32_t acc0, acc1, acc2, acc3, acc4;
245 uint32_t mask;
246 uint32_t mask_inv;
247
248 acc0 = ctx->acc[0];
249 acc1 = ctx->acc[1];
250 acc2 = ctx->acc[2];
251 acc3 = ctx->acc[3];
252 acc4 = ctx->acc[4];
253
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200254 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300255 * We do this by calculating acc - (2^130 - 5), then checking if
256 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
257 */
258
259 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300260 d = ( (uint64_t) acc0 + 5U );
261 g0 = (uint32_t) d;
262 d = ( (uint64_t) acc1 + ( d >> 32 ) );
263 g1 = (uint32_t) d;
264 d = ( (uint64_t) acc2 + ( d >> 32 ) );
265 g2 = (uint32_t) d;
266 d = ( (uint64_t) acc3 + ( d >> 32 ) );
267 g3 = (uint32_t) d;
268 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300269
270 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300271 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300272 mask_inv = ~mask;
273
274 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
275 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
276 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
277 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
278 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
279
280 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300281 d = (uint64_t) acc0 + ctx->s[0];
282 acc0 = (uint32_t) d;
283 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
284 acc1 = (uint32_t) d;
285 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
286 acc2 = (uint32_t) d;
287 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300288
289 /* Compute MAC (128 least significant bits of the accumulator) */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200290 mac[ 0] = (unsigned char)( acc0 );
291 mac[ 1] = (unsigned char)( acc0 >> 8 );
292 mac[ 2] = (unsigned char)( acc0 >> 16 );
293 mac[ 3] = (unsigned char)( acc0 >> 24 );
294 mac[ 4] = (unsigned char)( acc1 );
295 mac[ 5] = (unsigned char)( acc1 >> 8 );
296 mac[ 6] = (unsigned char)( acc1 >> 16 );
297 mac[ 7] = (unsigned char)( acc1 >> 24 );
298 mac[ 8] = (unsigned char)( acc2 );
299 mac[ 9] = (unsigned char)( acc2 >> 8 );
300 mac[10] = (unsigned char)( acc2 >> 16 );
301 mac[11] = (unsigned char)( acc2 >> 24 );
302 mac[12] = (unsigned char)( acc3 );
303 mac[13] = (unsigned char)( acc3 >> 8 );
304 mac[14] = (unsigned char)( acc3 >> 16 );
305 mac[15] = (unsigned char)( acc3 >> 24 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300306}
307
308void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
309{
Hanno Becker305e4e42018-12-11 15:03:16 +0000310 POLY1305_VALIDATE( ctx != NULL );
311
312 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300313}
314
315void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
316{
Hanno Becker236ea162018-12-12 14:00:34 +0000317 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000318 return;
319
320 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300321}
322
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200323int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300324 const unsigned char key[32] )
325{
Hanno Becker305e4e42018-12-11 15:03:16 +0000326 POLY1305_VALIDATE_RET( ctx != NULL );
327 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300328
329 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
330 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
331 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
332 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
333 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
334
335 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
336 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
337 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
338 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
339
340 /* Initial accumulator state */
341 ctx->acc[0] = 0U;
342 ctx->acc[1] = 0U;
343 ctx->acc[2] = 0U;
344 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200345 ctx->acc[4] = 0U;
346
347 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200348 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200349 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300350
Daniel Kinge6e79682016-05-24 11:16:17 -0300351 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300352}
353
354int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200355 const unsigned char *input,
356 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300357{
358 size_t offset = 0U;
359 size_t remaining = ilen;
360 size_t queue_free_len;
361 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000362 POLY1305_VALIDATE_RET( ctx != NULL );
363 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300364
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200365 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300366 {
367 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
368
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200369 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300370 {
371 /* Not enough data to complete the block.
372 * Store this data with the other leftovers.
373 */
374 memcpy( &ctx->queue[ctx->queue_len],
375 input,
376 ilen );
377
378 ctx->queue_len += ilen;
379
380 remaining = 0U;
381 }
382 else
383 {
384 /* Enough data to produce a complete block */
385 memcpy( &ctx->queue[ctx->queue_len],
386 input,
387 queue_free_len );
388
389 ctx->queue_len = 0U;
390
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200391 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300392
393 offset += queue_free_len;
394 remaining -= queue_free_len;
395 }
396 }
397
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200398 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300399 {
400 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
401
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200402 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300403
404 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
405 remaining %= POLY1305_BLOCK_SIZE_BYTES;
406 }
407
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200408 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300409 {
410 /* Store partial block */
411 ctx->queue_len = remaining;
412 memcpy( ctx->queue, &input[offset], remaining );
413 }
414
415 return( 0 );
416}
417
418int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
419 unsigned char mac[16] )
420{
Hanno Becker305e4e42018-12-11 15:03:16 +0000421 POLY1305_VALIDATE_RET( ctx != NULL );
422 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300423
424 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200425 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300426 {
427 /* Add padding bit */
428 ctx->queue[ctx->queue_len] = 1U;
429 ctx->queue_len++;
430
431 /* Pad with zeroes */
432 memset( &ctx->queue[ctx->queue_len],
433 0,
434 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
435
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200436 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200437 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300438 }
439
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200440 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300441
442 return( 0 );
443}
444
Daniel Kingadc32c02016-05-16 18:25:45 -0300445int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200446 const unsigned char *input,
447 size_t ilen,
448 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300449{
450 mbedtls_poly1305_context ctx;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200451 int ret;
Hanno Becker305e4e42018-12-11 15:03:16 +0000452 POLY1305_VALIDATE_RET( key != NULL );
453 POLY1305_VALIDATE_RET( mac != NULL );
454 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300455
456 mbedtls_poly1305_init( &ctx );
457
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200458 ret = mbedtls_poly1305_starts( &ctx, key );
459 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300460 goto cleanup;
461
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200462 ret = mbedtls_poly1305_update( &ctx, input, ilen );
463 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300464 goto cleanup;
465
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200466 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300467
468cleanup:
469 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200470 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300471}
472
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200473#endif /* MBEDTLS_POLY1305_ALT */
474
Daniel Kingadc32c02016-05-16 18:25:45 -0300475#if defined(MBEDTLS_SELF_TEST)
476
477static const unsigned char test_keys[2][32] =
478{
479 {
480 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
481 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
482 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
483 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
484 },
485 {
486 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
487 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
488 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
489 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
490 }
491};
492
493static const unsigned char test_data[2][127] =
494{
495 {
496 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
497 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
498 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
499 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
500 0x75, 0x70
501 },
502 {
503 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
504 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
505 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
506 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
507 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
508 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
509 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
510 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
511 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
512 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
513 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
514 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
515 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
516 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
517 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
518 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
519 }
520};
521
522static const size_t test_data_len[2] =
523{
524 34U,
525 127U
526};
527
528static const unsigned char test_mac[2][16] =
529{
530 {
531 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
532 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
533 },
534 {
535 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
536 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
537 }
538};
539
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200540#define ASSERT( cond, args ) \
541 do \
542 { \
543 if( ! ( cond ) ) \
544 { \
545 if( verbose != 0 ) \
546 mbedtls_printf args; \
547 \
548 return( -1 ); \
549 } \
550 } \
551 while( 0 )
552
Daniel Kingadc32c02016-05-16 18:25:45 -0300553int mbedtls_poly1305_self_test( int verbose )
554{
Daniel Kinge6e79682016-05-24 11:16:17 -0300555 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200556 unsigned i;
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200557 int ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300558
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200559 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300560 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200561 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200562 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300563
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200564 ret = mbedtls_poly1305_mac( test_keys[i],
565 test_data[i],
566 test_data_len[i],
567 mac );
568 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300569
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200570 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300571
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200572 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300573 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300574 }
575
576 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300577 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300578
579 return( 0 );
580}
581
582#endif /* MBEDTLS_SELF_TEST */
583
584#endif /* MBEDTLS_POLY1305_C */