blob: 7375a0c5728fd47b5eaa3dfa01c5f7f1b50d129d [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)
32#if defined(MBEDTLS_PLATFORM_C)
33#include "mbedtls/platform.h"
34#else
35#include <stdio.h>
36#define mbedtls_printf printf
37#endif /* MBEDTLS_PLATFORM_C */
38#endif /* MBEDTLS_SELF_TEST */
39
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020040#if !defined(MBEDTLS_POLY1305_ALT)
41
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020042#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
43 !defined(inline) && !defined(__cplusplus)
44#define inline __inline
45#endif
46
Hanno Becker305e4e42018-12-11 15:03:16 +000047/* Parameter validation macros */
48#define POLY1305_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
50#define POLY1305_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
Daniel Kingadc32c02016-05-16 18:25:45 -030053#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
54
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020055/*
56 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
57 * However we provided an alternative for platforms without such a multiplier.
58 */
59#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
60static uint64_t mul64( uint32_t a, uint32_t b )
61{
62 /* a = al + 2**16 ah, b = bl + 2**16 bh */
63 const uint16_t al = (uint16_t) a;
Joe Subbiani51b147a2021-07-16 17:47:17 +010064 const uint16_t bl = (uint16_t) b;
Joe Subbiani4919bb42021-07-16 17:14:07 +010065 const uint16_t ah = a >> 16;
66 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020067
68 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
69 const uint32_t lo = (uint32_t) al * bl;
70 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
71 const uint32_t hi = (uint32_t) ah * bh;
72
73 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
74}
75#else
76static inline uint64_t mul64( uint32_t a, uint32_t b )
77{
78 return( (uint64_t) a * b );
79}
80#endif
81
82
Daniel Kingadc32c02016-05-16 18:25:45 -030083/**
84 * \brief Process blocks with Poly1305.
85 *
86 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020087 * \param nblocks Number of blocks to process. Note that this
88 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030089 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020090 * \param needs_padding Set to 0 if the padding bit has already been
91 * applied to the input data before calling this
92 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030093 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +020094static void poly1305_process( mbedtls_poly1305_context *ctx,
95 size_t nblocks,
96 const unsigned char *input,
97 uint32_t needs_padding )
Daniel Kingadc32c02016-05-16 18:25:45 -030098{
99 uint64_t d0, d1, d2, d3;
100 uint32_t acc0, acc1, acc2, acc3, acc4;
101 uint32_t r0, r1, r2, r3;
102 uint32_t rs1, rs2, rs3;
103 size_t offset = 0U;
104 size_t i;
105
106 r0 = ctx->r[0];
107 r1 = ctx->r[1];
108 r2 = ctx->r[2];
109 r3 = ctx->r[3];
110
111 rs1 = r1 + ( r1 >> 2U );
112 rs2 = r2 + ( r2 >> 2U );
113 rs3 = r3 + ( r3 >> 2U );
114
115 acc0 = ctx->acc[0];
116 acc1 = ctx->acc[1];
117 acc2 = ctx->acc[2];
118 acc3 = ctx->acc[3];
119 acc4 = ctx->acc[4];
120
121 /* Process full blocks */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200122 for( i = 0U; i < nblocks; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300123 {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200124 /* The input block is treated as a 128-bit little-endian integer */
Joe Subbiani6a506312021-07-07 16:56:29 +0100125 d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
126 d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
127 d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
128 d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200129
130 /* Compute: acc += (padded) block as a 130-bit integer */
131 d0 += (uint64_t) acc0;
132 d1 += (uint64_t) acc1 + ( d0 >> 32U );
133 d2 += (uint64_t) acc2 + ( d1 >> 32U );
134 d3 += (uint64_t) acc3 + ( d2 >> 32U );
Daniel Kinge6e79682016-05-24 11:16:17 -0300135 acc0 = (uint32_t) d0;
136 acc1 = (uint32_t) d1;
137 acc2 = (uint32_t) d2;
138 acc3 = (uint32_t) d3;
139 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300140
141 /* Compute: acc *= r */
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +0200142 d0 = mul64( acc0, r0 ) +
143 mul64( acc1, rs3 ) +
144 mul64( acc2, rs2 ) +
145 mul64( acc3, rs1 );
146 d1 = mul64( acc0, r1 ) +
147 mul64( acc1, r0 ) +
148 mul64( acc2, rs3 ) +
149 mul64( acc3, rs2 ) +
150 mul64( acc4, rs1 );
151 d2 = mul64( acc0, r2 ) +
152 mul64( acc1, r1 ) +
153 mul64( acc2, r0 ) +
154 mul64( acc3, rs3 ) +
155 mul64( acc4, rs2 );
156 d3 = mul64( acc0, r3 ) +
157 mul64( acc1, r2 ) +
158 mul64( acc2, r1 ) +
159 mul64( acc3, r0 ) +
160 mul64( acc4, rs3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300161 acc4 *= r0;
162
163 /* Compute: acc %= (2^130 - 5) (partial remainder) */
164 d1 += ( d0 >> 32 );
165 d2 += ( d1 >> 32 );
166 d3 += ( d2 >> 32 );
Daniel Kinge6e79682016-05-24 11:16:17 -0300167 acc0 = (uint32_t) d0;
168 acc1 = (uint32_t) d1;
169 acc2 = (uint32_t) d2;
170 acc3 = (uint32_t) d3;
171 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300172
Daniel Kinge6e79682016-05-24 11:16:17 -0300173 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
Daniel Kingadc32c02016-05-16 18:25:45 -0300174 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300175 acc0 = (uint32_t) d0;
176 d0 = (uint64_t) acc1 + ( d0 >> 32U );
177 acc1 = (uint32_t) d0;
178 d0 = (uint64_t) acc2 + ( d0 >> 32U );
179 acc2 = (uint32_t) d0;
180 d0 = (uint64_t) acc3 + ( d0 >> 32U );
181 acc3 = (uint32_t) d0;
182 d0 = (uint64_t) acc4 + ( d0 >> 32U );
183 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300184
185 offset += POLY1305_BLOCK_SIZE_BYTES;
186 }
187
188 ctx->acc[0] = acc0;
189 ctx->acc[1] = acc1;
190 ctx->acc[2] = acc2;
191 ctx->acc[3] = acc3;
192 ctx->acc[4] = acc4;
193}
194
195/**
196 * \brief Compute the Poly1305 MAC
197 *
198 * \param ctx The Poly1305 context.
199 * \param mac The buffer to where the MAC is written. Must be
200 * big enough to contain the 16-byte MAC.
201 */
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200202static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
203 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300204{
205 uint64_t d;
206 uint32_t g0, g1, g2, g3, g4;
207 uint32_t acc0, acc1, acc2, acc3, acc4;
208 uint32_t mask;
209 uint32_t mask_inv;
210
211 acc0 = ctx->acc[0];
212 acc1 = ctx->acc[1];
213 acc2 = ctx->acc[2];
214 acc3 = ctx->acc[3];
215 acc4 = ctx->acc[4];
216
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200217 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300218 * We do this by calculating acc - (2^130 - 5), then checking if
219 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
220 */
221
222 /* Calculate acc + -(2^130 - 5) */
Daniel Kinge6e79682016-05-24 11:16:17 -0300223 d = ( (uint64_t) acc0 + 5U );
224 g0 = (uint32_t) d;
225 d = ( (uint64_t) acc1 + ( d >> 32 ) );
226 g1 = (uint32_t) d;
227 d = ( (uint64_t) acc2 + ( d >> 32 ) );
228 g2 = (uint32_t) d;
229 d = ( (uint64_t) acc3 + ( d >> 32 ) );
230 g3 = (uint32_t) d;
231 g4 = acc4 + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300232
233 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Daniel Kinge6e79682016-05-24 11:16:17 -0300234 mask = (uint32_t) 0U - ( g4 >> 2U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300235 mask_inv = ~mask;
236
237 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
238 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
239 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
240 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
241 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
242
243 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300244 d = (uint64_t) acc0 + ctx->s[0];
245 acc0 = (uint32_t) d;
246 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
247 acc1 = (uint32_t) d;
248 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
249 acc2 = (uint32_t) d;
250 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300251
252 /* Compute MAC (128 least significant bits of the accumulator) */
Joe Subbiani6dd73642021-07-19 11:56:54 +0100253 MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
254 MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
255 MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
256 MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300257}
258
259void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
260{
Hanno Becker305e4e42018-12-11 15:03:16 +0000261 POLY1305_VALIDATE( ctx != NULL );
262
263 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300264}
265
266void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
267{
Hanno Becker236ea162018-12-12 14:00:34 +0000268 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000269 return;
270
271 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300272}
273
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200274int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300275 const unsigned char key[32] )
276{
Hanno Becker305e4e42018-12-11 15:03:16 +0000277 POLY1305_VALIDATE_RET( ctx != NULL );
278 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300279
280 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Joe Subbiani6a506312021-07-07 16:56:29 +0100281 ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
282 ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
283 ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
284 ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300285
Joe Subbiani6a506312021-07-07 16:56:29 +0100286 ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
287 ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
288 ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
289 ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300290
291 /* Initial accumulator state */
292 ctx->acc[0] = 0U;
293 ctx->acc[1] = 0U;
294 ctx->acc[2] = 0U;
295 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200296 ctx->acc[4] = 0U;
297
298 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200299 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200300 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300301
Daniel Kinge6e79682016-05-24 11:16:17 -0300302 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300303}
304
305int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200306 const unsigned char *input,
307 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300308{
309 size_t offset = 0U;
310 size_t remaining = ilen;
311 size_t queue_free_len;
312 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000313 POLY1305_VALIDATE_RET( ctx != NULL );
314 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300315
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200316 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300317 {
318 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
319
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200320 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300321 {
322 /* Not enough data to complete the block.
323 * Store this data with the other leftovers.
324 */
325 memcpy( &ctx->queue[ctx->queue_len],
326 input,
327 ilen );
328
329 ctx->queue_len += ilen;
330
331 remaining = 0U;
332 }
333 else
334 {
335 /* Enough data to produce a complete block */
336 memcpy( &ctx->queue[ctx->queue_len],
337 input,
338 queue_free_len );
339
340 ctx->queue_len = 0U;
341
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200342 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300343
344 offset += queue_free_len;
345 remaining -= queue_free_len;
346 }
347 }
348
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200349 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300350 {
351 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
352
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200353 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300354
355 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
356 remaining %= POLY1305_BLOCK_SIZE_BYTES;
357 }
358
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200359 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300360 {
361 /* Store partial block */
362 ctx->queue_len = remaining;
363 memcpy( ctx->queue, &input[offset], remaining );
364 }
365
366 return( 0 );
367}
368
369int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
370 unsigned char mac[16] )
371{
Hanno Becker305e4e42018-12-11 15:03:16 +0000372 POLY1305_VALIDATE_RET( ctx != NULL );
373 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300374
375 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200376 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300377 {
378 /* Add padding bit */
379 ctx->queue[ctx->queue_len] = 1U;
380 ctx->queue_len++;
381
382 /* Pad with zeroes */
383 memset( &ctx->queue[ctx->queue_len],
384 0,
385 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
386
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200387 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200388 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300389 }
390
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200391 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300392
393 return( 0 );
394}
395
Daniel Kingadc32c02016-05-16 18:25:45 -0300396int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200397 const unsigned char *input,
398 size_t ilen,
399 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300400{
401 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000403 POLY1305_VALIDATE_RET( key != NULL );
404 POLY1305_VALIDATE_RET( mac != NULL );
405 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300406
407 mbedtls_poly1305_init( &ctx );
408
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200409 ret = mbedtls_poly1305_starts( &ctx, key );
410 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300411 goto cleanup;
412
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200413 ret = mbedtls_poly1305_update( &ctx, input, ilen );
414 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300415 goto cleanup;
416
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200417 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300418
419cleanup:
420 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200421 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300422}
423
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200424#endif /* MBEDTLS_POLY1305_ALT */
425
Daniel Kingadc32c02016-05-16 18:25:45 -0300426#if defined(MBEDTLS_SELF_TEST)
427
428static const unsigned char test_keys[2][32] =
429{
430 {
431 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
432 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
433 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
434 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
435 },
436 {
437 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
438 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
439 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
440 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
441 }
442};
443
444static const unsigned char test_data[2][127] =
445{
446 {
447 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
448 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
449 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
450 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
451 0x75, 0x70
452 },
453 {
454 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
455 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
456 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
457 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
458 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
459 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
460 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
461 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
462 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
463 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
464 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
465 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
466 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
467 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
468 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
469 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
470 }
471};
472
473static const size_t test_data_len[2] =
474{
475 34U,
476 127U
477};
478
479static const unsigned char test_mac[2][16] =
480{
481 {
482 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
483 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
484 },
485 {
486 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
487 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
488 }
489};
490
Ouss4e0b26872020-08-11 16:07:09 +0100491/* Make sure no other definition is already present. */
492#undef ASSERT
493
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200494#define ASSERT( cond, args ) \
495 do \
496 { \
497 if( ! ( cond ) ) \
498 { \
499 if( verbose != 0 ) \
500 mbedtls_printf args; \
501 \
502 return( -1 ); \
503 } \
504 } \
505 while( 0 )
506
Daniel Kingadc32c02016-05-16 18:25:45 -0300507int mbedtls_poly1305_self_test( int verbose )
508{
Daniel Kinge6e79682016-05-24 11:16:17 -0300509 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200510 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000511 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300512
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200513 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300514 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200515 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200516 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300517
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200518 ret = mbedtls_poly1305_mac( test_keys[i],
519 test_data[i],
520 test_data_len[i],
521 mac );
522 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300523
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200524 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300525
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200526 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300527 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300528 }
529
530 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300531 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300532
533 return( 0 );
534}
535
536#endif /* MBEDTLS_SELF_TEST */
537
538#endif /* MBEDTLS_POLY1305_C */