blob: 1f35f1d5015ed1adfc5dc05318a1b067df6099af [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 Subbianifbeb6922021-07-16 14:27:50 +0100253 mac[ 0] = MBEDTLS_BYTE_0( acc0 );
254 mac[ 1] = MBEDTLS_BYTE_1( acc0 );
255 mac[ 2] = MBEDTLS_BYTE_2( acc0 );
256 mac[ 3] = MBEDTLS_BYTE_3( acc0 );
257 mac[ 4] = MBEDTLS_BYTE_0( acc1 );
258 mac[ 5] = MBEDTLS_BYTE_1( acc1 );
259 mac[ 6] = MBEDTLS_BYTE_2( acc1 );
260 mac[ 7] = MBEDTLS_BYTE_3( acc1 );
261 mac[ 8] = MBEDTLS_BYTE_0( acc2 );
262 mac[ 9] = MBEDTLS_BYTE_1( acc2 );
263 mac[10] = MBEDTLS_BYTE_2( acc2 );
264 mac[11] = MBEDTLS_BYTE_3( acc2 );
265 mac[12] = MBEDTLS_BYTE_0( acc3 );
266 mac[13] = MBEDTLS_BYTE_1( acc3 );
267 mac[14] = MBEDTLS_BYTE_2( acc3 );
268 mac[15] = MBEDTLS_BYTE_3( acc3 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300269}
270
271void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
272{
Hanno Becker305e4e42018-12-11 15:03:16 +0000273 POLY1305_VALIDATE( ctx != NULL );
274
275 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300276}
277
278void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
279{
Hanno Becker236ea162018-12-12 14:00:34 +0000280 if( ctx == NULL )
Hanno Becker305e4e42018-12-11 15:03:16 +0000281 return;
282
283 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300284}
285
Manuel Pégourié-Gonnard4edd51b2018-05-07 10:21:56 +0200286int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
Daniel Kingadc32c02016-05-16 18:25:45 -0300287 const unsigned char key[32] )
288{
Hanno Becker305e4e42018-12-11 15:03:16 +0000289 POLY1305_VALIDATE_RET( ctx != NULL );
290 POLY1305_VALIDATE_RET( key != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300291
292 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Joe Subbiani6a506312021-07-07 16:56:29 +0100293 ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
294 ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
295 ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
296 ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300297
Joe Subbiani6a506312021-07-07 16:56:29 +0100298 ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
299 ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
300 ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
301 ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300302
303 /* Initial accumulator state */
304 ctx->acc[0] = 0U;
305 ctx->acc[1] = 0U;
306 ctx->acc[2] = 0U;
307 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200308 ctx->acc[4] = 0U;
309
310 /* Queue initially empty */
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +0200311 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200312 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300313
Daniel Kinge6e79682016-05-24 11:16:17 -0300314 return( 0 );
Daniel Kingadc32c02016-05-16 18:25:45 -0300315}
316
317int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200318 const unsigned char *input,
319 size_t ilen )
Daniel Kingadc32c02016-05-16 18:25:45 -0300320{
321 size_t offset = 0U;
322 size_t remaining = ilen;
323 size_t queue_free_len;
324 size_t nblocks;
Hanno Becker305e4e42018-12-11 15:03:16 +0000325 POLY1305_VALIDATE_RET( ctx != NULL );
326 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300327
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200328 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300329 {
330 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
331
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200332 if( ilen < queue_free_len )
Daniel Kingadc32c02016-05-16 18:25:45 -0300333 {
334 /* Not enough data to complete the block.
335 * Store this data with the other leftovers.
336 */
337 memcpy( &ctx->queue[ctx->queue_len],
338 input,
339 ilen );
340
341 ctx->queue_len += ilen;
342
343 remaining = 0U;
344 }
345 else
346 {
347 /* Enough data to produce a complete block */
348 memcpy( &ctx->queue[ctx->queue_len],
349 input,
350 queue_free_len );
351
352 ctx->queue_len = 0U;
353
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200354 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300355
356 offset += queue_free_len;
357 remaining -= queue_free_len;
358 }
359 }
360
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200361 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
Daniel Kingadc32c02016-05-16 18:25:45 -0300362 {
363 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
364
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200365 poly1305_process( ctx, nblocks, &input[offset], 1U );
Daniel Kingadc32c02016-05-16 18:25:45 -0300366
367 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
368 remaining %= POLY1305_BLOCK_SIZE_BYTES;
369 }
370
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200371 if( remaining > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300372 {
373 /* Store partial block */
374 ctx->queue_len = remaining;
375 memcpy( ctx->queue, &input[offset], remaining );
376 }
377
378 return( 0 );
379}
380
381int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
382 unsigned char mac[16] )
383{
Hanno Becker305e4e42018-12-11 15:03:16 +0000384 POLY1305_VALIDATE_RET( ctx != NULL );
385 POLY1305_VALIDATE_RET( mac != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300386
387 /* Process any leftover data */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200388 if( ctx->queue_len > 0U )
Daniel Kingadc32c02016-05-16 18:25:45 -0300389 {
390 /* Add padding bit */
391 ctx->queue[ctx->queue_len] = 1U;
392 ctx->queue_len++;
393
394 /* Pad with zeroes */
395 memset( &ctx->queue[ctx->queue_len],
396 0,
397 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
398
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200399 poly1305_process( ctx, 1U, /* Process 1 block */
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200400 ctx->queue, 0U ); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300401 }
402
Manuel Pégourié-Gonnard9620f9b2018-05-24 16:52:19 +0200403 poly1305_compute_mac( ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300404
405 return( 0 );
406}
407
Daniel Kingadc32c02016-05-16 18:25:45 -0300408int mbedtls_poly1305_mac( const unsigned char key[32],
Manuel Pégourié-Gonnardb1ac5e72018-05-09 09:25:00 +0200409 const unsigned char *input,
410 size_t ilen,
411 unsigned char mac[16] )
Daniel Kingadc32c02016-05-16 18:25:45 -0300412{
413 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker305e4e42018-12-11 15:03:16 +0000415 POLY1305_VALIDATE_RET( key != NULL );
416 POLY1305_VALIDATE_RET( mac != NULL );
417 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
Daniel Kingadc32c02016-05-16 18:25:45 -0300418
419 mbedtls_poly1305_init( &ctx );
420
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200421 ret = mbedtls_poly1305_starts( &ctx, key );
422 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300423 goto cleanup;
424
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200425 ret = mbedtls_poly1305_update( &ctx, input, ilen );
426 if( ret != 0 )
Daniel Kingadc32c02016-05-16 18:25:45 -0300427 goto cleanup;
428
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200429 ret = mbedtls_poly1305_finish( &ctx, mac );
Daniel Kingadc32c02016-05-16 18:25:45 -0300430
431cleanup:
432 mbedtls_poly1305_free( &ctx );
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200433 return( ret );
Daniel Kingadc32c02016-05-16 18:25:45 -0300434}
435
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200436#endif /* MBEDTLS_POLY1305_ALT */
437
Daniel Kingadc32c02016-05-16 18:25:45 -0300438#if defined(MBEDTLS_SELF_TEST)
439
440static const unsigned char test_keys[2][32] =
441{
442 {
443 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
444 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
445 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
446 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
447 },
448 {
449 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
450 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
451 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
452 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
453 }
454};
455
456static const unsigned char test_data[2][127] =
457{
458 {
459 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
460 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
461 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
462 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
463 0x75, 0x70
464 },
465 {
466 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
467 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
468 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
469 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
470 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
471 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
472 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
473 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
474 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
475 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
476 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
477 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
478 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
479 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
480 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
481 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
482 }
483};
484
485static const size_t test_data_len[2] =
486{
487 34U,
488 127U
489};
490
491static const unsigned char test_mac[2][16] =
492{
493 {
494 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
495 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
496 },
497 {
498 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
499 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
500 }
501};
502
Ouss4e0b26872020-08-11 16:07:09 +0100503/* Make sure no other definition is already present. */
504#undef ASSERT
505
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200506#define ASSERT( cond, args ) \
507 do \
508 { \
509 if( ! ( cond ) ) \
510 { \
511 if( verbose != 0 ) \
512 mbedtls_printf args; \
513 \
514 return( -1 ); \
515 } \
516 } \
517 while( 0 )
518
Daniel Kingadc32c02016-05-16 18:25:45 -0300519int mbedtls_poly1305_self_test( int verbose )
520{
Daniel Kinge6e79682016-05-24 11:16:17 -0300521 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200522 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000523 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300524
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200525 for( i = 0U; i < 2U; i++ )
Daniel Kingadc32c02016-05-16 18:25:45 -0300526 {
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200527 if( verbose != 0 )
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200528 mbedtls_printf( " Poly1305 test %u ", i );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300529
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200530 ret = mbedtls_poly1305_mac( test_keys[i],
531 test_data[i],
532 test_data_len[i],
533 mac );
534 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300535
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200536 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
Daniel Kingadc32c02016-05-16 18:25:45 -0300537
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200538 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300539 mbedtls_printf( "passed\n" );
Daniel Kingdedf4a32016-05-18 10:07:53 -0300540 }
541
542 if( verbose != 0 )
Daniel Kingdedf4a32016-05-18 10:07:53 -0300543 mbedtls_printf( "\n" );
Daniel Kingadc32c02016-05-16 18:25:45 -0300544
545 return( 0 );
546}
547
548#endif /* MBEDTLS_SELF_TEST */
549
550#endif /* MBEDTLS_POLY1305_C */