blob: 0850f66a34d2aeb2550a1788a79d8ebab6148bd8 [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úti1e148272020-08-07 13:07:28 +02006 * Copyright The Mbed TLS Contributors
Daniel Kingadc32c02016-05-16 18:25:45 -03007 * 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.
Daniel Kingadc32c02016-05-16 18:25:45 -030020 */
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030022
23#if defined(MBEDTLS_POLY1305_C)
24
Daniel Kingadc32c02016-05-16 18:25:45 -030025#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020026#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000027#include "mbedtls/error.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030028
29#include <string.h>
30
Daniel Kingadc32c02016-05-16 18:25:45 -030031#include "mbedtls/platform.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030032
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020033#if !defined(MBEDTLS_POLY1305_ALT)
34
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020035#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
36 !defined(inline) && !defined(__cplusplus)
37#define inline __inline
38#endif
39
Daniel Kingadc32c02016-05-16 18:25:45 -030040#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
41
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020042/*
43 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
44 * However we provided an alternative for platforms without such a multiplier.
45 */
46#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
47static uint64_t mul64( uint32_t a, uint32_t b )
48{
49 /* a = al + 2**16 ah, b = bl + 2**16 bh */
50 const uint16_t al = (uint16_t) a;
Joe Subbiani51b147a2021-07-16 17:47:17 +010051 const uint16_t bl = (uint16_t) b;
Joe Subbiani4919bb42021-07-16 17:14:07 +010052 const uint16_t ah = a >> 16;
53 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020054
55 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
56 const uint32_t lo = (uint32_t) al * bl;
57 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
58 const uint32_t hi = (uint32_t) ah * bh;
59
60 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
61}
62#else
63static inline uint64_t mul64( uint32_t a, uint32_t b )
64{
65 return( (uint64_t) a * b );
66}
67#endif
68
69
Daniel Kingadc32c02016-05-16 18:25:45 -030070/**
71 * \brief Process blocks with Poly1305.
72 *
73 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020074 * \param nblocks Number of blocks to process. Note that this
75 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030076 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020077 * \param needs_padding Set to 0 if the padding bit has already been
78 * applied to the input data before calling this
79 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030080 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020081static void poly1305_process( mbedtls_poly1305_context *ctx,
82 size_t nblocks,
83 const unsigned char *input,
84 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030085{
86 uint64_t d0, d1, d2, d3;
87 uint32_t acc0, acc1, acc2, acc3, acc4;
88 uint32_t r0, r1, r2, r3;
89 uint32_t rs1, rs2, rs3;
90 size_t offset = 0U;
91 size_t i;
92
93 r0 = ctx->r[0];
94 r1 = ctx->r[1];
95 r2 = ctx->r[2];
96 r3 = ctx->r[3];
97
98 rs1 = r1 + ( r1 >> 2U );
99 rs2 = r2 + ( r2 >> 2U );
100 rs3 = r3 + ( r3 >> 2U );
101
102 acc0 = ctx->acc[0];
103 acc1 = ctx->acc[1];
104 acc2 = ctx->acc[2];
105 acc3 = ctx->acc[3];
106 acc4 = ctx->acc[4];
107
108 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200109 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300110 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200111 /* The input block is treated as a 128-bit little-endian integer */
Joe Subbiani6a506312021-07-07 16:56:29 +0100112 d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
113 d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
114 d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
115 d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200116
117 /* Compute: acc += (padded) block as a 130-bit integer */
118 d0 += (uint64_t) acc0;
119 d1 += (uint64_t) acc1 + ( d0 >> 32U );
120 d2 += (uint64_t) acc2 + ( d1 >> 32U );
121 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300122 acc0 = (uint32_t) d0;
123 acc1 = (uint32_t) d1;
124 acc2 = (uint32_t) d2;
125 acc3 = (uint32_t) d3;
126 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300127
128 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200129 d0 = mul64( acc0, r0 ) +
130 mul64( acc1, rs3 ) +
131 mul64( acc2, rs2 ) +
132 mul64( acc3, rs1 );
133 d1 = mul64( acc0, r1 ) +
134 mul64( acc1, r0 ) +
135 mul64( acc2, rs3 ) +
136 mul64( acc3, rs2 ) +
137 mul64( acc4, rs1 );
138 d2 = mul64( acc0, r2 ) +
139 mul64( acc1, r1 ) +
140 mul64( acc2, r0 ) +
141 mul64( acc3, rs3 ) +
142 mul64( acc4, rs2 );
143 d3 = mul64( acc0, r3 ) +
144 mul64( acc1, r2 ) +
145 mul64( acc2, r1 ) +
146 mul64( acc3, r0 ) +
147 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300148 acc4 *= r0;
149
150 /* Compute: acc %= (2^130 - 5) (partial remainder) */
151 d1 += ( d0 >> 32 );
152 d2 += ( d1 >> 32 );
153 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300154 acc0 = (uint32_t) d0;
155 acc1 = (uint32_t) d1;
156 acc2 = (uint32_t) d2;
157 acc3 = (uint32_t) d3;
158 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300159
Daniel Kinge6e79682016-05-24 11:16:17 -0300160 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300161 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300162 acc0 = (uint32_t) d0;
163 d0 = (uint64_t) acc1 + ( d0 >> 32U );
164 acc1 = (uint32_t) d0;
165 d0 = (uint64_t) acc2 + ( d0 >> 32U );
166 acc2 = (uint32_t) d0;
167 d0 = (uint64_t) acc3 + ( d0 >> 32U );
168 acc3 = (uint32_t) d0;
169 d0 = (uint64_t) acc4 + ( d0 >> 32U );
170 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300171
172 offset += POLY1305_BLOCK_SIZE_BYTES;
173 }
174
175 ctx->acc[0] = acc0;
176 ctx->acc[1] = acc1;
177 ctx->acc[2] = acc2;
178 ctx->acc[3] = acc3;
179 ctx->acc[4] = acc4;
180}
181
182/**
183 * \brief Compute the Poly1305 MAC
184 *
185 * \param ctx The Poly1305 context.
186 * \param mac The buffer to where the MAC is written. Must be
187 * big enough to contain the 16-byte MAC.
188 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200189static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
190 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300191{
192 uint64_t d;
193 uint32_t g0, g1, g2, g3, g4;
194 uint32_t acc0, acc1, acc2, acc3, acc4;
195 uint32_t mask;
196 uint32_t mask_inv;
197
198 acc0 = ctx->acc[0];
199 acc1 = ctx->acc[1];
200 acc2 = ctx->acc[2];
201 acc3 = ctx->acc[3];
202 acc4 = ctx->acc[4];
203
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200204 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300205 * We do this by calculating acc - (2^130 - 5), then checking if
206 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
207 */
208
209 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300210 d = ( (uint64_t) acc0 + 5U );
211 g0 = (uint32_t) d;
212 d = ( (uint64_t) acc1 + ( d >> 32 ) );
213 g1 = (uint32_t) d;
214 d = ( (uint64_t) acc2 + ( d >> 32 ) );
215 g2 = (uint32_t) d;
216 d = ( (uint64_t) acc3 + ( d >> 32 ) );
217 g3 = (uint32_t) d;
218 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300219
220 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300221 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300222 mask_inv = ~mask;
223
224 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
225 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
226 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
227 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
228 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
229
230 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300231 d = (uint64_t) acc0 + ctx->s[0];
232 acc0 = (uint32_t) d;
233 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
234 acc1 = (uint32_t) d;
235 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
236 acc2 = (uint32_t) d;
237 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300238
239 /* Compute MAC (128 least significant bits of the accumulator) */
Joe Subbiani6dd73642021-07-19 11:56:54 +0100240 MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
241 MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
242 MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
243 MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300244}
245
246void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
247{
Hanno Becker305e4e42018-12-11 15:03:16 +0000248 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300249}
250
251void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
252{
Hanno Becker236ea162018-12-12 14:00:34 +0000253 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000254 return;
255
256 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300257}
258
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200259int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300260 const unsigned char key[32] )
261{
Daniel Kingadc32c02016-05-16 18:25:45 -0300262 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Joe Subbiani6a506312021-07-07 16:56:29 +0100263 ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
264 ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
265 ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
266 ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300267
Joe Subbiani6a506312021-07-07 16:56:29 +0100268 ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
269 ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
270 ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
271 ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300272
273 /* Initial accumulator state */
274 ctx->acc[0] = 0U;
275 ctx->acc[1] = 0U;
276 ctx->acc[2] = 0U;
277 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200278 ctx->acc[4] = 0U;
279
280 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200281 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200282 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300283
Daniel Kinge6e79682016-05-24 11:16:17 -0300284 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300285}
286
287int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200288 const unsigned char *input,
289 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300290{
291 size_t offset = 0U;
292 size_t remaining = ilen;
293 size_t queue_free_len;
294 size_t nblocks;
Daniel Kingadc32c02016-05-16 18:25:45 -0300295
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200296 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300297 {
298 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
299
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200300 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300301 {
302 /* Not enough data to complete the block.
303 * Store this data with the other leftovers.
304 */
305 memcpy( &ctx->queue[ctx->queue_len],
306 input,
307 ilen );
308
309 ctx->queue_len += ilen;
310
311 remaining = 0U;
312 }
313 else
314 {
315 /* Enough data to produce a complete block */
316 memcpy( &ctx->queue[ctx->queue_len],
317 input,
318 queue_free_len );
319
320 ctx->queue_len = 0U;
321
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200322 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300323
324 offset += queue_free_len;
325 remaining -= queue_free_len;
326 }
327 }
328
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200329 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300330 {
331 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
332
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200333 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300334
335 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
336 remaining %= POLY1305_BLOCK_SIZE_BYTES;
337 }
338
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200339 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300340 {
341 /* Store partial block */
342 ctx->queue_len = remaining;
343 memcpy( ctx->queue, &input[offset], remaining );
344 }
345
346 return( 0 );
347}
348
349int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
350 unsigned char mac[16] )
351{
Daniel Kingadc32c02016-05-16 18:25:45 -0300352 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200353 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300354 {
355 /* Add padding bit */
356 ctx->queue[ctx->queue_len] = 1U;
357 ctx->queue_len++;
358
359 /* Pad with zeroes */
360 memset( &ctx->queue[ctx->queue_len],
361 0,
362 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
363
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200364 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200365 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300366 }
367
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200368 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300369
370 return( 0 );
371}
372
Daniel Kingadc32c02016-05-16 18:25:45 -0300373int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200374 const unsigned char *input,
375 size_t ilen,
376 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300377{
378 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000379 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300380
381 mbedtls_poly1305_init( &ctx );
382
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200383 ret = mbedtls_poly1305_starts( &ctx, key );
384 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300385 goto cleanup;
386
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200387 ret = mbedtls_poly1305_update( &ctx, input, ilen );
388 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300389 goto cleanup;
390
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200391 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300392
393cleanup:
394 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200395 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300396}
397
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200398#endif /* MBEDTLS_POLY1305_ALT */
399
Daniel Kingadc32c02016-05-16 18:25:45 -0300400#if defined(MBEDTLS_SELF_TEST)
401
402static const unsigned char test_keys[2][32] =
403{
404 {
405 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
406 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
407 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
408 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
409 },
410 {
411 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
412 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
413 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
414 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
415 }
416};
417
418static const unsigned char test_data[2][127] =
419{
420 {
421 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
422 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
423 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
424 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
425 0x75, 0x70
426 },
427 {
428 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
429 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
430 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
431 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
432 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
433 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
434 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
435 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
436 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
437 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
438 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
439 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
440 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
441 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
442 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
443 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
444 }
445};
446
447static const size_t test_data_len[2] =
448{
449 34U,
450 127U
451};
452
453static const unsigned char test_mac[2][16] =
454{
455 {
456 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
457 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
458 },
459 {
460 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
461 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
462 }
463};
464
Ouss4e0b26872020-08-11 16:07:09 +0100465/* Make sure no other definition is already present. */
466#undef ASSERT
467
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200468#define ASSERT( cond, args ) \
469 do \
470 { \
471 if( ! ( cond ) ) \
472 { \
473 if( verbose != 0 ) \
474 mbedtls_printf args; \
475 \
476 return( -1 ); \
477 } \
478 } \
479 while( 0 )
480
Daniel Kingadc32c02016-05-16 18:25:45 -0300481int mbedtls_poly1305_self_test( int verbose )
482{
Daniel Kinge6e79682016-05-24 11:16:17 -0300483 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200484 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300486
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200487 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300488 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200489 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200490 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300491
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200492 ret = mbedtls_poly1305_mac( test_keys[i],
493 test_data[i],
494 test_data_len[i],
495 mac );
496 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300497
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200498 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300499
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200500 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300501 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300502 }
503
504 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300505 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300506
507 return( 0 );
508}
509
510#endif /* MBEDTLS_SELF_TEST */
511
512#endif /* MBEDTLS_POLY1305_C */