blob: a2b223303db9d5ab5b6deb7f81bf02fa14bb9fc8 [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
31#if defined(MBEDTLS_SELF_TEST)
Daniel Kingadc32c02016-05-16 18:25:45 -030032#include "mbedtls/platform.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030033#endif /* MBEDTLS_SELF_TEST */
34
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020035#if !defined(MBEDTLS_POLY1305_ALT)
36
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020037#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
38 !defined(inline) && !defined(__cplusplus)
39#define inline __inline
40#endif
41
Hanno Becker305e4e42018-12-11 15:03:16 +000042/* Parameter validation macros */
43#define POLY1305_VALIDATE_RET( cond ) \
44 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
45#define POLY1305_VALIDATE( cond ) \
46 MBEDTLS_INTERNAL_VALIDATE( cond )
47
Daniel Kingadc32c02016-05-16 18:25:45 -030048#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
49
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020050/*
51 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
52 * However we provided an alternative for platforms without such a multiplier.
53 */
54#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
55static uint64_t mul64( uint32_t a, uint32_t b )
56{
57 /* a = al + 2**16 ah, b = bl + 2**16 bh */
58 const uint16_t al = (uint16_t) a;
Joe Subbiani197e9ed2021-07-16 17:47:17 +010059 const uint16_t bl = (uint16_t) b;
Joe Subbiani281956d2021-07-16 17:14:07 +010060 const uint16_t ah = a >> 16;
61 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020062
63 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
64 const uint32_t lo = (uint32_t) al * bl;
65 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
66 const uint32_t hi = (uint32_t) ah * bh;
67
68 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
69}
70#else
71static inline uint64_t mul64( uint32_t a, uint32_t b )
72{
73 return( (uint64_t) a * b );
74}
75#endif
76
77
Daniel Kingadc32c02016-05-16 18:25:45 -030078/**
79 * \brief Process blocks with Poly1305.
80 *
81 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020082 * \param nblocks Number of blocks to process. Note that this
83 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030084 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020085 * \param needs_padding Set to 0 if the padding bit has already been
86 * applied to the input data before calling this
87 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030088 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020089static void poly1305_process( mbedtls_poly1305_context *ctx,
90 size_t nblocks,
91 const unsigned char *input,
92 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030093{
94 uint64_t d0, d1, d2, d3;
95 uint32_t acc0, acc1, acc2, acc3, acc4;
96 uint32_t r0, r1, r2, r3;
97 uint32_t rs1, rs2, rs3;
98 size_t offset = 0U;
99 size_t i;
100
101 r0 = ctx->r[0];
102 r1 = ctx->r[1];
103 r2 = ctx->r[2];
104 r3 = ctx->r[3];
105
106 rs1 = r1 + ( r1 >> 2U );
107 rs2 = r2 + ( r2 >> 2U );
108 rs3 = r3 + ( r3 >> 2U );
109
110 acc0 = ctx->acc[0];
111 acc1 = ctx->acc[1];
112 acc2 = ctx->acc[2];
113 acc3 = ctx->acc[3];
114 acc4 = ctx->acc[4];
115
116 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200117 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300118 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200119 /* The input block is treated as a 128-bit little-endian integer */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100120 d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
121 d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
122 d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
123 d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200124
125 /* Compute: acc += (padded) block as a 130-bit integer */
126 d0 += (uint64_t) acc0;
127 d1 += (uint64_t) acc1 + ( d0 >> 32U );
128 d2 += (uint64_t) acc2 + ( d1 >> 32U );
129 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300130 acc0 = (uint32_t) d0;
131 acc1 = (uint32_t) d1;
132 acc2 = (uint32_t) d2;
133 acc3 = (uint32_t) d3;
134 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300135
136 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200137 d0 = mul64( acc0, r0 ) +
138 mul64( acc1, rs3 ) +
139 mul64( acc2, rs2 ) +
140 mul64( acc3, rs1 );
141 d1 = mul64( acc0, r1 ) +
142 mul64( acc1, r0 ) +
143 mul64( acc2, rs3 ) +
144 mul64( acc3, rs2 ) +
145 mul64( acc4, rs1 );
146 d2 = mul64( acc0, r2 ) +
147 mul64( acc1, r1 ) +
148 mul64( acc2, r0 ) +
149 mul64( acc3, rs3 ) +
150 mul64( acc4, rs2 );
151 d3 = mul64( acc0, r3 ) +
152 mul64( acc1, r2 ) +
153 mul64( acc2, r1 ) +
154 mul64( acc3, r0 ) +
155 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300156 acc4 *= r0;
157
158 /* Compute: acc %= (2^130 - 5) (partial remainder) */
159 d1 += ( d0 >> 32 );
160 d2 += ( d1 >> 32 );
161 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300162 acc0 = (uint32_t) d0;
163 acc1 = (uint32_t) d1;
164 acc2 = (uint32_t) d2;
165 acc3 = (uint32_t) d3;
166 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300167
Daniel Kinge6e79682016-05-24 11:16:17 -0300168 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300169 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300170 acc0 = (uint32_t) d0;
171 d0 = (uint64_t) acc1 + ( d0 >> 32U );
172 acc1 = (uint32_t) d0;
173 d0 = (uint64_t) acc2 + ( d0 >> 32U );
174 acc2 = (uint32_t) d0;
175 d0 = (uint64_t) acc3 + ( d0 >> 32U );
176 acc3 = (uint32_t) d0;
177 d0 = (uint64_t) acc4 + ( d0 >> 32U );
178 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300179
180 offset += POLY1305_BLOCK_SIZE_BYTES;
181 }
182
183 ctx->acc[0] = acc0;
184 ctx->acc[1] = acc1;
185 ctx->acc[2] = acc2;
186 ctx->acc[3] = acc3;
187 ctx->acc[4] = acc4;
188}
189
190/**
191 * \brief Compute the Poly1305 MAC
192 *
193 * \param ctx The Poly1305 context.
194 * \param mac The buffer to where the MAC is written. Must be
195 * big enough to contain the 16-byte MAC.
196 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200197static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
198 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300199{
200 uint64_t d;
201 uint32_t g0, g1, g2, g3, g4;
202 uint32_t acc0, acc1, acc2, acc3, acc4;
203 uint32_t mask;
204 uint32_t mask_inv;
205
206 acc0 = ctx->acc[0];
207 acc1 = ctx->acc[1];
208 acc2 = ctx->acc[2];
209 acc3 = ctx->acc[3];
210 acc4 = ctx->acc[4];
211
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200212 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300213 * We do this by calculating acc - (2^130 - 5), then checking if
214 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
215 */
216
217 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300218 d = ( (uint64_t) acc0 + 5U );
219 g0 = (uint32_t) d;
220 d = ( (uint64_t) acc1 + ( d >> 32 ) );
221 g1 = (uint32_t) d;
222 d = ( (uint64_t) acc2 + ( d >> 32 ) );
223 g2 = (uint32_t) d;
224 d = ( (uint64_t) acc3 + ( d >> 32 ) );
225 g3 = (uint32_t) d;
226 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300227
228 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300229 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300230 mask_inv = ~mask;
231
232 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
233 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
234 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
235 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
236 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
237
238 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300239 d = (uint64_t) acc0 + ctx->s[0];
240 acc0 = (uint32_t) d;
241 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
242 acc1 = (uint32_t) d;
243 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
244 acc2 = (uint32_t) d;
245 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300246
247 /* Compute MAC (128 least significant bits of the accumulator) */
Joe Subbianic54e9082021-07-19 11:56:54 +0100248 MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
249 MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
250 MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
251 MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300252}
253
254void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
255{
Hanno Becker305e4e42018-12-11 15:03:16 +0000256 POLY1305_VALIDATE( ctx != NULL );
257
258 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300259}
260
261void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
262{
Hanno Becker236ea162018-12-12 14:00:34 +0000263 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000264 return;
265
266 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300267}
268
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200269int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300270 const unsigned char key[32] )
271{
Hanno Becker305e4e42018-12-11 15:03:16 +0000272 POLY1305_VALIDATE_RET( ctx != NULL );
273 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300274
275 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100276 ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
277 ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
278 ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
279 ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300280
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100281 ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
282 ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
283 ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
284 ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300285
286 /* Initial accumulator state */
287 ctx->acc[0] = 0U;
288 ctx->acc[1] = 0U;
289 ctx->acc[2] = 0U;
290 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200291 ctx->acc[4] = 0U;
292
293 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200294 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200295 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300296
Daniel Kinge6e79682016-05-24 11:16:17 -0300297 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300298}
299
300int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200301 const unsigned char *input,
302 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300303{
304 size_t offset = 0U;
305 size_t remaining = ilen;
306 size_t queue_free_len;
307 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000308 POLY1305_VALIDATE_RET( ctx != NULL );
309 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300310
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200311 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300312 {
313 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
314
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200315 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300316 {
317 /* Not enough data to complete the block.
318 * Store this data with the other leftovers.
319 */
320 memcpy( &ctx->queue[ctx->queue_len],
321 input,
322 ilen );
323
324 ctx->queue_len += ilen;
325
326 remaining = 0U;
327 }
328 else
329 {
330 /* Enough data to produce a complete block */
331 memcpy( &ctx->queue[ctx->queue_len],
332 input,
333 queue_free_len );
334
335 ctx->queue_len = 0U;
336
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200337 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300338
339 offset += queue_free_len;
340 remaining -= queue_free_len;
341 }
342 }
343
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200344 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300345 {
346 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
347
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200348 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300349
350 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
351 remaining %= POLY1305_BLOCK_SIZE_BYTES;
352 }
353
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200354 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300355 {
356 /* Store partial block */
357 ctx->queue_len = remaining;
358 memcpy( ctx->queue, &input[offset], remaining );
359 }
360
361 return( 0 );
362}
363
364int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
365 unsigned char mac[16] )
366{
Hanno Becker305e4e42018-12-11 15:03:16 +0000367 POLY1305_VALIDATE_RET( ctx != NULL );
368 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300369
370 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200371 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300372 {
373 /* Add padding bit */
374 ctx->queue[ctx->queue_len] = 1U;
375 ctx->queue_len++;
376
377 /* Pad with zeroes */
378 memset( &ctx->queue[ctx->queue_len],
379 0,
380 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
381
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200382 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200383 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300384 }
385
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200386 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300387
388 return( 0 );
389}
390
Daniel Kingadc32c02016-05-16 18:25:45 -0300391int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200392 const unsigned char *input,
393 size_t ilen,
394 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300395{
396 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000397 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000398 POLY1305_VALIDATE_RET( key != NULL );
399 POLY1305_VALIDATE_RET( mac != NULL );
400 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300401
402 mbedtls_poly1305_init( &ctx );
403
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200404 ret = mbedtls_poly1305_starts( &ctx, key );
405 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300406 goto cleanup;
407
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200408 ret = mbedtls_poly1305_update( &ctx, input, ilen );
409 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300410 goto cleanup;
411
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200412 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300413
414cleanup:
415 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200416 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300417}
418
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200419#endif /* MBEDTLS_POLY1305_ALT */
420
Daniel Kingadc32c02016-05-16 18:25:45 -0300421#if defined(MBEDTLS_SELF_TEST)
422
423static const unsigned char test_keys[2][32] =
424{
425 {
426 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
427 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
428 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
429 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
430 },
431 {
432 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
433 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
434 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
435 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
436 }
437};
438
439static const unsigned char test_data[2][127] =
440{
441 {
442 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
443 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
444 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
445 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
446 0x75, 0x70
447 },
448 {
449 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
450 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
451 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
452 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
453 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
454 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
455 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
456 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
457 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
458 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
459 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
460 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
461 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
462 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
463 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
464 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
465 }
466};
467
468static const size_t test_data_len[2] =
469{
470 34U,
471 127U
472};
473
474static const unsigned char test_mac[2][16] =
475{
476 {
477 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
478 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
479 },
480 {
481 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
482 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
483 }
484};
485
Ouss4e0b26872020-08-11 16:07:09 +0100486/* Make sure no other definition is already present. */
487#undef ASSERT
488
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200489#define ASSERT( cond, args ) \
490 do \
491 { \
492 if( ! ( cond ) ) \
493 { \
494 if( verbose != 0 ) \
495 mbedtls_printf args; \
496 \
497 return( -1 ); \
498 } \
499 } \
500 while( 0 )
501
Daniel Kingadc32c02016-05-16 18:25:45 -0300502int mbedtls_poly1305_self_test( int verbose )
503{
Daniel Kinge6e79682016-05-24 11:16:17 -0300504 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200505 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000506 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300507
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200508 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300509 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200510 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200511 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300512
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200513 ret = mbedtls_poly1305_mac( test_keys[i],
514 test_data[i],
515 test_data_len[i],
516 mac );
517 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300518
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200519 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300520
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200521 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300522 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300523 }
524
525 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300526 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300527
528 return( 0 );
529}
530
531#endif /* MBEDTLS_SELF_TEST */
532
533#endif /* MBEDTLS_POLY1305_C */