blob: c78110760202a216ae071527faec0111795ec8a0 [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
Dave Rodgman7ff79652023-11-03 12:04:52 +00007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Daniel Kingadc32c02016-05-16 18:25:45 -03008 */
Gilles Peskinedb09ef62020-06-03 01:43:33 +02009#include "common.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030010
11#if defined(MBEDTLS_POLY1305_C)
12
Daniel Kingadc32c02016-05-16 18:25:45 -030013#include "mbedtls/poly1305.h"
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020014#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000015#include "mbedtls/error.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030016
17#include <string.h>
18
Daniel Kingadc32c02016-05-16 18:25:45 -030019#include "mbedtls/platform.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030020
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020021#if !defined(MBEDTLS_POLY1305_ALT)
22
Hanno Becker305e4e42018-12-11 15:03:16 +000023/* Parameter validation macros */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010024#define POLY1305_VALIDATE_RET(cond) \
25 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA)
26#define POLY1305_VALIDATE(cond) \
27 MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker305e4e42018-12-11 15:03:16 +000028
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010029#define POLY1305_BLOCK_SIZE_BYTES (16U)
Daniel Kingadc32c02016-05-16 18:25:45 -030030
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020031/*
32 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
33 * However we provided an alternative for platforms without such a multiplier.
34 */
35#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010036static uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020037{
38 /* a = al + 2**16 ah, b = bl + 2**16 bh */
39 const uint16_t al = (uint16_t) a;
Joe Subbiani197e9ed2021-07-16 17:47:17 +010040 const uint16_t bl = (uint16_t) b;
Joe Subbiani281956d2021-07-16 17:14:07 +010041 const uint16_t ah = a >> 16;
42 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020043
44 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
45 const uint32_t lo = (uint32_t) al * bl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010046 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020047 const uint32_t hi = (uint32_t) ah * bh;
48
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010049 return lo + (me << 16) + ((uint64_t) hi << 32);
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020050}
51#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010052static inline uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020053{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 return (uint64_t) a * b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020055}
56#endif
57
58
Daniel Kingadc32c02016-05-16 18:25:45 -030059/**
60 * \brief Process blocks with Poly1305.
61 *
62 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020063 * \param nblocks Number of blocks to process. Note that this
64 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030065 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020066 * \param needs_padding Set to 0 if the padding bit has already been
67 * applied to the input data before calling this
68 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030069 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010070static void poly1305_process(mbedtls_poly1305_context *ctx,
71 size_t nblocks,
72 const unsigned char *input,
73 uint32_t needs_padding)
Daniel Kingadc32c02016-05-16 18:25:45 -030074{
75 uint64_t d0, d1, d2, d3;
76 uint32_t acc0, acc1, acc2, acc3, acc4;
77 uint32_t r0, r1, r2, r3;
78 uint32_t rs1, rs2, rs3;
79 size_t offset = 0U;
80 size_t i;
81
82 r0 = ctx->r[0];
83 r1 = ctx->r[1];
84 r2 = ctx->r[2];
85 r3 = ctx->r[3];
86
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010087 rs1 = r1 + (r1 >> 2U);
88 rs2 = r2 + (r2 >> 2U);
89 rs3 = r3 + (r3 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -030090
91 acc0 = ctx->acc[0];
92 acc1 = ctx->acc[1];
93 acc2 = ctx->acc[2];
94 acc3 = ctx->acc[3];
95 acc4 = ctx->acc[4];
96
97 /* Process full blocks */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 for (i = 0U; i < nblocks; i++) {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020099 /* The input block is treated as a 128-bit little-endian integer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0);
101 d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4);
102 d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8);
103 d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12);
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200104
105 /* Compute: acc += (padded) block as a 130-bit integer */
106 d0 += (uint64_t) acc0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 d1 += (uint64_t) acc1 + (d0 >> 32U);
108 d2 += (uint64_t) acc2 + (d1 >> 32U);
109 d3 += (uint64_t) acc3 + (d2 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300110 acc0 = (uint32_t) d0;
111 acc1 = (uint32_t) d1;
112 acc2 = (uint32_t) d2;
113 acc3 = (uint32_t) d3;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100114 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300115
116 /* Compute: acc *= r */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 d0 = mul64(acc0, r0) +
118 mul64(acc1, rs3) +
119 mul64(acc2, rs2) +
120 mul64(acc3, rs1);
121 d1 = mul64(acc0, r1) +
122 mul64(acc1, r0) +
123 mul64(acc2, rs3) +
124 mul64(acc3, rs2) +
125 mul64(acc4, rs1);
126 d2 = mul64(acc0, r2) +
127 mul64(acc1, r1) +
128 mul64(acc2, r0) +
129 mul64(acc3, rs3) +
130 mul64(acc4, rs2);
131 d3 = mul64(acc0, r3) +
132 mul64(acc1, r2) +
133 mul64(acc2, r1) +
134 mul64(acc3, r0) +
135 mul64(acc4, rs3);
Daniel Kingadc32c02016-05-16 18:25:45 -0300136 acc4 *= r0;
137
138 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 d1 += (d0 >> 32);
140 d2 += (d1 >> 32);
141 d3 += (d2 >> 32);
Daniel Kinge6e79682016-05-24 11:16:17 -0300142 acc0 = (uint32_t) d0;
143 acc1 = (uint32_t) d1;
144 acc2 = (uint32_t) d2;
145 acc3 = (uint32_t) d3;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 acc4 = (uint32_t) (d3 >> 32) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300147
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100148 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Daniel Kingadc32c02016-05-16 18:25:45 -0300149 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300150 acc0 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 d0 = (uint64_t) acc1 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300152 acc1 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153 d0 = (uint64_t) acc2 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300154 acc2 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155 d0 = (uint64_t) acc3 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300156 acc3 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100157 d0 = (uint64_t) acc4 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300158 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300159
160 offset += POLY1305_BLOCK_SIZE_BYTES;
161 }
162
163 ctx->acc[0] = acc0;
164 ctx->acc[1] = acc1;
165 ctx->acc[2] = acc2;
166 ctx->acc[3] = acc3;
167 ctx->acc[4] = acc4;
168}
169
170/**
171 * \brief Compute the Poly1305 MAC
172 *
173 * \param ctx The Poly1305 context.
174 * \param mac The buffer to where the MAC is written. Must be
175 * big enough to contain the 16-byte MAC.
176 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
178 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300179{
180 uint64_t d;
181 uint32_t g0, g1, g2, g3, g4;
182 uint32_t acc0, acc1, acc2, acc3, acc4;
183 uint32_t mask;
184 uint32_t mask_inv;
185
186 acc0 = ctx->acc[0];
187 acc1 = ctx->acc[1];
188 acc2 = ctx->acc[2];
189 acc3 = ctx->acc[3];
190 acc4 = ctx->acc[4];
191
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200192 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300193 * We do this by calculating acc - (2^130 - 5), then checking if
194 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
195 */
196
197 /* Calculate acc + -(2^130 - 5) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100198 d = ((uint64_t) acc0 + 5U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300199 g0 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100200 d = ((uint64_t) acc1 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300201 g1 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100202 d = ((uint64_t) acc2 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300203 g2 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 d = ((uint64_t) acc3 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300205 g3 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100206 g4 = acc4 + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300207
208 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 mask = (uint32_t) 0U - (g4 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300210 mask_inv = ~mask;
211
212 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100213 acc0 = (acc0 & mask_inv) | (g0 & mask);
214 acc1 = (acc1 & mask_inv) | (g1 & mask);
215 acc2 = (acc2 & mask_inv) | (g2 & mask);
216 acc3 = (acc3 & mask_inv) | (g3 & mask);
Daniel Kingadc32c02016-05-16 18:25:45 -0300217
218 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300219 d = (uint64_t) acc0 + ctx->s[0];
220 acc0 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100221 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300222 acc1 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100223 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300224 acc2 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300226
227 /* Compute MAC (128 least significant bits of the accumulator) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228 MBEDTLS_PUT_UINT32_LE(acc0, mac, 0);
229 MBEDTLS_PUT_UINT32_LE(acc1, mac, 4);
230 MBEDTLS_PUT_UINT32_LE(acc2, mac, 8);
231 MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
Daniel Kingadc32c02016-05-16 18:25:45 -0300232}
233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300235{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100236 POLY1305_VALIDATE(ctx != NULL);
Hanno Becker305e4e42018-12-11 15:03:16 +0000237
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300239}
240
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300242{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243 if (ctx == NULL) {
Hanno Becker305e4e42018-12-11 15:03:16 +0000244 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245 }
Hanno Becker305e4e42018-12-11 15:03:16 +0000246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300248}
249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
251 const unsigned char key[32])
Daniel Kingadc32c02016-05-16 18:25:45 -0300252{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253 POLY1305_VALIDATE_RET(ctx != NULL);
254 POLY1305_VALIDATE_RET(key != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300255
256 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU;
258 ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU;
259 ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU;
260 ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262 ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
263 ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
264 ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
265 ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
Daniel Kingadc32c02016-05-16 18:25:45 -0300266
267 /* Initial accumulator state */
268 ctx->acc[0] = 0U;
269 ctx->acc[1] = 0U;
270 ctx->acc[2] = 0U;
271 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200272 ctx->acc[4] = 0U;
273
274 /* Queue initially empty */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100275 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200276 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300277
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300279}
280
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
282 const unsigned char *input,
283 size_t ilen)
Daniel Kingadc32c02016-05-16 18:25:45 -0300284{
285 size_t offset = 0U;
286 size_t remaining = ilen;
287 size_t queue_free_len;
288 size_t nblocks;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 POLY1305_VALIDATE_RET(ctx != NULL);
290 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
293 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300294
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 if (ilen < queue_free_len) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300296 /* Not enough data to complete the block.
297 * Store this data with the other leftovers.
298 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100299 memcpy(&ctx->queue[ctx->queue_len],
300 input,
301 ilen);
Daniel Kingadc32c02016-05-16 18:25:45 -0300302
303 ctx->queue_len += ilen;
304
305 remaining = 0U;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 } else {
Daniel Kingadc32c02016-05-16 18:25:45 -0300307 /* Enough data to produce a complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100308 memcpy(&ctx->queue[ctx->queue_len],
309 input,
310 queue_free_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300311
312 ctx->queue_len = 0U;
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300315
316 offset += queue_free_len;
317 remaining -= queue_free_len;
318 }
319 }
320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300322 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324 poly1305_process(ctx, nblocks, &input[offset], 1U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300325
326 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
327 remaining %= POLY1305_BLOCK_SIZE_BYTES;
328 }
329
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100330 if (remaining > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300331 /* Store partial block */
332 ctx->queue_len = remaining;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 memcpy(ctx->queue, &input[offset], remaining);
Daniel Kingadc32c02016-05-16 18:25:45 -0300334 }
335
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300337}
338
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
340 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300341{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 POLY1305_VALIDATE_RET(ctx != NULL);
343 POLY1305_VALIDATE_RET(mac != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300344
345 /* Process any leftover data */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100346 if (ctx->queue_len > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300347 /* Add padding bit */
348 ctx->queue[ctx->queue_len] = 1U;
349 ctx->queue_len++;
350
351 /* Pad with zeroes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100352 memset(&ctx->queue[ctx->queue_len],
353 0,
354 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300355
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100356 poly1305_process(ctx, 1U, /* Process 1 block */
357 ctx->queue, 0U); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300358 }
359
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 poly1305_compute_mac(ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300363}
364
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100365int mbedtls_poly1305_mac(const unsigned char key[32],
366 const unsigned char *input,
367 size_t ilen,
368 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300369{
370 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000371 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 POLY1305_VALIDATE_RET(key != NULL);
373 POLY1305_VALIDATE_RET(mac != NULL);
374 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300375
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100376 mbedtls_poly1305_init(&ctx);
Daniel Kingadc32c02016-05-16 18:25:45 -0300377
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 ret = mbedtls_poly1305_starts(&ctx, key);
379 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300380 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 ret = mbedtls_poly1305_update(&ctx, input, ilen);
384 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300385 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100386 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 ret = mbedtls_poly1305_finish(&ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300389
390cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 mbedtls_poly1305_free(&ctx);
392 return ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300393}
394
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200395#endif /* MBEDTLS_POLY1305_ALT */
396
Daniel Kingadc32c02016-05-16 18:25:45 -0300397#if defined(MBEDTLS_SELF_TEST)
398
399static const unsigned char test_keys[2][32] =
400{
401 {
402 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
403 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
404 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
405 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
406 },
407 {
408 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
409 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
410 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
411 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
412 }
413};
414
415static const unsigned char test_data[2][127] =
416{
417 {
418 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
419 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
420 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
421 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
422 0x75, 0x70
423 },
424 {
425 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
426 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
427 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
428 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
429 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
430 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
431 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
432 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
433 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
434 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
435 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
436 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
437 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
438 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
439 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
440 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
441 }
442};
443
444static const size_t test_data_len[2] =
445{
446 34U,
447 127U
448};
449
450static const unsigned char test_mac[2][16] =
451{
452 {
453 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
454 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
455 },
456 {
457 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
458 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
459 }
460};
461
Ouss4e0b26872020-08-11 16:07:09 +0100462/* Make sure no other definition is already present. */
463#undef ASSERT
464
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100465#define ASSERT(cond, args) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200466 do \
467 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100468 if (!(cond)) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200469 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100470 if (verbose != 0) \
471 mbedtls_printf args; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200472 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100473 return -1; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200474 } \
475 } \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100476 while (0)
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100478int mbedtls_poly1305_self_test(int verbose)
Daniel Kingadc32c02016-05-16 18:25:45 -0300479{
Daniel Kinge6e79682016-05-24 11:16:17 -0300480 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200481 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000482 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300483
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100484 for (i = 0U; i < 2U; i++) {
485 if (verbose != 0) {
486 mbedtls_printf(" Poly1305 test %u ", i);
487 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 ret = mbedtls_poly1305_mac(test_keys[i],
490 test_data[i],
491 test_data_len[i],
492 mac);
493 ASSERT(0 == ret, ("error code: %i\n", ret));
Daniel Kingadc32c02016-05-16 18:25:45 -0300494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100495 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Daniel Kingadc32c02016-05-16 18:25:45 -0300496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 if (verbose != 0) {
498 mbedtls_printf("passed\n");
499 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300500 }
501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 if (verbose != 0) {
503 mbedtls_printf("\n");
504 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300507}
508
509#endif /* MBEDTLS_SELF_TEST */
510
511#endif /* MBEDTLS_POLY1305_C */