blob: 81a484691a8da5d0f52d516b22a13182be56c14a [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 Rodgman16799db2023-11-02 19:47:20 +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
Gilles Peskine449bd832023-01-11 14:50:10 +010021#define POLY1305_BLOCK_SIZE_BYTES (16U)
Daniel Kingadc32c02016-05-16 18:25:45 -030022
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020023/*
24 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
25 * However we provided an alternative for platforms without such a multiplier.
26 */
27#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
Gilles Peskine449bd832023-01-11 14:50:10 +010028static uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020029{
30 /* a = al + 2**16 ah, b = bl + 2**16 bh */
31 const uint16_t al = (uint16_t) a;
Joe Subbiani51b147a2021-07-16 17:47:17 +010032 const uint16_t bl = (uint16_t) b;
Joe Subbiani4919bb42021-07-16 17:14:07 +010033 const uint16_t ah = a >> 16;
34 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020035
36 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
37 const uint32_t lo = (uint32_t) al * bl;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020039 const uint32_t hi = (uint32_t) ah * bh;
40
Gilles Peskine449bd832023-01-11 14:50:10 +010041 return lo + (me << 16) + ((uint64_t) hi << 32);
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020042}
43#else
Gilles Peskine449bd832023-01-11 14:50:10 +010044static inline uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020045{
Gilles Peskine449bd832023-01-11 14:50:10 +010046 return (uint64_t) a * b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020047}
48#endif
49
50
Daniel Kingadc32c02016-05-16 18:25:45 -030051/**
52 * \brief Process blocks with Poly1305.
53 *
54 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020055 * \param nblocks Number of blocks to process. Note that this
56 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030057 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020058 * \param needs_padding Set to 0 if the padding bit has already been
59 * applied to the input data before calling this
60 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030061 */
Gilles Peskine449bd832023-01-11 14:50:10 +010062static void poly1305_process(mbedtls_poly1305_context *ctx,
63 size_t nblocks,
64 const unsigned char *input,
65 uint32_t needs_padding)
Daniel Kingadc32c02016-05-16 18:25:45 -030066{
67 uint64_t d0, d1, d2, d3;
68 uint32_t acc0, acc1, acc2, acc3, acc4;
69 uint32_t r0, r1, r2, r3;
70 uint32_t rs1, rs2, rs3;
71 size_t offset = 0U;
72 size_t i;
73
74 r0 = ctx->r[0];
75 r1 = ctx->r[1];
76 r2 = ctx->r[2];
77 r3 = ctx->r[3];
78
Gilles Peskine449bd832023-01-11 14:50:10 +010079 rs1 = r1 + (r1 >> 2U);
80 rs2 = r2 + (r2 >> 2U);
81 rs3 = r3 + (r3 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -030082
83 acc0 = ctx->acc[0];
84 acc1 = ctx->acc[1];
85 acc2 = ctx->acc[2];
86 acc3 = ctx->acc[3];
87 acc4 = ctx->acc[4];
88
89 /* Process full blocks */
Gilles Peskine449bd832023-01-11 14:50:10 +010090 for (i = 0U; i < nblocks; i++) {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020091 /* The input block is treated as a 128-bit little-endian integer */
Gilles Peskine449bd832023-01-11 14:50:10 +010092 d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0);
93 d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4);
94 d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8);
95 d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12);
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020096
97 /* Compute: acc += (padded) block as a 130-bit integer */
98 d0 += (uint64_t) acc0;
Gilles Peskine449bd832023-01-11 14:50:10 +010099 d1 += (uint64_t) acc1 + (d0 >> 32U);
100 d2 += (uint64_t) acc2 + (d1 >> 32U);
101 d3 += (uint64_t) acc3 + (d2 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300102 acc0 = (uint32_t) d0;
103 acc1 = (uint32_t) d1;
104 acc2 = (uint32_t) d2;
105 acc3 = (uint32_t) d3;
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300107
108 /* Compute: acc *= r */
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 d0 = mul64(acc0, r0) +
110 mul64(acc1, rs3) +
111 mul64(acc2, rs2) +
112 mul64(acc3, rs1);
113 d1 = mul64(acc0, r1) +
114 mul64(acc1, r0) +
115 mul64(acc2, rs3) +
116 mul64(acc3, rs2) +
117 mul64(acc4, rs1);
118 d2 = mul64(acc0, r2) +
119 mul64(acc1, r1) +
120 mul64(acc2, r0) +
121 mul64(acc3, rs3) +
122 mul64(acc4, rs2);
123 d3 = mul64(acc0, r3) +
124 mul64(acc1, r2) +
125 mul64(acc2, r1) +
126 mul64(acc3, r0) +
127 mul64(acc4, rs3);
Daniel Kingadc32c02016-05-16 18:25:45 -0300128 acc4 *= r0;
129
130 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 d1 += (d0 >> 32);
132 d2 += (d1 >> 32);
133 d3 += (d2 >> 32);
Daniel Kinge6e79682016-05-24 11:16:17 -0300134 acc0 = (uint32_t) d0;
135 acc1 = (uint32_t) d1;
136 acc2 = (uint32_t) d2;
137 acc3 = (uint32_t) d3;
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 acc4 = (uint32_t) (d3 >> 32) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Daniel Kingadc32c02016-05-16 18:25:45 -0300141 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300142 acc0 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 d0 = (uint64_t) acc1 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300144 acc1 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 d0 = (uint64_t) acc2 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300146 acc2 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 d0 = (uint64_t) acc3 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300148 acc3 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 d0 = (uint64_t) acc4 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300150 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300151
152 offset += POLY1305_BLOCK_SIZE_BYTES;
153 }
154
155 ctx->acc[0] = acc0;
156 ctx->acc[1] = acc1;
157 ctx->acc[2] = acc2;
158 ctx->acc[3] = acc3;
159 ctx->acc[4] = acc4;
160}
161
162/**
163 * \brief Compute the Poly1305 MAC
164 *
165 * \param ctx The Poly1305 context.
166 * \param mac The buffer to where the MAC is written. Must be
167 * big enough to contain the 16-byte MAC.
168 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100169static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
170 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300171{
172 uint64_t d;
173 uint32_t g0, g1, g2, g3, g4;
174 uint32_t acc0, acc1, acc2, acc3, acc4;
175 uint32_t mask;
176 uint32_t mask_inv;
177
178 acc0 = ctx->acc[0];
179 acc1 = ctx->acc[1];
180 acc2 = ctx->acc[2];
181 acc3 = ctx->acc[3];
182 acc4 = ctx->acc[4];
183
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200184 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300185 * We do this by calculating acc - (2^130 - 5), then checking if
186 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
187 */
188
189 /* Calculate acc + -(2^130 - 5) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 d = ((uint64_t) acc0 + 5U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300191 g0 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 d = ((uint64_t) acc1 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300193 g1 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 d = ((uint64_t) acc2 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300195 g2 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 d = ((uint64_t) acc3 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300197 g3 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 g4 = acc4 + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300199
200 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 mask = (uint32_t) 0U - (g4 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300202 mask_inv = ~mask;
203
204 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 acc0 = (acc0 & mask_inv) | (g0 & mask);
206 acc1 = (acc1 & mask_inv) | (g1 & mask);
207 acc2 = (acc2 & mask_inv) | (g2 & mask);
208 acc3 = (acc3 & mask_inv) | (g3 & mask);
Daniel Kingadc32c02016-05-16 18:25:45 -0300209
210 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300211 d = (uint64_t) acc0 + ctx->s[0];
212 acc0 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300214 acc1 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300216 acc2 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300218
219 /* Compute MAC (128 least significant bits of the accumulator) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 MBEDTLS_PUT_UINT32_LE(acc0, mac, 0);
221 MBEDTLS_PUT_UINT32_LE(acc1, mac, 4);
222 MBEDTLS_PUT_UINT32_LE(acc2, mac, 8);
223 MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
Daniel Kingadc32c02016-05-16 18:25:45 -0300224}
225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300227{
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300229}
230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300232{
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (ctx == NULL) {
Hanno Becker305e4e42018-12-11 15:03:16 +0000234 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 }
Hanno Becker305e4e42018-12-11 15:03:16 +0000236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300238}
239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
241 const unsigned char key[32])
Daniel Kingadc32c02016-05-16 18:25:45 -0300242{
Daniel Kingadc32c02016-05-16 18:25:45 -0300243 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU;
245 ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU;
246 ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU;
247 ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
250 ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
251 ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
252 ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
Daniel Kingadc32c02016-05-16 18:25:45 -0300253
254 /* Initial accumulator state */
255 ctx->acc[0] = 0U;
256 ctx->acc[1] = 0U;
257 ctx->acc[2] = 0U;
258 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200259 ctx->acc[4] = 0U;
260
261 /* Queue initially empty */
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200263 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300266}
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
269 const unsigned char *input,
270 size_t ilen)
Daniel Kingadc32c02016-05-16 18:25:45 -0300271{
272 size_t offset = 0U;
273 size_t remaining = ilen;
274 size_t queue_free_len;
275 size_t nblocks;
Daniel Kingadc32c02016-05-16 18:25:45 -0300276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
278 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 if (ilen < queue_free_len) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300281 /* Not enough data to complete the block.
282 * Store this data with the other leftovers.
283 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 memcpy(&ctx->queue[ctx->queue_len],
285 input,
286 ilen);
Daniel Kingadc32c02016-05-16 18:25:45 -0300287
288 ctx->queue_len += ilen;
289
290 remaining = 0U;
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 } else {
Daniel Kingadc32c02016-05-16 18:25:45 -0300292 /* Enough data to produce a complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 memcpy(&ctx->queue[ctx->queue_len],
294 input,
295 queue_free_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300296
297 ctx->queue_len = 0U;
298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300300
301 offset += queue_free_len;
302 remaining -= queue_free_len;
303 }
304 }
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300307 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 poly1305_process(ctx, nblocks, &input[offset], 1U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300310
311 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
312 remaining %= POLY1305_BLOCK_SIZE_BYTES;
313 }
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 if (remaining > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300316 /* Store partial block */
317 ctx->queue_len = remaining;
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 memcpy(ctx->queue, &input[offset], remaining);
Daniel Kingadc32c02016-05-16 18:25:45 -0300319 }
320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300322}
323
Gilles Peskine449bd832023-01-11 14:50:10 +0100324int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
325 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300326{
Daniel Kingadc32c02016-05-16 18:25:45 -0300327 /* Process any leftover data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 if (ctx->queue_len > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300329 /* Add padding bit */
330 ctx->queue[ctx->queue_len] = 1U;
331 ctx->queue_len++;
332
333 /* Pad with zeroes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 memset(&ctx->queue[ctx->queue_len],
335 0,
336 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 poly1305_process(ctx, 1U, /* Process 1 block */
339 ctx->queue, 0U); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300340 }
341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 poly1305_compute_mac(ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300345}
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347int mbedtls_poly1305_mac(const unsigned char key[32],
348 const unsigned char *input,
349 size_t ilen,
350 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300351{
352 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000353 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 mbedtls_poly1305_init(&ctx);
Daniel Kingadc32c02016-05-16 18:25:45 -0300356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 ret = mbedtls_poly1305_starts(&ctx, key);
358 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300359 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 ret = mbedtls_poly1305_update(&ctx, input, ilen);
363 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300364 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 ret = mbedtls_poly1305_finish(&ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300368
369cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 mbedtls_poly1305_free(&ctx);
371 return ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300372}
373
374#if defined(MBEDTLS_SELF_TEST)
375
376static const unsigned char test_keys[2][32] =
377{
378 {
379 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
380 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
381 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
382 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
383 },
384 {
385 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
386 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
387 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
388 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
389 }
390};
391
392static const unsigned char test_data[2][127] =
393{
394 {
395 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
396 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
397 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
398 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
399 0x75, 0x70
400 },
401 {
402 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
403 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
404 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
405 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
406 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
407 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
408 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
409 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
410 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
411 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
412 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
413 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
414 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
415 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
416 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
417 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
418 }
419};
420
421static const size_t test_data_len[2] =
422{
423 34U,
424 127U
425};
426
427static const unsigned char test_mac[2][16] =
428{
429 {
430 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
431 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
432 },
433 {
434 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
435 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
436 }
437};
438
Ouss4e0b26872020-08-11 16:07:09 +0100439/* Make sure no other definition is already present. */
440#undef ASSERT
441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442#define ASSERT(cond, args) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200443 do \
444 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 if (!(cond)) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200446 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 if (verbose != 0) \
448 mbedtls_printf args; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200449 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 return -1; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200451 } \
452 } \
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 while (0)
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455int mbedtls_poly1305_self_test(int verbose)
Daniel Kingadc32c02016-05-16 18:25:45 -0300456{
Daniel Kinge6e79682016-05-24 11:16:17 -0300457 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200458 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300460
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 for (i = 0U; i < 2U; i++) {
462 if (verbose != 0) {
463 mbedtls_printf(" Poly1305 test %u ", i);
464 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 ret = mbedtls_poly1305_mac(test_keys[i],
467 test_data[i],
468 test_data_len[i],
469 mac);
470 ASSERT(0 == ret, ("error code: %i\n", ret));
Daniel Kingadc32c02016-05-16 18:25:45 -0300471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Daniel Kingadc32c02016-05-16 18:25:45 -0300473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (verbose != 0) {
475 mbedtls_printf("passed\n");
476 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300477 }
478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 if (verbose != 0) {
480 mbedtls_printf("\n");
481 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300484}
485
486#endif /* MBEDTLS_SELF_TEST */
487
488#endif /* MBEDTLS_POLY1305_C */