blob: 510a45a698d209c403b835fcf5e6cd85633b9200 [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
Hanno Becker305e4e42018-12-11 15:03:16 +000035/* Parameter validation macros */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010036#define POLY1305_VALIDATE_RET(cond) \
37 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA)
38#define POLY1305_VALIDATE(cond) \
39 MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker305e4e42018-12-11 15:03:16 +000040
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010041#define POLY1305_BLOCK_SIZE_BYTES (16U)
Daniel Kingadc32c02016-05-16 18:25:45 -030042
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020043/*
44 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
45 * However we provided an alternative for platforms without such a multiplier.
46 */
47#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048static uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020049{
50 /* a = al + 2**16 ah, b = bl + 2**16 bh */
51 const uint16_t al = (uint16_t) a;
Joe Subbiani197e9ed2021-07-16 17:47:17 +010052 const uint16_t bl = (uint16_t) b;
Joe Subbiani281956d2021-07-16 17:14:07 +010053 const uint16_t ah = a >> 16;
54 const uint16_t bh = b >> 16;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020055
56 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
57 const uint32_t lo = (uint32_t) al * bl;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010058 const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020059 const uint32_t hi = (uint32_t) ah * bh;
60
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010061 return lo + (me << 16) + ((uint64_t) hi << 32);
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020062}
63#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064static inline uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020065{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066 return (uint64_t) a * b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020067}
68#endif
69
70
Daniel Kingadc32c02016-05-16 18:25:45 -030071/**
72 * \brief Process blocks with Poly1305.
73 *
74 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020075 * \param nblocks Number of blocks to process. Note that this
76 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030077 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020078 * \param needs_padding Set to 0 if the padding bit has already been
79 * applied to the input data before calling this
80 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030081 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010082static void poly1305_process(mbedtls_poly1305_context *ctx,
83 size_t nblocks,
84 const unsigned char *input,
85 uint32_t needs_padding)
Daniel Kingadc32c02016-05-16 18:25:45 -030086{
87 uint64_t d0, d1, d2, d3;
88 uint32_t acc0, acc1, acc2, acc3, acc4;
89 uint32_t r0, r1, r2, r3;
90 uint32_t rs1, rs2, rs3;
91 size_t offset = 0U;
92 size_t i;
93
94 r0 = ctx->r[0];
95 r1 = ctx->r[1];
96 r2 = ctx->r[2];
97 r3 = ctx->r[3];
98
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010099 rs1 = r1 + (r1 >> 2U);
100 rs2 = r2 + (r2 >> 2U);
101 rs3 = r3 + (r3 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300102
103 acc0 = ctx->acc[0];
104 acc1 = ctx->acc[1];
105 acc2 = ctx->acc[2];
106 acc3 = ctx->acc[3];
107 acc4 = ctx->acc[4];
108
109 /* Process full blocks */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 for (i = 0U; i < nblocks; i++) {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200111 /* The input block is treated as a 128-bit little-endian integer */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112 d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0);
113 d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4);
114 d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8);
115 d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12);
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200116
117 /* Compute: acc += (padded) block as a 130-bit integer */
118 d0 += (uint64_t) acc0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 d1 += (uint64_t) acc1 + (d0 >> 32U);
120 d2 += (uint64_t) acc2 + (d1 >> 32U);
121 d3 += (uint64_t) acc3 + (d2 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300122 acc0 = (uint32_t) d0;
123 acc1 = (uint32_t) d1;
124 acc2 = (uint32_t) d2;
125 acc3 = (uint32_t) d3;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 acc4 += (uint32_t) (d3 >> 32U) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300127
128 /* Compute: acc *= r */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 d0 = mul64(acc0, r0) +
130 mul64(acc1, rs3) +
131 mul64(acc2, rs2) +
132 mul64(acc3, rs1);
133 d1 = mul64(acc0, r1) +
134 mul64(acc1, r0) +
135 mul64(acc2, rs3) +
136 mul64(acc3, rs2) +
137 mul64(acc4, rs1);
138 d2 = mul64(acc0, r2) +
139 mul64(acc1, r1) +
140 mul64(acc2, r0) +
141 mul64(acc3, rs3) +
142 mul64(acc4, rs2);
143 d3 = mul64(acc0, r3) +
144 mul64(acc1, r2) +
145 mul64(acc2, r1) +
146 mul64(acc3, r0) +
147 mul64(acc4, rs3);
Daniel Kingadc32c02016-05-16 18:25:45 -0300148 acc4 *= r0;
149
150 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 d1 += (d0 >> 32);
152 d2 += (d1 >> 32);
153 d3 += (d2 >> 32);
Daniel Kinge6e79682016-05-24 11:16:17 -0300154 acc0 = (uint32_t) d0;
155 acc1 = (uint32_t) d1;
156 acc2 = (uint32_t) d2;
157 acc3 = (uint32_t) d3;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100158 acc4 = (uint32_t) (d3 >> 32) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Daniel Kingadc32c02016-05-16 18:25:45 -0300161 acc4 &= 3U;
Daniel Kinge6e79682016-05-24 11:16:17 -0300162 acc0 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 d0 = (uint64_t) acc1 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300164 acc1 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165 d0 = (uint64_t) acc2 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300166 acc2 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 d0 = (uint64_t) acc3 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300168 acc3 = (uint32_t) d0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100169 d0 = (uint64_t) acc4 + (d0 >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300170 acc4 = (uint32_t) d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300171
172 offset += POLY1305_BLOCK_SIZE_BYTES;
173 }
174
175 ctx->acc[0] = acc0;
176 ctx->acc[1] = acc1;
177 ctx->acc[2] = acc2;
178 ctx->acc[3] = acc3;
179 ctx->acc[4] = acc4;
180}
181
182/**
183 * \brief Compute the Poly1305 MAC
184 *
185 * \param ctx The Poly1305 context.
186 * \param mac The buffer to where the MAC is written. Must be
187 * big enough to contain the 16-byte MAC.
188 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100189static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
190 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300191{
192 uint64_t d;
193 uint32_t g0, g1, g2, g3, g4;
194 uint32_t acc0, acc1, acc2, acc3, acc4;
195 uint32_t mask;
196 uint32_t mask_inv;
197
198 acc0 = ctx->acc[0];
199 acc1 = ctx->acc[1];
200 acc2 = ctx->acc[2];
201 acc3 = ctx->acc[3];
202 acc4 = ctx->acc[4];
203
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200204 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300205 * We do this by calculating acc - (2^130 - 5), then checking if
206 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
207 */
208
209 /* Calculate acc + -(2^130 - 5) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100210 d = ((uint64_t) acc0 + 5U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300211 g0 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100212 d = ((uint64_t) acc1 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300213 g1 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100214 d = ((uint64_t) acc2 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300215 g2 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216 d = ((uint64_t) acc3 + (d >> 32));
Daniel Kinge6e79682016-05-24 11:16:17 -0300217 g3 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100218 g4 = acc4 + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300219
220 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100221 mask = (uint32_t) 0U - (g4 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300222 mask_inv = ~mask;
223
224 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225 acc0 = (acc0 & mask_inv) | (g0 & mask);
226 acc1 = (acc1 & mask_inv) | (g1 & mask);
227 acc2 = (acc2 & mask_inv) | (g2 & mask);
228 acc3 = (acc3 & mask_inv) | (g3 & mask);
Daniel Kingadc32c02016-05-16 18:25:45 -0300229
230 /* Add 's' */
Daniel Kinge6e79682016-05-24 11:16:17 -0300231 d = (uint64_t) acc0 + ctx->s[0];
232 acc0 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100233 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300234 acc1 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
Daniel Kinge6e79682016-05-24 11:16:17 -0300236 acc2 = (uint32_t) d;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100237 acc3 += ctx->s[3] + (uint32_t) (d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300238
239 /* Compute MAC (128 least significant bits of the accumulator) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100240 MBEDTLS_PUT_UINT32_LE(acc0, mac, 0);
241 MBEDTLS_PUT_UINT32_LE(acc1, mac, 4);
242 MBEDTLS_PUT_UINT32_LE(acc2, mac, 8);
243 MBEDTLS_PUT_UINT32_LE(acc3, mac, 12);
Daniel Kingadc32c02016-05-16 18:25:45 -0300244}
245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100246void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300247{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100248 POLY1305_VALIDATE(ctx != NULL);
Hanno Becker305e4e42018-12-11 15:03:16 +0000249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300251}
252
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300254{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100255 if (ctx == NULL) {
Hanno Becker305e4e42018-12-11 15:03:16 +0000256 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 }
Hanno Becker305e4e42018-12-11 15:03:16 +0000258
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300260}
261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
263 const unsigned char key[32])
Daniel Kingadc32c02016-05-16 18:25:45 -0300264{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 POLY1305_VALIDATE_RET(ctx != NULL);
266 POLY1305_VALIDATE_RET(key != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300267
268 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269 ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU;
270 ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU;
271 ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU;
272 ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16);
275 ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20);
276 ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24);
277 ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28);
Daniel Kingadc32c02016-05-16 18:25:45 -0300278
279 /* Initial accumulator state */
280 ctx->acc[0] = 0U;
281 ctx->acc[1] = 0U;
282 ctx->acc[2] = 0U;
283 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200284 ctx->acc[4] = 0U;
285
286 /* Queue initially empty */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100287 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200288 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300289
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100290 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300291}
292
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
294 const unsigned char *input,
295 size_t ilen)
Daniel Kingadc32c02016-05-16 18:25:45 -0300296{
297 size_t offset = 0U;
298 size_t remaining = ilen;
299 size_t queue_free_len;
300 size_t nblocks;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 POLY1305_VALIDATE_RET(ctx != NULL);
302 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
305 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300306
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307 if (ilen < queue_free_len) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300308 /* Not enough data to complete the block.
309 * Store this data with the other leftovers.
310 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 memcpy(&ctx->queue[ctx->queue_len],
312 input,
313 ilen);
Daniel Kingadc32c02016-05-16 18:25:45 -0300314
315 ctx->queue_len += ilen;
316
317 remaining = 0U;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 } else {
Daniel Kingadc32c02016-05-16 18:25:45 -0300319 /* Enough data to produce a complete block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100320 memcpy(&ctx->queue[ctx->queue_len],
321 input,
322 queue_free_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300323
324 ctx->queue_len = 0U;
325
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300327
328 offset += queue_free_len;
329 remaining -= queue_free_len;
330 }
331 }
332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300334 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
335
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 poly1305_process(ctx, nblocks, &input[offset], 1U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300337
338 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
339 remaining %= POLY1305_BLOCK_SIZE_BYTES;
340 }
341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 if (remaining > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300343 /* Store partial block */
344 ctx->queue_len = remaining;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 memcpy(ctx->queue, &input[offset], remaining);
Daniel Kingadc32c02016-05-16 18:25:45 -0300346 }
347
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300349}
350
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100351int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
352 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300353{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 POLY1305_VALIDATE_RET(ctx != NULL);
355 POLY1305_VALIDATE_RET(mac != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300356
357 /* Process any leftover data */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 if (ctx->queue_len > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300359 /* Add padding bit */
360 ctx->queue[ctx->queue_len] = 1U;
361 ctx->queue_len++;
362
363 /* Pad with zeroes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100364 memset(&ctx->queue[ctx->queue_len],
365 0,
366 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100368 poly1305_process(ctx, 1U, /* Process 1 block */
369 ctx->queue, 0U); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300370 }
371
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 poly1305_compute_mac(ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300375}
376
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377int mbedtls_poly1305_mac(const unsigned char key[32],
378 const unsigned char *input,
379 size_t ilen,
380 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300381{
382 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000383 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100384 POLY1305_VALIDATE_RET(key != NULL);
385 POLY1305_VALIDATE_RET(mac != NULL);
386 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 mbedtls_poly1305_init(&ctx);
Daniel Kingadc32c02016-05-16 18:25:45 -0300389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 ret = mbedtls_poly1305_starts(&ctx, key);
391 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300392 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 ret = mbedtls_poly1305_update(&ctx, input, ilen);
396 if (ret != 0) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300397 goto cleanup;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300399
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 ret = mbedtls_poly1305_finish(&ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300401
402cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 mbedtls_poly1305_free(&ctx);
404 return ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300405}
406
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200407#endif /* MBEDTLS_POLY1305_ALT */
408
Daniel Kingadc32c02016-05-16 18:25:45 -0300409#if defined(MBEDTLS_SELF_TEST)
410
411static const unsigned char test_keys[2][32] =
412{
413 {
414 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
415 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
416 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
417 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
418 },
419 {
420 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
421 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
422 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
423 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
424 }
425};
426
427static const unsigned char test_data[2][127] =
428{
429 {
430 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
431 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
432 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
433 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
434 0x75, 0x70
435 },
436 {
437 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
438 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
439 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
440 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
441 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
442 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
443 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
444 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
445 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
446 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
447 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
448 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
449 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
450 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
451 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
452 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
453 }
454};
455
456static const size_t test_data_len[2] =
457{
458 34U,
459 127U
460};
461
462static const unsigned char test_mac[2][16] =
463{
464 {
465 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
466 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
467 },
468 {
469 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
470 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
471 }
472};
473
Ouss4e0b26872020-08-11 16:07:09 +0100474/* Make sure no other definition is already present. */
475#undef ASSERT
476
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100477#define ASSERT(cond, args) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200478 do \
479 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 if (!(cond)) \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200481 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100482 if (verbose != 0) \
483 mbedtls_printf args; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200484 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485 return -1; \
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200486 } \
487 } \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100488 while (0)
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200489
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490int mbedtls_poly1305_self_test(int verbose)
Daniel Kingadc32c02016-05-16 18:25:45 -0300491{
Daniel Kinge6e79682016-05-24 11:16:17 -0300492 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200493 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000494 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300495
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 for (i = 0U; i < 2U; i++) {
497 if (verbose != 0) {
498 mbedtls_printf(" Poly1305 test %u ", i);
499 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 ret = mbedtls_poly1305_mac(test_keys[i],
502 test_data[i],
503 test_data_len[i],
504 mac);
505 ASSERT(0 == ret, ("error code: %i\n", ret));
Daniel Kingadc32c02016-05-16 18:25:45 -0300506
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100507 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Daniel Kingadc32c02016-05-16 18:25:45 -0300508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 if (verbose != 0) {
510 mbedtls_printf("passed\n");
511 }
Daniel Kingdedf4a32016-05-18 10:07:53 -0300512 }
513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 if (verbose != 0) {
515 mbedtls_printf("\n");
516 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300519}
520
521#endif /* MBEDTLS_SELF_TEST */
522
523#endif /* MBEDTLS_POLY1305_C */