blob: a1c5b19d8e89e9b2233046d3df408e50fdd2cb15 [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
Hanno Becker305e4e42018-12-11 15:03:16 +000035/* Parameter validation macros */
36#define POLY1305_VALIDATE_RET( cond ) \
37 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
38#define POLY1305_VALIDATE( cond ) \
39 MBEDTLS_INTERNAL_VALIDATE( cond )
40
Daniel Kingadc32c02016-05-16 18:25:45 -030041#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
42
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020043/*
44 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
45 * However we provided an alternative for platforms without such a multiplier.
46 */
47#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
48static uint64_t mul64( uint32_t a, uint32_t b )
49{
50 /* a = al + 2**16 ah, b = bl + 2**16 bh */
51 const uint16_t al = (uint16_t) a;
Joe Subbiani197e9ed2021-07-16 17:47:17 +010052 const uint16_t bl = (uint16_t) b;
Joe Subbiani281956d2021-07-16 17:14:07 +010053 const uint16_t ah = a >> 16;
54 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020055
56 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
57 const uint32_t lo = (uint32_t) al * bl;
58 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
59 const uint32_t hi = (uint32_t) ah * bh;
60
61 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
62}
63#else
64static inline uint64_t mul64( uint32_t a, uint32_t b )
65{
66 return( (uint64_t) a * b );
67}
68#endif
69
70
Daniel Kingadc32c02016-05-16 18:25:45 -030071/**
72 * \brief Process blocks with Poly1305.
73 *
74 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020075 * \param nblocks Number of blocks to process. Note that this
76 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030077 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020078 * \param needs_padding Set to 0 if the padding bit has already been
79 * applied to the input data before calling this
80 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030081 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020082static void poly1305_process( mbedtls_poly1305_context *ctx,
83 size_t nblocks,
84 const unsigned char *input,
85 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030086{
87 uint64_t d0, d1, d2, d3;
88 uint32_t acc0, acc1, acc2, acc3, acc4;
89 uint32_t r0, r1, r2, r3;
90 uint32_t rs1, rs2, rs3;
91 size_t offset = 0U;
92 size_t i;
93
94 r0 = ctx->r[0];
95 r1 = ctx->r[1];
96 r2 = ctx->r[2];
97 r3 = ctx->r[3];
98
99 rs1 = r1 + ( r1 >> 2U );
100 rs2 = r2 + ( r2 >> 2U );
101 rs3 = r3 + ( r3 >> 2U );
102
103 acc0 = ctx->acc[0];
104 acc1 = ctx->acc[1];
105 acc2 = ctx->acc[2];
106 acc3 = ctx->acc[3];
107 acc4 = ctx->acc[4];
108
109 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200110 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300111 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200112 /* The input block is treated as a 128-bit little-endian integer */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100113 d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
114 d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
115 d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
116 d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200117
118 /* Compute: acc += (padded) block as a 130-bit integer */
119 d0 += (uint64_t) acc0;
120 d1 += (uint64_t) acc1 + ( d0 >> 32U );
121 d2 += (uint64_t) acc2 + ( d1 >> 32U );
122 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300123 acc0 = (uint32_t) d0;
124 acc1 = (uint32_t) d1;
125 acc2 = (uint32_t) d2;
126 acc3 = (uint32_t) d3;
127 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300128
129 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200130 d0 = mul64( acc0, r0 ) +
131 mul64( acc1, rs3 ) +
132 mul64( acc2, rs2 ) +
133 mul64( acc3, rs1 );
134 d1 = mul64( acc0, r1 ) +
135 mul64( acc1, r0 ) +
136 mul64( acc2, rs3 ) +
137 mul64( acc3, rs2 ) +
138 mul64( acc4, rs1 );
139 d2 = mul64( acc0, r2 ) +
140 mul64( acc1, r1 ) +
141 mul64( acc2, r0 ) +
142 mul64( acc3, rs3 ) +
143 mul64( acc4, rs2 );
144 d3 = mul64( acc0, r3 ) +
145 mul64( acc1, r2 ) +
146 mul64( acc2, r1 ) +
147 mul64( acc3, r0 ) +
148 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300149 acc4 *= r0;
150
151 /* Compute: acc %= (2^130 - 5) (partial remainder) */
152 d1 += ( d0 >> 32 );
153 d2 += ( d1 >> 32 );
154 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300155 acc0 = (uint32_t) d0;
156 acc1 = (uint32_t) d1;
157 acc2 = (uint32_t) d2;
158 acc3 = (uint32_t) d3;
159 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300160
Daniel Kinge6e79682016-05-24 11:16:17 -0300161 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300162 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300163 acc0 = (uint32_t) d0;
164 d0 = (uint64_t) acc1 + ( d0 >> 32U );
165 acc1 = (uint32_t) d0;
166 d0 = (uint64_t) acc2 + ( d0 >> 32U );
167 acc2 = (uint32_t) d0;
168 d0 = (uint64_t) acc3 + ( d0 >> 32U );
169 acc3 = (uint32_t) d0;
170 d0 = (uint64_t) acc4 + ( d0 >> 32U );
171 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300172
173 offset += POLY1305_BLOCK_SIZE_BYTES;
174 }
175
176 ctx->acc[0] = acc0;
177 ctx->acc[1] = acc1;
178 ctx->acc[2] = acc2;
179 ctx->acc[3] = acc3;
180 ctx->acc[4] = acc4;
181}
182
183/**
184 * \brief Compute the Poly1305 MAC
185 *
186 * \param ctx The Poly1305 context.
187 * \param mac The buffer to where the MAC is written. Must be
188 * big enough to contain the 16-byte MAC.
189 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200190static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
191 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300192{
193 uint64_t d;
194 uint32_t g0, g1, g2, g3, g4;
195 uint32_t acc0, acc1, acc2, acc3, acc4;
196 uint32_t mask;
197 uint32_t mask_inv;
198
199 acc0 = ctx->acc[0];
200 acc1 = ctx->acc[1];
201 acc2 = ctx->acc[2];
202 acc3 = ctx->acc[3];
203 acc4 = ctx->acc[4];
204
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200205 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300206 * We do this by calculating acc - (2^130 - 5), then checking if
207 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
208 */
209
210 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300211 d = ( (uint64_t) acc0 + 5U );
212 g0 = (uint32_t) d;
213 d = ( (uint64_t) acc1 + ( d >> 32 ) );
214 g1 = (uint32_t) d;
215 d = ( (uint64_t) acc2 + ( d >> 32 ) );
216 g2 = (uint32_t) d;
217 d = ( (uint64_t) acc3 + ( d >> 32 ) );
218 g3 = (uint32_t) d;
219 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300220
221 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300222 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300223 mask_inv = ~mask;
224
225 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
226 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
227 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
228 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
229 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
230
231 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300232 d = (uint64_t) acc0 + ctx->s[0];
233 acc0 = (uint32_t) d;
234 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
235 acc1 = (uint32_t) d;
236 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
237 acc2 = (uint32_t) d;
238 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300239
240 /* Compute MAC (128 least significant bits of the accumulator) */
Joe Subbianic54e9082021-07-19 11:56:54 +0100241 MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
242 MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
243 MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
244 MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300245}
246
247void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
248{
Hanno Becker305e4e42018-12-11 15:03:16 +0000249 POLY1305_VALIDATE( ctx != NULL );
250
251 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300252}
253
254void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
255{
Hanno Becker236ea162018-12-12 14:00:34 +0000256 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000257 return;
258
259 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300260}
261
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200262int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300263 const unsigned char key[32] )
264{
Hanno Becker305e4e42018-12-11 15:03:16 +0000265 POLY1305_VALIDATE_RET( ctx != NULL );
266 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300267
268 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100269 ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
270 ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
271 ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
272 ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300273
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100274 ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
275 ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
276 ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
277 ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300278
279 /* Initial accumulator state */
280 ctx->acc[0] = 0U;
281 ctx->acc[1] = 0U;
282 ctx->acc[2] = 0U;
283 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200284 ctx->acc[4] = 0U;
285
286 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200287 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200288 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300289
Daniel Kinge6e79682016-05-24 11:16:17 -0300290 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300291}
292
293int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200294 const unsigned char *input,
295 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300296{
297 size_t offset = 0U;
298 size_t remaining = ilen;
299 size_t queue_free_len;
300 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000301 POLY1305_VALIDATE_RET( ctx != NULL );
302 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300303
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200304 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300305 {
306 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
307
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200308 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300309 {
310 /* Not enough data to complete the block.
311 * Store this data with the other leftovers.
312 */
313 memcpy( &ctx->queue[ctx->queue_len],
314 input,
315 ilen );
316
317 ctx->queue_len += ilen;
318
319 remaining = 0U;
320 }
321 else
322 {
323 /* Enough data to produce a complete block */
324 memcpy( &ctx->queue[ctx->queue_len],
325 input,
326 queue_free_len );
327
328 ctx->queue_len = 0U;
329
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200330 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300331
332 offset += queue_free_len;
333 remaining -= queue_free_len;
334 }
335 }
336
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200337 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300338 {
339 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
340
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200341 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300342
343 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
344 remaining %= POLY1305_BLOCK_SIZE_BYTES;
345 }
346
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200347 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300348 {
349 /* Store partial block */
350 ctx->queue_len = remaining;
351 memcpy( ctx->queue, &input[offset], remaining );
352 }
353
354 return( 0 );
355}
356
357int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
358 unsigned char mac[16] )
359{
Hanno Becker305e4e42018-12-11 15:03:16 +0000360 POLY1305_VALIDATE_RET( ctx != NULL );
361 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300362
363 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200364 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300365 {
366 /* Add padding bit */
367 ctx->queue[ctx->queue_len] = 1U;
368 ctx->queue_len++;
369
370 /* Pad with zeroes */
371 memset( &ctx->queue[ctx->queue_len],
372 0,
373 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
374
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200375 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200376 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300377 }
378
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200379 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300380
381 return( 0 );
382}
383
Daniel Kingadc32c02016-05-16 18:25:45 -0300384int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200385 const unsigned char *input,
386 size_t ilen,
387 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300388{
389 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000390 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000391 POLY1305_VALIDATE_RET( key != NULL );
392 POLY1305_VALIDATE_RET( mac != NULL );
393 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300394
395 mbedtls_poly1305_init( &ctx );
396
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200397 ret = mbedtls_poly1305_starts( &ctx, key );
398 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300399 goto cleanup;
400
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200401 ret = mbedtls_poly1305_update( &ctx, input, ilen );
402 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300403 goto cleanup;
404
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200405 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300406
407cleanup:
408 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200409 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300410}
411
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200412#endif /* MBEDTLS_POLY1305_ALT */
413
Daniel Kingadc32c02016-05-16 18:25:45 -0300414#if defined(MBEDTLS_SELF_TEST)
415
416static const unsigned char test_keys[2][32] =
417{
418 {
419 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
420 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
421 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
422 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
423 },
424 {
425 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
426 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
427 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
428 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
429 }
430};
431
432static const unsigned char test_data[2][127] =
433{
434 {
435 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
436 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
437 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
438 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
439 0x75, 0x70
440 },
441 {
442 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
443 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
444 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
445 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
446 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
447 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
448 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
449 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
450 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
451 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
452 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
453 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
454 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
455 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
456 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
457 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
458 }
459};
460
461static const size_t test_data_len[2] =
462{
463 34U,
464 127U
465};
466
467static const unsigned char test_mac[2][16] =
468{
469 {
470 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
471 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
472 },
473 {
474 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
475 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
476 }
477};
478
Ouss4e0b26872020-08-11 16:07:09 +0100479/* Make sure no other definition is already present. */
480#undef ASSERT
481
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200482#define ASSERT( cond, args ) \
483 do \
484 { \
485 if( ! ( cond ) ) \
486 { \
487 if( verbose != 0 ) \
488 mbedtls_printf args; \
489 \
490 return( -1 ); \
491 } \
492 } \
493 while( 0 )
494
Daniel Kingadc32c02016-05-16 18:25:45 -0300495int mbedtls_poly1305_self_test( int verbose )
496{
Daniel Kinge6e79682016-05-24 11:16:17 -0300497 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200498 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000499 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300500
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200501 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300502 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200503 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200504 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300505
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200506 ret = mbedtls_poly1305_mac( test_keys[i],
507 test_data[i],
508 test_data_len[i],
509 mac );
510 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300511
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200512 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300513
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200514 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300515 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300516 }
517
518 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300519 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300520
521 return( 0 );
522}
523
524#endif /* MBEDTLS_SELF_TEST */
525
526#endif /* MBEDTLS_POLY1305_C */