blob: f4e1d3f8807c55b532e75f2b9f39ee4d8f0186bf [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
7 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander3d3b0592019-03-20 15:30:29 +01008 *
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.
Jens Wiklander3d3b0592019-03-20 15:30:29 +010020 */
Jerome Forissier79013242021-07-28 10:24:04 +020021#include "common.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010022
23#if defined(MBEDTLS_POLY1305_C)
24
25#include "mbedtls/poly1305.h"
26#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020027#include "mbedtls/error.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010028
29#include <string.h>
30
Jens Wiklander3d3b0592019-03-20 15:30:29 +010031#include "mbedtls/platform.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010032
33#if !defined(MBEDTLS_POLY1305_ALT)
34
Jens Wiklander32b31802023-10-06 16:59:46 +020035#define POLY1305_BLOCK_SIZE_BYTES (16U)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036
Jens Wiklander3d3b0592019-03-20 15:30:29 +010037/*
38 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
39 * However we provided an alternative for platforms without such a multiplier.
40 */
41#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
Jens Wiklander32b31802023-10-06 16:59:46 +020042static uint64_t mul64(uint32_t a, uint32_t b)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010043{
44 /* a = al + 2**16 ah, b = bl + 2**16 bh */
45 const uint16_t al = (uint16_t) a;
46 const uint16_t bl = (uint16_t) b;
47 const uint16_t ah = a >> 16;
48 const uint16_t bh = b >> 16;
49
50 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
51 const uint32_t lo = (uint32_t) al * bl;
Jens Wiklander32b31802023-10-06 16:59:46 +020052 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010053 const uint32_t hi = (uint32_t) ah * bh;
54
Jens Wiklander32b31802023-10-06 16:59:46 +020055 return lo + (me << 16) + ((uint64_t) hi << 32);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010056}
57#else
Jens Wiklander32b31802023-10-06 16:59:46 +020058static inline uint64_t mul64(uint32_t a, uint32_t b)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010059{
Jens Wiklander32b31802023-10-06 16:59:46 +020060 return (uint64_t) a * b;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010061}
62#endif
63
64
65/**
66 * \brief Process blocks with Poly1305.
67 *
68 * \param ctx The Poly1305 context.
69 * \param nblocks Number of blocks to process. Note that this
70 * function only processes full blocks.
71 * \param input Buffer containing the input block(s).
72 * \param needs_padding Set to 0 if the padding bit has already been
73 * applied to the input data before calling this
74 * function. Otherwise, set this parameter to 1.
75 */
Jens Wiklander32b31802023-10-06 16:59:46 +020076static void poly1305_process(mbedtls_poly1305_context *ctx,
77 size_t nblocks,
78 const unsigned char *input,
79 uint32_t needs_padding)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010080{
81 uint64_t d0, d1, d2, d3;
82 uint32_t acc0, acc1, acc2, acc3, acc4;
83 uint32_t r0, r1, r2, r3;
84 uint32_t rs1, rs2, rs3;
85 size_t offset = 0U;
86 size_t i;
87
88 r0 = ctx->r[0];
89 r1 = ctx->r[1];
90 r2 = ctx->r[2];
91 r3 = ctx->r[3];
92
Jens Wiklander32b31802023-10-06 16:59:46 +020093 rs1 = r1 + (r1 >> 2U);
94 rs2 = r2 + (r2 >> 2U);
95 rs3 = r3 + (r3 >> 2U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +010096
97 acc0 = ctx->acc[0];
98 acc1 = ctx->acc[1];
99 acc2 = ctx->acc[2];
100 acc3 = ctx->acc[3];
101 acc4 = ctx->acc[4];
102
103 /* Process full blocks */
Jens Wiklander32b31802023-10-06 16:59:46 +0200104 for (i = 0U; i < nblocks; i++) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100105 /* The input block is treated as a 128-bit little-endian integer */
Jens Wiklander32b31802023-10-06 16:59:46 +0200106 d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0);
107 d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4);
108 d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8);
109 d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100110
111 /* Compute: acc += (padded) block as a 130-bit integer */
112 d0 += (uint64_t) acc0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200113 d1 += (uint64_t) acc1 + (d0 >> 32U);
114 d2 += (uint64_t) acc2 + (d1 >> 32U);
115 d3 += (uint64_t) acc3 + (d2 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100116 acc0 = (uint32_t) d0;
117 acc1 = (uint32_t) d1;
118 acc2 = (uint32_t) d2;
119 acc3 = (uint32_t) d3;
Jens Wiklander32b31802023-10-06 16:59:46 +0200120 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100121
122 /* Compute: acc *= r */
Jens Wiklander32b31802023-10-06 16:59:46 +0200123 d0 = mul64(acc0, r0) +
124 mul64(acc1, rs3) +
125 mul64(acc2, rs2) +
126 mul64(acc3, rs1);
127 d1 = mul64(acc0, r1) +
128 mul64(acc1, r0) +
129 mul64(acc2, rs3) +
130 mul64(acc3, rs2) +
131 mul64(acc4, rs1);
132 d2 = mul64(acc0, r2) +
133 mul64(acc1, r1) +
134 mul64(acc2, r0) +
135 mul64(acc3, rs3) +
136 mul64(acc4, rs2);
137 d3 = mul64(acc0, r3) +
138 mul64(acc1, r2) +
139 mul64(acc2, r1) +
140 mul64(acc3, r0) +
141 mul64(acc4, rs3);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100142 acc4 *= r0;
143
144 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200145 d1 += (d0 >> 32);
146 d2 += (d1 >> 32);
147 d3 += (d2 >> 32);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100148 acc0 = (uint32_t) d0;
149 acc1 = (uint32_t) d1;
150 acc2 = (uint32_t) d2;
151 acc3 = (uint32_t) d3;
Jens Wiklander32b31802023-10-06 16:59:46 +0200152 acc4 = (uint32_t) (d3 >> 32) + acc4;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100153
Jens Wiklander32b31802023-10-06 16:59:46 +0200154 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100155 acc4 &= 3U;
156 acc0 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200157 d0 = (uint64_t) acc1 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100158 acc1 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200159 d0 = (uint64_t) acc2 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100160 acc2 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200161 d0 = (uint64_t) acc3 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100162 acc3 = (uint32_t) d0;
Jens Wiklander32b31802023-10-06 16:59:46 +0200163 d0 = (uint64_t) acc4 + (d0 >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100164 acc4 = (uint32_t) d0;
165
166 offset += POLY1305_BLOCK_SIZE_BYTES;
167 }
168
169 ctx->acc[0] = acc0;
170 ctx->acc[1] = acc1;
171 ctx->acc[2] = acc2;
172 ctx->acc[3] = acc3;
173 ctx->acc[4] = acc4;
174}
175
176/**
177 * \brief Compute the Poly1305 MAC
178 *
179 * \param ctx The Poly1305 context.
180 * \param mac The buffer to where the MAC is written. Must be
181 * big enough to contain the 16-byte MAC.
182 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200183static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
184 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100185{
186 uint64_t d;
187 uint32_t g0, g1, g2, g3, g4;
188 uint32_t acc0, acc1, acc2, acc3, acc4;
189 uint32_t mask;
190 uint32_t mask_inv;
191
192 acc0 = ctx->acc[0];
193 acc1 = ctx->acc[1];
194 acc2 = ctx->acc[2];
195 acc3 = ctx->acc[3];
196 acc4 = ctx->acc[4];
197
198 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
199 * We do this by calculating acc - (2^130 - 5), then checking if
200 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
201 */
202
203 /* Calculate acc + -(2^130 - 5) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200204 d = ((uint64_t) acc0 + 5U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100205 g0 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200206 d = ((uint64_t) acc1 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100207 g1 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200208 d = ((uint64_t) acc2 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100209 g2 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200210 d = ((uint64_t) acc3 + (d >> 32));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100211 g3 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200212 g4 = acc4 + (uint32_t) (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100213
214 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200215 mask = (uint32_t) 0U - (g4 >> 2U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100216 mask_inv = ~mask;
217
218 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Jens Wiklander32b31802023-10-06 16:59:46 +0200219 acc0 = (acc0 & mask_inv) | (g0 & mask);
220 acc1 = (acc1 & mask_inv) | (g1 & mask);
221 acc2 = (acc2 & mask_inv) | (g2 & mask);
222 acc3 = (acc3 & mask_inv) | (g3 & mask);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100223
224 /* Add 's' */
225 d = (uint64_t) acc0 + ctx->s[0];
226 acc0 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200227 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100228 acc1 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200229 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100230 acc2 = (uint32_t) d;
Jens Wiklander32b31802023-10-06 16:59:46 +0200231 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100232
233 /* Compute MAC (128 least significant bits of the accumulator) */
Jens Wiklander32b31802023-10-06 16:59:46 +0200234 MBEDTLS_PUT_UINT32_LE(acc0, mac, 0);
235 MBEDTLS_PUT_UINT32_LE(acc1, mac, 4);
236 MBEDTLS_PUT_UINT32_LE(acc2, mac, 8);
237 MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100238}
239
Jens Wiklander32b31802023-10-06 16:59:46 +0200240void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100241{
Jens Wiklander32b31802023-10-06 16:59:46 +0200242 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100243}
244
Jens Wiklander32b31802023-10-06 16:59:46 +0200245void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100246{
Jens Wiklander32b31802023-10-06 16:59:46 +0200247 if (ctx == NULL) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100248 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200249 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100250
Jens Wiklander32b31802023-10-06 16:59:46 +0200251 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100252}
253
Jens Wiklander32b31802023-10-06 16:59:46 +0200254int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
255 const unsigned char key[32])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100256{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100257 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Jens Wiklander32b31802023-10-06 16:59:46 +0200258 ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU;
259 ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU;
260 ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU;
261 ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100262
Jens Wiklander32b31802023-10-06 16:59:46 +0200263 ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
264 ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
265 ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
266 ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100267
268 /* Initial accumulator state */
269 ctx->acc[0] = 0U;
270 ctx->acc[1] = 0U;
271 ctx->acc[2] = 0U;
272 ctx->acc[3] = 0U;
273 ctx->acc[4] = 0U;
274
275 /* Queue initially empty */
Jens Wiklander32b31802023-10-06 16:59:46 +0200276 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100277 ctx->queue_len = 0U;
278
Jens Wiklander32b31802023-10-06 16:59:46 +0200279 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100280}
281
Jens Wiklander32b31802023-10-06 16:59:46 +0200282int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
283 const unsigned char *input,
284 size_t ilen)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100285{
286 size_t offset = 0U;
287 size_t remaining = ilen;
288 size_t queue_free_len;
289 size_t nblocks;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100290
Jens Wiklander32b31802023-10-06 16:59:46 +0200291 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
292 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100293
Jens Wiklander32b31802023-10-06 16:59:46 +0200294 if (ilen < queue_free_len) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100295 /* Not enough data to complete the block.
296 * Store this data with the other leftovers.
297 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200298 memcpy(&ctx->queue[ctx->queue_len],
299 input,
300 ilen);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100301
302 ctx->queue_len += ilen;
303
304 remaining = 0U;
Jens Wiklander32b31802023-10-06 16:59:46 +0200305 } else {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100306 /* Enough data to produce a complete block */
Jens Wiklander32b31802023-10-06 16:59:46 +0200307 memcpy(&ctx->queue[ctx->queue_len],
308 input,
309 queue_free_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100310
311 ctx->queue_len = 0U;
312
Jens Wiklander32b31802023-10-06 16:59:46 +0200313 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100314
315 offset += queue_free_len;
316 remaining -= queue_free_len;
317 }
318 }
319
Jens Wiklander32b31802023-10-06 16:59:46 +0200320 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100321 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
322
Jens Wiklander32b31802023-10-06 16:59:46 +0200323 poly1305_process(ctx, nblocks, &input[offset], 1U);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100324
325 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
326 remaining %= POLY1305_BLOCK_SIZE_BYTES;
327 }
328
Jens Wiklander32b31802023-10-06 16:59:46 +0200329 if (remaining > 0U) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100330 /* Store partial block */
331 ctx->queue_len = remaining;
Jens Wiklander32b31802023-10-06 16:59:46 +0200332 memcpy(ctx->queue, &input[offset], remaining);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100333 }
334
Jens Wiklander32b31802023-10-06 16:59:46 +0200335 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100336}
337
Jens Wiklander32b31802023-10-06 16:59:46 +0200338int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
339 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100340{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100341 /* Process any leftover data */
Jens Wiklander32b31802023-10-06 16:59:46 +0200342 if (ctx->queue_len > 0U) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100343 /* Add padding bit */
344 ctx->queue[ctx->queue_len] = 1U;
345 ctx->queue_len++;
346
347 /* Pad with zeroes */
Jens Wiklander32b31802023-10-06 16:59:46 +0200348 memset(&ctx->queue[ctx->queue_len],
349 0,
350 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100351
Jens Wiklander32b31802023-10-06 16:59:46 +0200352 poly1305_process(ctx, 1U, /* Process 1 block */
353 ctx->queue, 0U); /* Already padded above */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100354 }
355
Jens Wiklander32b31802023-10-06 16:59:46 +0200356 poly1305_compute_mac(ctx, mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100357
Jens Wiklander32b31802023-10-06 16:59:46 +0200358 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100359}
360
Jens Wiklander32b31802023-10-06 16:59:46 +0200361int mbedtls_poly1305_mac(const unsigned char key[32],
362 const unsigned char *input,
363 size_t ilen,
364 unsigned char mac[16])
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100365{
366 mbedtls_poly1305_context ctx;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100368
Jens Wiklander32b31802023-10-06 16:59:46 +0200369 mbedtls_poly1305_init(&ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100370
Jens Wiklander32b31802023-10-06 16:59:46 +0200371 ret = mbedtls_poly1305_starts(&ctx, key);
372 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100373 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200374 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100375
Jens Wiklander32b31802023-10-06 16:59:46 +0200376 ret = mbedtls_poly1305_update(&ctx, input, ilen);
377 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100378 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +0200379 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100380
Jens Wiklander32b31802023-10-06 16:59:46 +0200381 ret = mbedtls_poly1305_finish(&ctx, mac);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100382
383cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +0200384 mbedtls_poly1305_free(&ctx);
385 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100386}
387
388#endif /* MBEDTLS_POLY1305_ALT */
389
390#if defined(MBEDTLS_SELF_TEST)
391
392static const unsigned char test_keys[2][32] =
393{
394 {
395 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
396 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
397 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
398 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
399 },
400 {
401 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
402 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
403 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
404 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
405 }
406};
407
408static const unsigned char test_data[2][127] =
409{
410 {
411 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
412 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
413 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
414 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
415 0x75, 0x70
416 },
417 {
418 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
419 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
420 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
421 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
422 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
423 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
424 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
425 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
426 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
427 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
428 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
429 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
430 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
431 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
432 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
433 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
434 }
435};
436
437static const size_t test_data_len[2] =
438{
439 34U,
440 127U
441};
442
443static const unsigned char test_mac[2][16] =
444{
445 {
446 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
447 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
448 },
449 {
450 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
451 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
452 }
453};
454
Jerome Forissier79013242021-07-28 10:24:04 +0200455/* Make sure no other definition is already present. */
456#undef ASSERT
457
Jens Wiklander32b31802023-10-06 16:59:46 +0200458#define ASSERT(cond, args) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100459 do \
460 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200461 if (!(cond)) \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100462 { \
Jens Wiklander32b31802023-10-06 16:59:46 +0200463 if (verbose != 0) \
464 mbedtls_printf args; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100465 \
Jens Wiklander32b31802023-10-06 16:59:46 +0200466 return -1; \
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100467 } \
468 } \
Jens Wiklander32b31802023-10-06 16:59:46 +0200469 while (0)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100470
Jens Wiklander32b31802023-10-06 16:59:46 +0200471int mbedtls_poly1305_self_test(int verbose)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100472{
473 unsigned char mac[16];
474 unsigned i;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200475 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100476
Jens Wiklander32b31802023-10-06 16:59:46 +0200477 for (i = 0U; i < 2U; i++) {
478 if (verbose != 0) {
479 mbedtls_printf(" Poly1305 test %u ", i);
480 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100481
Jens Wiklander32b31802023-10-06 16:59:46 +0200482 ret = mbedtls_poly1305_mac(test_keys[i],
483 test_data[i],
484 test_data_len[i],
485 mac);
486 ASSERT(0 == ret, ("error code: %i\n", ret));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100487
Jens Wiklander32b31802023-10-06 16:59:46 +0200488 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100489
Jens Wiklander32b31802023-10-06 16:59:46 +0200490 if (verbose != 0) {
491 mbedtls_printf("passed\n");
492 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100493 }
494
Jens Wiklander32b31802023-10-06 16:59:46 +0200495 if (verbose != 0) {
496 mbedtls_printf("\n");
497 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100498
Jens Wiklander32b31802023-10-06 16:59:46 +0200499 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100500}
501
502#endif /* MBEDTLS_SELF_TEST */
503
504#endif /* MBEDTLS_POLY1305_C */