blob: f4e1d3f8807c55b532e75f2b9f39ee4d8f0186bf [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
Daniel Kingadc32c02016-05-16 18:25:45 -030031#include "mbedtls/platform.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030032
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020033#if !defined(MBEDTLS_POLY1305_ALT)
34
Gilles Peskine449bd832023-01-11 14:50:10 +010035#define POLY1305_BLOCK_SIZE_BYTES (16U)
Daniel Kingadc32c02016-05-16 18:25:45 -030036
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020037/*
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)
Gilles Peskine449bd832023-01-11 14:50:10 +010042static uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020043{
44 /* a = al + 2**16 ah, b = bl + 2**16 bh */
45 const uint16_t al = (uint16_t) a;
Joe Subbiani51b147a2021-07-16 17:47:17 +010046 const uint16_t bl = (uint16_t) b;
Joe Subbiani4919bb42021-07-16 17:14:07 +010047 const uint16_t ah = a >> 16;
48 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020049
50 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
51 const uint32_t lo = (uint32_t) al * bl;
Gilles Peskine449bd832023-01-11 14:50:10 +010052 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020053 const uint32_t hi = (uint32_t) ah * bh;
54
Gilles Peskine449bd832023-01-11 14:50:10 +010055 return lo + (me << 16) + ((uint64_t) hi << 32);
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020056}
57#else
Gilles Peskine449bd832023-01-11 14:50:10 +010058static inline uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020059{
Gilles Peskine449bd832023-01-11 14:50:10 +010060 return (uint64_t) a * b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020061}
62#endif
63
64
Daniel Kingadc32c02016-05-16 18:25:45 -030065/**
66 * \brief Process blocks with Poly1305.
67 *
68 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020069 * \param nblocks Number of blocks to process. Note that this
70 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030071 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020072 * \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.
Daniel Kingadc32c02016-05-16 18:25:45 -030075 */
Gilles Peskine449bd832023-01-11 14:50:10 +010076static void poly1305_process(mbedtls_poly1305_context *ctx,
77 size_t nblocks,
78 const unsigned char *input,
79 uint32_t needs_padding)
Daniel Kingadc32c02016-05-16 18:25:45 -030080{
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
Gilles Peskine449bd832023-01-11 14:50:10 +010093 rs1 = r1 + (r1 >> 2U);
94 rs2 = r2 + (r2 >> 2U);
95 rs3 = r3 + (r3 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -030096
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 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 for (i = 0U; i < nblocks; i++) {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200105 /* The input block is treated as a 128-bit little-endian integer */
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 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);
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200110
111 /* Compute: acc += (padded) block as a 130-bit integer */
112 d0 += (uint64_t) acc0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 d1 += (uint64_t) acc1 + (d0 >> 32U);
114 d2 += (uint64_t) acc2 + (d1 >> 32U);
115 d3 += (uint64_t) acc3 + (d2 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300116 acc0 = (uint32_t) d0;
117 acc1 = (uint32_t) d1;
118 acc2 = (uint32_t) d2;
119 acc3 = (uint32_t) d3;
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300121
122 /* Compute: acc *= r */
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 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);
Daniel Kingadc32c02016-05-16 18:25:45 -0300142 acc4 *= r0;
143
144 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 d1 += (d0 >> 32);
146 d2 += (d1 >> 32);
147 d3 += (d2 >> 32);
Daniel Kinge6e79682016-05-24 11:16:17 -0300148 acc0 = (uint32_t) d0;
149 acc1 = (uint32_t) d1;
150 acc2 = (uint32_t) d2;
151 acc3 = (uint32_t) d3;
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 acc4 = (uint32_t) (d3 >> 32) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Daniel Kingadc32c02016-05-16 18:25:45 -0300155 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300156 acc0 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 d0 = (uint64_t) acc1 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300158 acc1 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100159 d0 = (uint64_t) acc2 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300160 acc2 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 d0 = (uint64_t) acc3 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300162 acc3 = (uint32_t) d0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 d0 = (uint64_t) acc4 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300164 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300165
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 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100183static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
184 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300185{
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
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200198 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300199 * 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) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 d = ((uint64_t) acc0 + 5U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300205 g0 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 d = ((uint64_t) acc1 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300207 g1 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 d = ((uint64_t) acc2 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300209 g2 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 d = ((uint64_t) acc3 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300211 g3 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 g4 = acc4 + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300213
214 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 mask = (uint32_t) 0U - (g4 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300216 mask_inv = ~mask;
217
218 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 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);
Daniel Kingadc32c02016-05-16 18:25:45 -0300223
224 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300225 d = (uint64_t) acc0 + ctx->s[0];
226 acc0 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300228 acc1 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300230 acc2 = (uint32_t) d;
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300232
233 /* Compute MAC (128 least significant bits of the accumulator) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 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);
Daniel Kingadc32c02016-05-16 18:25:45 -0300238}
239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300241{
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300243}
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300246{
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (ctx == NULL) {
Hanno Becker305e4e42018-12-11 15:03:16 +0000248 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Hanno Becker305e4e42018-12-11 15:03:16 +0000250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300252}
253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
255 const unsigned char key[32])
Daniel Kingadc32c02016-05-16 18:25:45 -0300256{
Daniel Kingadc32c02016-05-16 18:25:45 -0300257 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 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;
Daniel Kingadc32c02016-05-16 18:25:45 -0300262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 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);
Daniel Kingadc32c02016-05-16 18:25:45 -0300267
268 /* Initial accumulator state */
269 ctx->acc[0] = 0U;
270 ctx->acc[1] = 0U;
271 ctx->acc[2] = 0U;
272 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200273 ctx->acc[4] = 0U;
274
275 /* Queue initially empty */
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200277 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300280}
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
283 const unsigned char *input,
284 size_t ilen)
Daniel Kingadc32c02016-05-16 18:25:45 -0300285{
286 size_t offset = 0U;
287 size_t remaining = ilen;
288 size_t queue_free_len;
289 size_t nblocks;
Daniel Kingadc32c02016-05-16 18:25:45 -0300290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
292 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 if (ilen < queue_free_len) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300295 /* Not enough data to complete the block.
296 * Store this data with the other leftovers.
297 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 memcpy(&ctx->queue[ctx->queue_len],
299 input,
300 ilen);
Daniel Kingadc32c02016-05-16 18:25:45 -0300301
302 ctx->queue_len += ilen;
303
304 remaining = 0U;
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 } else {
Daniel Kingadc32c02016-05-16 18:25:45 -0300306 /* Enough data to produce a complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 memcpy(&ctx->queue[ctx->queue_len],
308 input,
309 queue_free_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300310
311 ctx->queue_len = 0U;
312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300314
315 offset += queue_free_len;
316 remaining -= queue_free_len;
317 }
318 }
319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300321 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 poly1305_process(ctx, nblocks, &input[offset], 1U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300324
325 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
326 remaining %= POLY1305_BLOCK_SIZE_BYTES;
327 }
328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 if (remaining > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300330 /* Store partial block */
331 ctx->queue_len = remaining;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 memcpy(ctx->queue, &input[offset], remaining);
Daniel Kingadc32c02016-05-16 18:25:45 -0300333 }
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300336}
337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
339 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300340{
Daniel Kingadc32c02016-05-16 18:25:45 -0300341 /* Process any leftover data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 if (ctx->queue_len > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300343 /* Add padding bit */
344 ctx->queue[ctx->queue_len] = 1U;
345 ctx->queue_len++;
346
347 /* Pad with zeroes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 memset(&ctx->queue[ctx->queue_len],
349 0,
350 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 poly1305_process(ctx, 1U, /* Process 1 block */
353 ctx->queue, 0U); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300354 }
355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 poly1305_compute_mac(ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300359}
360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361int mbedtls_poly1305_mac(const unsigned char key[32],
362 const unsigned char *input,
363 size_t ilen,
364 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300365{
366 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 mbedtls_poly1305_init(&ctx);
Daniel Kingadc32c02016-05-16 18:25:45 -0300370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 ret = mbedtls_poly1305_starts(&ctx, key);
372 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300373 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 ret = mbedtls_poly1305_update(&ctx, input, ilen);
377 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300378 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 ret = mbedtls_poly1305_finish(&ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300382
383cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 mbedtls_poly1305_free(&ctx);
385 return ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300386}
387
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200388#endif /* MBEDTLS_POLY1305_ALT */
389
Daniel Kingadc32c02016-05-16 18:25:45 -0300390#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
Ouss4e0b26872020-08-11 16:07:09 +0100455/* Make sure no other definition is already present. */
456#undef ASSERT
457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458#define ASSERT(cond, args) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200459 do \
460 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 if (!(cond)) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200462 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 if (verbose != 0) \
464 mbedtls_printf args; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200465 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 return -1; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200467 } \
468 } \
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 while (0)
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471int mbedtls_poly1305_self_test(int verbose)
Daniel Kingadc32c02016-05-16 18:25:45 -0300472{
Daniel Kinge6e79682016-05-24 11:16:17 -0300473 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200474 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000475 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 for (i = 0U; i < 2U; i++) {
478 if (verbose != 0) {
479 mbedtls_printf(" Poly1305 test %u ", i);
480 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 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));
Daniel Kingadc32c02016-05-16 18:25:45 -0300487
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Daniel Kingadc32c02016-05-16 18:25:45 -0300489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 if (verbose != 0) {
491 mbedtls_printf("passed\n");
492 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300493 }
494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 if (verbose != 0) {
496 mbedtls_printf("\n");
497 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300500}
501
502#endif /* MBEDTLS_SELF_TEST */
503
504#endif /* MBEDTLS_POLY1305_C */