blob: c9ebe9e1daa6835b20a5d36d8c89051b4d49390b [file] [log] [blame]
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001/**
2 * \file poly1305.c
3 *
4 * \brief Poly1305 authentication algorithm.
5 *
Jerome Forissier79013242021-07-28 10:24:04 +02006 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander3d3b0592019-03-20 15:30:29 +01008 */
Jerome Forissier79013242021-07-28 10:24:04 +02009#include "common.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010010
11#if defined(MBEDTLS_POLY1305_C)
12
13#include "mbedtls/poly1305.h"
14#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020015#include "mbedtls/error.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010016
17#include <string.h>
18
Jens Wiklander3d3b0592019-03-20 15:30:29 +010019#include "mbedtls/platform.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010020
21#if !defined(MBEDTLS_POLY1305_ALT)
22
Jens Wiklander32b31802023-10-06 16:59:46 +020023#define POLY1305_BLOCK_SIZE_BYTES (16U)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010024
Jens Wiklander3d3b0592019-03-20 15:30:29 +010025/*
26 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
27 * However we provided an alternative for platforms without such a multiplier.
28 */
29#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
Jens Wiklander32b31802023-10-06 16:59:46 +020030static uint64_t mul64(uint32_t a, uint32_t b)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010031{
32 /* a = al + 2**16 ah, b = bl + 2**16 bh */
33 const uint16_t al = (uint16_t) a;
34 const uint16_t bl = (uint16_t) b;
35 const uint16_t ah = a >> 16;
36 const uint16_t bh = b >> 16;
37
38 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
39 const uint32_t lo = (uint32_t) al * bl;
Jens Wiklander32b31802023-10-06 16:59:46 +020040 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010041 const uint32_t hi = (uint32_t) ah * bh;
42
Jens Wiklander32b31802023-10-06 16:59:46 +020043 return lo + (me << 16) + ((uint64_t) hi << 32);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010044}
45#else
Jens Wiklander32b31802023-10-06 16:59:46 +020046static inline uint64_t mul64(uint32_t a, uint32_t b)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010047{
Jens Wiklander32b31802023-10-06 16:59:46 +020048 return (uint64_t) a * b;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010049}
50#endif
51
52
53/**
54 * \brief Process blocks with Poly1305.
55 *
56 * \param ctx The Poly1305 context.
57 * \param nblocks Number of blocks to process. Note that this
58 * function only processes full blocks.
59 * \param input Buffer containing the input block(s).
60 * \param needs_padding Set to 0 if the padding bit has already been
61 * applied to the input data before calling this
62 * function. Otherwise, set this parameter to 1.
63 */
Jens Wiklander32b31802023-10-06 16:59:46 +020064static void poly1305_process(mbedtls_poly1305_context *ctx,
65 size_t nblocks,
66 const unsigned char *input,
67 uint32_t needs_padding)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010068{
69 uint64_t d0, d1, d2, d3;
70 uint32_t acc0, acc1, acc2, acc3, acc4;
71 uint32_t r0, r1, r2, r3;
72 uint32_t rs1, rs2, rs3;
73 size_t offset = 0U;
74 size_t i;
75
76 r0 = ctx->r[0];
77 r1 = ctx->r[1];
78 r2 = ctx->r[2];
79 r3 = ctx->r[3];
80
Jens Wiklander32b31802023-10-06 16:59:46 +020081 rs1 = r1 + (r1 >> 2U);
82 rs2 = r2 + (r2 >> 2U);
83 rs3 = r3 + (r3 >> 2U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010084
85 acc0 = ctx->acc[0];
86 acc1 = ctx->acc[1];
87 acc2 = ctx->acc[2];
88 acc3 = ctx->acc[3];
89 acc4 = ctx->acc[4];
90
91 /* Process full blocks */
Jens Wiklander32b31802023-10-06 16:59:46 +020092 for (i = 0U; i < nblocks; i++) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +010093 /* The input block is treated as a 128-bit little-endian integer */
Jens Wiklander32b31802023-10-06 16:59:46 +020094 d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0);
95 d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4);
96 d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8);
97 d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010098
99 /* Compute: acc += (padded) block as a 130-bit integer */
100 d0 += (uint64_t) acc0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200101 d1 += (uint64_t) acc1 + (d0 >> 32U);
102 d2 += (uint64_t) acc2 + (d1 >> 32U);
103 d3 += (uint64_t) acc3 + (d2 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100104 acc0 = (uint32_t) d0;
105 acc1 = (uint32_t) d1;
106 acc2 = (uint32_t) d2;
107 acc3 = (uint32_t) d3;
Jens Wiklander32b31802023-10-06 16:59:46 +0200108 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100109
110 /* Compute: acc *= r */
Jens Wiklander32b31802023-10-06 16:59:46 +0200111 d0 = mul64(acc0, r0) +
112 mul64(acc1, rs3) +
113 mul64(acc2, rs2) +
114 mul64(acc3, rs1);
115 d1 = mul64(acc0, r1) +
116 mul64(acc1, r0) +
117 mul64(acc2, rs3) +
118 mul64(acc3, rs2) +
119 mul64(acc4, rs1);
120 d2 = mul64(acc0, r2) +
121 mul64(acc1, r1) +
122 mul64(acc2, r0) +
123 mul64(acc3, rs3) +
124 mul64(acc4, rs2);
125 d3 = mul64(acc0, r3) +
126 mul64(acc1, r2) +
127 mul64(acc2, r1) +
128 mul64(acc3, r0) +
129 mul64(acc4, rs3);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100130 acc4 *= r0;
131
132 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200133 d1 += (d0 >> 32);
134 d2 += (d1 >> 32);
135 d3 += (d2 >> 32);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100136 acc0 = (uint32_t) d0;
137 acc1 = (uint32_t) d1;
138 acc2 = (uint32_t) d2;
139 acc3 = (uint32_t) d3;
Jens Wiklander32b31802023-10-06 16:59:46 +0200140 acc4 = (uint32_t) (d3 >> 32) + acc4;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100141
Jens Wiklander32b31802023-10-06 16:59:46 +0200142 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100143 acc4 &= 3U;
144 acc0 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200145 d0 = (uint64_t) acc1 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100146 acc1 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200147 d0 = (uint64_t) acc2 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100148 acc2 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200149 d0 = (uint64_t) acc3 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100150 acc3 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200151 d0 = (uint64_t) acc4 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100152 acc4 = (uint32_t) d0;
153
154 offset += POLY1305_BLOCK_SIZE_BYTES;
155 }
156
157 ctx->acc[0] = acc0;
158 ctx->acc[1] = acc1;
159 ctx->acc[2] = acc2;
160 ctx->acc[3] = acc3;
161 ctx->acc[4] = acc4;
162}
163
164/**
165 * \brief Compute the Poly1305 MAC
166 *
167 * \param ctx The Poly1305 context.
168 * \param mac The buffer to where the MAC is written. Must be
169 * big enough to contain the 16-byte MAC.
170 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200171static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
172 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100173{
174 uint64_t d;
175 uint32_t g0, g1, g2, g3, g4;
176 uint32_t acc0, acc1, acc2, acc3, acc4;
177 uint32_t mask;
178 uint32_t mask_inv;
179
180 acc0 = ctx->acc[0];
181 acc1 = ctx->acc[1];
182 acc2 = ctx->acc[2];
183 acc3 = ctx->acc[3];
184 acc4 = ctx->acc[4];
185
186 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
187 * We do this by calculating acc - (2^130 - 5), then checking if
188 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
189 */
190
191 /* Calculate acc + -(2^130 - 5) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200192 d = ((uint64_t) acc0 + 5U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100193 g0 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200194 d = ((uint64_t) acc1 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100195 g1 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200196 d = ((uint64_t) acc2 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100197 g2 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200198 d = ((uint64_t) acc3 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100199 g3 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200200 g4 = acc4 + (uint32_t) (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100201
202 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200203 mask = (uint32_t) 0U - (g4 >> 2U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100204 mask_inv = ~mask;
205
206 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Jens Wiklander32b31802023-10-06 16:59:46 +0200207 acc0 = (acc0 & mask_inv) | (g0 & mask);
208 acc1 = (acc1 & mask_inv) | (g1 & mask);
209 acc2 = (acc2 & mask_inv) | (g2 & mask);
210 acc3 = (acc3 & mask_inv) | (g3 & mask);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100211
212 /* Add 's' */
213 d = (uint64_t) acc0 + ctx->s[0];
214 acc0 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200215 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100216 acc1 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200217 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100218 acc2 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200219 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100220
221 /* Compute MAC (128 least significant bits of the accumulator) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200222 MBEDTLS_PUT_UINT32_LE(acc0, mac, 0);
223 MBEDTLS_PUT_UINT32_LE(acc1, mac, 4);
224 MBEDTLS_PUT_UINT32_LE(acc2, mac, 8);
225 MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100226}
227
Jens Wiklander32b31802023-10-06 16:59:46 +0200228void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100229{
Jens Wiklander32b31802023-10-06 16:59:46 +0200230 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100231}
232
Jens Wiklander32b31802023-10-06 16:59:46 +0200233void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100234{
Jens Wiklander32b31802023-10-06 16:59:46 +0200235 if (ctx == NULL) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100236 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200237 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100238
Jens Wiklander32b31802023-10-06 16:59:46 +0200239 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100240}
241
Jens Wiklander32b31802023-10-06 16:59:46 +0200242int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
243 const unsigned char key[32])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100244{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100245 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Jens Wiklander32b31802023-10-06 16:59:46 +0200246 ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU;
247 ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU;
248 ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU;
249 ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100250
Jens Wiklander32b31802023-10-06 16:59:46 +0200251 ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
252 ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
253 ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
254 ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100255
256 /* Initial accumulator state */
257 ctx->acc[0] = 0U;
258 ctx->acc[1] = 0U;
259 ctx->acc[2] = 0U;
260 ctx->acc[3] = 0U;
261 ctx->acc[4] = 0U;
262
263 /* Queue initially empty */
Jens Wiklander32b31802023-10-06 16:59:46 +0200264 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100265 ctx->queue_len = 0U;
266
Jens Wiklander32b31802023-10-06 16:59:46 +0200267 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100268}
269
Jens Wiklander32b31802023-10-06 16:59:46 +0200270int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
271 const unsigned char *input,
272 size_t ilen)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100273{
274 size_t offset = 0U;
275 size_t remaining = ilen;
276 size_t queue_free_len;
277 size_t nblocks;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100278
Jens Wiklander32b31802023-10-06 16:59:46 +0200279 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
280 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100281
Jens Wiklander32b31802023-10-06 16:59:46 +0200282 if (ilen < queue_free_len) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100283 /* Not enough data to complete the block.
284 * Store this data with the other leftovers.
285 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200286 memcpy(&ctx->queue[ctx->queue_len],
287 input,
288 ilen);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100289
290 ctx->queue_len += ilen;
291
292 remaining = 0U;
Jens Wiklander32b31802023-10-06 16:59:46 +0200293 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100294 /* Enough data to produce a complete block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200295 memcpy(&ctx->queue[ctx->queue_len],
296 input,
297 queue_free_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100298
299 ctx->queue_len = 0U;
300
Jens Wiklander32b31802023-10-06 16:59:46 +0200301 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100302
303 offset += queue_free_len;
304 remaining -= queue_free_len;
305 }
306 }
307
Jens Wiklander32b31802023-10-06 16:59:46 +0200308 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100309 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
310
Jens Wiklander32b31802023-10-06 16:59:46 +0200311 poly1305_process(ctx, nblocks, &input[offset], 1U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100312
313 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
314 remaining %= POLY1305_BLOCK_SIZE_BYTES;
315 }
316
Jens Wiklander32b31802023-10-06 16:59:46 +0200317 if (remaining > 0U) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100318 /* Store partial block */
319 ctx->queue_len = remaining;
Jens Wiklander32b31802023-10-06 16:59:46 +0200320 memcpy(ctx->queue, &input[offset], remaining);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100321 }
322
Jens Wiklander32b31802023-10-06 16:59:46 +0200323 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100324}
325
Jens Wiklander32b31802023-10-06 16:59:46 +0200326int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
327 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100328{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100329 /* Process any leftover data */
Jens Wiklander32b31802023-10-06 16:59:46 +0200330 if (ctx->queue_len > 0U) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100331 /* Add padding bit */
332 ctx->queue[ctx->queue_len] = 1U;
333 ctx->queue_len++;
334
335 /* Pad with zeroes */
Jens Wiklander32b31802023-10-06 16:59:46 +0200336 memset(&ctx->queue[ctx->queue_len],
337 0,
338 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100339
Jens Wiklander32b31802023-10-06 16:59:46 +0200340 poly1305_process(ctx, 1U, /* Process 1 block */
341 ctx->queue, 0U); /* Already padded above */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100342 }
343
Jens Wiklander32b31802023-10-06 16:59:46 +0200344 poly1305_compute_mac(ctx, mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100345
Jens Wiklander32b31802023-10-06 16:59:46 +0200346 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100347}
348
Jens Wiklander32b31802023-10-06 16:59:46 +0200349int mbedtls_poly1305_mac(const unsigned char key[32],
350 const unsigned char *input,
351 size_t ilen,
352 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100353{
354 mbedtls_poly1305_context ctx;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200355 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100356
Jens Wiklander32b31802023-10-06 16:59:46 +0200357 mbedtls_poly1305_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100358
Jens Wiklander32b31802023-10-06 16:59:46 +0200359 ret = mbedtls_poly1305_starts(&ctx, key);
360 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100361 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200362 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100363
Jens Wiklander32b31802023-10-06 16:59:46 +0200364 ret = mbedtls_poly1305_update(&ctx, input, ilen);
365 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100366 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200367 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100368
Jens Wiklander32b31802023-10-06 16:59:46 +0200369 ret = mbedtls_poly1305_finish(&ctx, mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100370
371cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +0200372 mbedtls_poly1305_free(&ctx);
373 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100374}
375
376#endif /* MBEDTLS_POLY1305_ALT */
377
378#if defined(MBEDTLS_SELF_TEST)
379
380static const unsigned char test_keys[2][32] =
381{
382 {
383 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
384 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
385 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
386 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
387 },
388 {
389 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
390 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
391 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
392 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
393 }
394};
395
396static const unsigned char test_data[2][127] =
397{
398 {
399 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
400 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
401 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
402 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
403 0x75, 0x70
404 },
405 {
406 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
407 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
408 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
409 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
410 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
411 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
412 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
413 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
414 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
415 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
416 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
417 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
418 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
419 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
420 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
421 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
422 }
423};
424
425static const size_t test_data_len[2] =
426{
427 34U,
428 127U
429};
430
431static const unsigned char test_mac[2][16] =
432{
433 {
434 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
435 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
436 },
437 {
438 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
439 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
440 }
441};
442
Jerome Forissier79013242021-07-28 10:24:04 +0200443/* Make sure no other definition is already present. */
444#undef ASSERT
445
Jens Wiklander32b31802023-10-06 16:59:46 +0200446#define ASSERT(cond, args) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100447 do \
448 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200449 if (!(cond)) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100450 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200451 if (verbose != 0) \
452 mbedtls_printf args; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100453 \
Jens Wiklander32b31802023-10-06 16:59:46 +0200454 return -1; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100455 } \
456 } \
Jens Wiklander32b31802023-10-06 16:59:46 +0200457 while (0)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100458
Jens Wiklander32b31802023-10-06 16:59:46 +0200459int mbedtls_poly1305_self_test(int verbose)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100460{
461 unsigned char mac[16];
462 unsigned i;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200463 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100464
Jens Wiklander32b31802023-10-06 16:59:46 +0200465 for (i = 0U; i < 2U; i++) {
466 if (verbose != 0) {
467 mbedtls_printf(" Poly1305 test %u ", i);
468 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100469
Jens Wiklander32b31802023-10-06 16:59:46 +0200470 ret = mbedtls_poly1305_mac(test_keys[i],
471 test_data[i],
472 test_data_len[i],
473 mac);
474 ASSERT(0 == ret, ("error code: %i\n", ret));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100475
Jens Wiklander32b31802023-10-06 16:59:46 +0200476 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100477
Jens Wiklander32b31802023-10-06 16:59:46 +0200478 if (verbose != 0) {
479 mbedtls_printf("passed\n");
480 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100481 }
482
Jens Wiklander32b31802023-10-06 16:59:46 +0200483 if (verbose != 0) {
484 mbedtls_printf("\n");
485 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100486
Jens Wiklander32b31802023-10-06 16:59:46 +0200487 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100488}
489
490#endif /* MBEDTLS_SELF_TEST */
491
492#endif /* MBEDTLS_POLY1305_C */