blob: de3282f97f03cd2e912aff3a15344455adef5bc5 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020025# include "mbedtls/poly1305.h"
26# include "mbedtls/platform_util.h"
27# include "mbedtls/error.h"
Daniel Kingadc32c02016-05-16 18:25:45 -030028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include <string.h>
Daniel Kingadc32c02016-05-16 18:25:45 -030030
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020031# if defined(MBEDTLS_SELF_TEST)
32# if defined(MBEDTLS_PLATFORM_C)
33# include "mbedtls/platform.h"
34# else
35# include <stdio.h>
36# define mbedtls_printf printf
37# endif /* MBEDTLS_PLATFORM_C */
38# endif /* MBEDTLS_SELF_TEST */
Daniel Kingadc32c02016-05-16 18:25:45 -030039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040# if !defined(MBEDTLS_POLY1305_ALT)
Manuel Pégourié-Gonnardfb78c902018-05-24 13:46:15 +020041
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020042# if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && \
43 !defined(inline) && !defined(__cplusplus)
44# define inline __inline
45# endif
Manuel Pégourié-Gonnard21a65e02018-06-07 11:54:17 +020046
Hanno Becker305e4e42018-12-11 15:03:16 +000047/* Parameter validation macros */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020048# define POLY1305_VALIDATE_RET(cond) \
49 MBEDTLS_INTERNAL_VALIDATE_RET(cond, \
50 MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA)
51# define POLY1305_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker305e4e42018-12-11 15:03:16 +000052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020053# define POLY1305_BLOCK_SIZE_BYTES (16U)
Daniel Kingadc32c02016-05-16 18:25:45 -030054
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020055# define BYTES_TO_U32_LE(data, offset) \
56 ((uint32_t)(data)[offset] | \
57 (uint32_t)((uint32_t)(data)[(offset) + 1] << 8) | \
58 (uint32_t)((uint32_t)(data)[(offset) + 2] << 16) | \
59 (uint32_t)((uint32_t)(data)[(offset) + 3] << 24))
Daniel Kingadc32c02016-05-16 18:25:45 -030060
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020061/*
62 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
63 * However we provided an alternative for platforms without such a multiplier.
64 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020065# if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
66static uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020067{
68 /* a = al + 2**16 ah, b = bl + 2**16 bh */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020069 const uint16_t al = (uint16_t)a;
70 const uint16_t bl = (uint16_t)b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020071 const uint16_t ah = a >> 16;
72 const uint16_t bh = b >> 16;
73
74 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075 const uint32_t lo = (uint32_t)al * bl;
76 const uint64_t me = (uint64_t)((uint32_t)ah * bl) + (uint32_t)al * bh;
77 const uint32_t hi = (uint32_t)ah * bh;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020078
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020079 return (lo + (me << 16) + ((uint64_t)hi << 32));
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020080}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081# else
82static inline uint64_t mul64(uint32_t a, uint32_t b)
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020083{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020084 return (uint64_t)a * b;
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020085}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020086# endif
Manuel Pégourié-Gonnard2adb3752018-06-07 10:51:44 +020087
Daniel Kingadc32c02016-05-16 18:25:45 -030088/**
89 * \brief Process blocks with Poly1305.
90 *
91 * \param ctx The Poly1305 context.
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020092 * \param nblocks Number of blocks to process. Note that this
93 * function only processes full blocks.
Daniel Kingadc32c02016-05-16 18:25:45 -030094 * \param input Buffer containing the input block(s).
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +020095 * \param needs_padding Set to 0 if the padding bit has already been
96 * applied to the input data before calling this
97 * function. Otherwise, set this parameter to 1.
Daniel Kingadc32c02016-05-16 18:25:45 -030098 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020099static void poly1305_process(mbedtls_poly1305_context *ctx,
100 size_t nblocks,
101 const unsigned char *input,
102 uint32_t needs_padding)
Daniel Kingadc32c02016-05-16 18:25:45 -0300103{
104 uint64_t d0, d1, d2, d3;
105 uint32_t acc0, acc1, acc2, acc3, acc4;
106 uint32_t r0, r1, r2, r3;
107 uint32_t rs1, rs2, rs3;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108 size_t offset = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300109 size_t i;
110
111 r0 = ctx->r[0];
112 r1 = ctx->r[1];
113 r2 = ctx->r[2];
114 r3 = ctx->r[3];
115
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 rs1 = r1 + (r1 >> 2U);
117 rs2 = r2 + (r2 >> 2U);
118 rs3 = r3 + (r3 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300119
120 acc0 = ctx->acc[0];
121 acc1 = ctx->acc[1];
122 acc2 = ctx->acc[2];
123 acc3 = ctx->acc[3];
124 acc4 = ctx->acc[4];
125
126 /* Process full blocks */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200127 for (i = 0U; i < nblocks; i++) {
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200128 /* The input block is treated as a 128-bit little-endian integer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200129 d0 = BYTES_TO_U32_LE(input, offset + 0);
130 d1 = BYTES_TO_U32_LE(input, offset + 4);
131 d2 = BYTES_TO_U32_LE(input, offset + 8);
132 d3 = BYTES_TO_U32_LE(input, offset + 12);
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200133
134 /* Compute: acc += (padded) block as a 130-bit integer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 d0 += (uint64_t)acc0;
136 d1 += (uint64_t)acc1 + (d0 >> 32U);
137 d2 += (uint64_t)acc2 + (d1 >> 32U);
138 d3 += (uint64_t)acc3 + (d2 >> 32U);
139 acc0 = (uint32_t)d0;
140 acc1 = (uint32_t)d1;
141 acc2 = (uint32_t)d2;
142 acc3 = (uint32_t)d3;
143 acc4 += (uint32_t)(d3 >> 32U) + needs_padding;
Daniel Kingadc32c02016-05-16 18:25:45 -0300144
145 /* Compute: acc *= r */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200146 d0 = mul64(acc0, r0) + mul64(acc1, rs3) + mul64(acc2, rs2) +
147 mul64(acc3, rs1);
148 d1 = mul64(acc0, r1) + mul64(acc1, r0) + mul64(acc2, rs3) +
149 mul64(acc3, rs2) + mul64(acc4, rs1);
150 d2 = mul64(acc0, r2) + mul64(acc1, r1) + mul64(acc2, r0) +
151 mul64(acc3, rs3) + mul64(acc4, rs2);
152 d3 = mul64(acc0, r3) + mul64(acc1, r2) + mul64(acc2, r1) +
153 mul64(acc3, r0) + mul64(acc4, rs3);
Daniel Kingadc32c02016-05-16 18:25:45 -0300154 acc4 *= r0;
155
156 /* Compute: acc %= (2^130 - 5) (partial remainder) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200157 d1 += (d0 >> 32);
158 d2 += (d1 >> 32);
159 d3 += (d2 >> 32);
160 acc0 = (uint32_t)d0;
161 acc1 = (uint32_t)d1;
162 acc2 = (uint32_t)d2;
163 acc3 = (uint32_t)d3;
164 acc4 = (uint32_t)(d3 >> 32) + acc4;
Daniel Kingadc32c02016-05-16 18:25:45 -0300165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200166 d0 = (uint64_t)acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
Daniel Kingadc32c02016-05-16 18:25:45 -0300167 acc4 &= 3U;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 acc0 = (uint32_t)d0;
169 d0 = (uint64_t)acc1 + (d0 >> 32U);
170 acc1 = (uint32_t)d0;
171 d0 = (uint64_t)acc2 + (d0 >> 32U);
172 acc2 = (uint32_t)d0;
173 d0 = (uint64_t)acc3 + (d0 >> 32U);
174 acc3 = (uint32_t)d0;
175 d0 = (uint64_t)acc4 + (d0 >> 32U);
176 acc4 = (uint32_t)d0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300177
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200178 offset += POLY1305_BLOCK_SIZE_BYTES;
Daniel Kingadc32c02016-05-16 18:25:45 -0300179 }
180
181 ctx->acc[0] = acc0;
182 ctx->acc[1] = acc1;
183 ctx->acc[2] = acc2;
184 ctx->acc[3] = acc3;
185 ctx->acc[4] = acc4;
186}
187
188/**
189 * \brief Compute the Poly1305 MAC
190 *
191 * \param ctx The Poly1305 context.
192 * \param mac The buffer to where the MAC is written. Must be
193 * big enough to contain the 16-byte MAC.
194 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
196 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300197{
198 uint64_t d;
199 uint32_t g0, g1, g2, g3, g4;
200 uint32_t acc0, acc1, acc2, acc3, acc4;
201 uint32_t mask;
202 uint32_t mask_inv;
203
204 acc0 = ctx->acc[0];
205 acc1 = ctx->acc[1];
206 acc2 = ctx->acc[2];
207 acc3 = ctx->acc[3];
208 acc4 = ctx->acc[4];
209
Manuel Pégourié-Gonnard17297892018-05-24 17:53:41 +0200210 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
Daniel Kingadc32c02016-05-16 18:25:45 -0300211 * We do this by calculating acc - (2^130 - 5), then checking if
212 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
213 */
214
215 /* Calculate acc + -(2^130 - 5) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216 d = ((uint64_t)acc0 + 5U);
217 g0 = (uint32_t)d;
218 d = ((uint64_t)acc1 + (d >> 32));
219 g1 = (uint32_t)d;
220 d = ((uint64_t)acc2 + (d >> 32));
221 g2 = (uint32_t)d;
222 d = ((uint64_t)acc3 + (d >> 32));
223 g3 = (uint32_t)d;
224 g4 = acc4 + (uint32_t)(d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300225
226 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200227 mask = (uint32_t)0U - (g4 >> 2U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300228 mask_inv = ~mask;
229
230 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200231 acc0 = (acc0 & mask_inv) | (g0 & mask);
232 acc1 = (acc1 & mask_inv) | (g1 & mask);
233 acc2 = (acc2 & mask_inv) | (g2 & mask);
234 acc3 = (acc3 & mask_inv) | (g3 & mask);
Daniel Kingadc32c02016-05-16 18:25:45 -0300235
236 /* Add 's' */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200237 d = (uint64_t)acc0 + ctx->s[0];
238 acc0 = (uint32_t)d;
239 d = (uint64_t)acc1 + ctx->s[1] + (d >> 32U);
240 acc1 = (uint32_t)d;
241 d = (uint64_t)acc2 + ctx->s[2] + (d >> 32U);
242 acc2 = (uint32_t)d;
243 acc3 += ctx->s[3] + (uint32_t)(d >> 32U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300244
245 /* Compute MAC (128 least significant bits of the accumulator) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246 mac[0] = (unsigned char)(acc0);
247 mac[1] = (unsigned char)(acc0 >> 8);
248 mac[2] = (unsigned char)(acc0 >> 16);
249 mac[3] = (unsigned char)(acc0 >> 24);
250 mac[4] = (unsigned char)(acc1);
251 mac[5] = (unsigned char)(acc1 >> 8);
252 mac[6] = (unsigned char)(acc1 >> 16);
253 mac[7] = (unsigned char)(acc1 >> 24);
254 mac[8] = (unsigned char)(acc2);
255 mac[9] = (unsigned char)(acc2 >> 8);
256 mac[10] = (unsigned char)(acc2 >> 16);
257 mac[11] = (unsigned char)(acc2 >> 24);
258 mac[12] = (unsigned char)(acc3);
259 mac[13] = (unsigned char)(acc3 >> 8);
260 mac[14] = (unsigned char)(acc3 >> 16);
261 mac[15] = (unsigned char)(acc3 >> 24);
Daniel Kingadc32c02016-05-16 18:25:45 -0300262}
263
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200264void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300265{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 POLY1305_VALIDATE(ctx != NULL);
Hanno Becker305e4e42018-12-11 15:03:16 +0000267
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300269}
270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx)
Daniel Kingadc32c02016-05-16 18:25:45 -0300272{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200273 if (ctx == NULL)
Hanno Becker305e4e42018-12-11 15:03:16 +0000274 return;
275
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200276 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
Daniel Kingadc32c02016-05-16 18:25:45 -0300277}
278
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200279int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
280 const unsigned char key[32])
Daniel Kingadc32c02016-05-16 18:25:45 -0300281{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282 POLY1305_VALIDATE_RET(ctx != NULL);
283 POLY1305_VALIDATE_RET(key != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300284
285 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 ctx->r[0] = BYTES_TO_U32_LE(key, 0) & 0x0FFFFFFFU;
287 ctx->r[1] = BYTES_TO_U32_LE(key, 4) & 0x0FFFFFFCU;
288 ctx->r[2] = BYTES_TO_U32_LE(key, 8) & 0x0FFFFFFCU;
289 ctx->r[3] = BYTES_TO_U32_LE(key, 12) & 0x0FFFFFFCU;
Daniel Kingadc32c02016-05-16 18:25:45 -0300290
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200291 ctx->s[0] = BYTES_TO_U32_LE(key, 16);
292 ctx->s[1] = BYTES_TO_U32_LE(key, 20);
293 ctx->s[2] = BYTES_TO_U32_LE(key, 24);
294 ctx->s[3] = BYTES_TO_U32_LE(key, 28);
Daniel Kingadc32c02016-05-16 18:25:45 -0300295
296 /* Initial accumulator state */
297 ctx->acc[0] = 0U;
298 ctx->acc[1] = 0U;
299 ctx->acc[2] = 0U;
300 ctx->acc[3] = 0U;
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200301 ctx->acc[4] = 0U;
302
303 /* Queue initially empty */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
Manuel Pégourié-Gonnard14656022018-05-09 12:51:54 +0200305 ctx->queue_len = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300306
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300308}
309
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200310int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
311 const unsigned char *input,
312 size_t ilen)
Daniel Kingadc32c02016-05-16 18:25:45 -0300313{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200314 size_t offset = 0U;
Daniel Kingadc32c02016-05-16 18:25:45 -0300315 size_t remaining = ilen;
316 size_t queue_free_len;
317 size_t nblocks;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200318 POLY1305_VALIDATE_RET(ctx != NULL);
319 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200321 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
322 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300323
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200324 if (ilen < queue_free_len) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300325 /* Not enough data to complete the block.
326 * Store this data with the other leftovers.
327 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200328 memcpy(&ctx->queue[ctx->queue_len], input, ilen);
Daniel Kingadc32c02016-05-16 18:25:45 -0300329
330 ctx->queue_len += ilen;
331
332 remaining = 0U;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200333 } else {
Daniel Kingadc32c02016-05-16 18:25:45 -0300334 /* Enough data to produce a complete block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200335 memcpy(&ctx->queue[ctx->queue_len], input, queue_free_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300336
337 ctx->queue_len = 0U;
338
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200339 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
Daniel Kingadc32c02016-05-16 18:25:45 -0300340
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200341 offset += queue_free_len;
Daniel Kingadc32c02016-05-16 18:25:45 -0300342 remaining -= queue_free_len;
343 }
344 }
345
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200346 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300347 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
348
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200349 poly1305_process(ctx, nblocks, &input[offset], 1U);
Daniel Kingadc32c02016-05-16 18:25:45 -0300350
351 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
352 remaining %= POLY1305_BLOCK_SIZE_BYTES;
353 }
354
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200355 if (remaining > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300356 /* Store partial block */
357 ctx->queue_len = remaining;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200358 memcpy(ctx->queue, &input[offset], remaining);
Daniel Kingadc32c02016-05-16 18:25:45 -0300359 }
360
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200361 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300362}
363
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200364int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
365 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300366{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 POLY1305_VALIDATE_RET(ctx != NULL);
368 POLY1305_VALIDATE_RET(mac != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300369
370 /* Process any leftover data */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200371 if (ctx->queue_len > 0U) {
Daniel Kingadc32c02016-05-16 18:25:45 -0300372 /* Add padding bit */
373 ctx->queue[ctx->queue_len] = 1U;
374 ctx->queue_len++;
375
376 /* Pad with zeroes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200377 memset(&ctx->queue[ctx->queue_len], 0,
378 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
Daniel Kingadc32c02016-05-16 18:25:45 -0300379
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200380 poly1305_process(ctx, 1U, /* Process 1 block */
381 ctx->queue, 0U); /* Already padded above */
Daniel Kingadc32c02016-05-16 18:25:45 -0300382 }
383
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200384 poly1305_compute_mac(ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300385
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200386 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300387}
388
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200389int mbedtls_poly1305_mac(const unsigned char key[32],
390 const unsigned char *input,
391 size_t ilen,
392 unsigned char mac[16])
Daniel Kingadc32c02016-05-16 18:25:45 -0300393{
394 mbedtls_poly1305_context ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000395 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200396 POLY1305_VALIDATE_RET(key != NULL);
397 POLY1305_VALIDATE_RET(mac != NULL);
398 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
Daniel Kingadc32c02016-05-16 18:25:45 -0300399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400 mbedtls_poly1305_init(&ctx);
Daniel Kingadc32c02016-05-16 18:25:45 -0300401
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200402 ret = mbedtls_poly1305_starts(&ctx, key);
403 if (ret != 0)
Daniel Kingadc32c02016-05-16 18:25:45 -0300404 goto cleanup;
405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200406 ret = mbedtls_poly1305_update(&ctx, input, ilen);
407 if (ret != 0)
Daniel Kingadc32c02016-05-16 18:25:45 -0300408 goto cleanup;
409
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410 ret = mbedtls_poly1305_finish(&ctx, mac);
Daniel Kingadc32c02016-05-16 18:25:45 -0300411
412cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 mbedtls_poly1305_free(&ctx);
414 return ret;
Daniel Kingadc32c02016-05-16 18:25:45 -0300415}
416
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200417# endif /* MBEDTLS_POLY1305_ALT */
Manuel Pégourié-Gonnard95d0bdb2018-05-07 09:58:35 +0200418
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200419# if defined(MBEDTLS_SELF_TEST)
Daniel Kingadc32c02016-05-16 18:25:45 -0300420
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421static const unsigned char test_keys[2][32] = {
422 { 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, 0x7f, 0x44, 0x52,
423 0xfe, 0x42, 0xd5, 0x06, 0xa8, 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d,
424 0xb2, 0xfd, 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b },
425 { 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, 0xf3, 0x33, 0x88,
426 0x86, 0x04, 0xf6, 0xb5, 0xf0, 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b,
427 0x80, 0x09, 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300428};
429
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430static const unsigned char test_data[2][127] = {
431 { 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
432 0x63, 0x20, 0x46, 0x6f, 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
433 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70 },
434 { 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x69,
435 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
436 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, 0x76, 0x65, 0x73, 0x0a,
437 0x44, 0x69, 0x64, 0x20, 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
438 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74,
439 0x68, 0x65, 0x20, 0x77, 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
440 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, 0x65, 0x72, 0x65, 0x20,
441 0x74, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
442 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
443 0x6f, 0x6d, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
444 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e }
Daniel Kingadc32c02016-05-16 18:25:45 -0300445};
446
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200447static const size_t test_data_len[2] = { 34U, 127U };
Daniel Kingadc32c02016-05-16 18:25:45 -0300448
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200449static const unsigned char test_mac[2][16] = {
450 { 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, 0xc2, 0x2b, 0x8b, 0xaf,
451 0x0c, 0x01, 0x27, 0xa9 },
452 { 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, 0xe7, 0x08, 0xdc, 0x7c,
453 0xbc, 0xc5, 0xeb, 0x62 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300454};
455
Ouss4e0b26872020-08-11 16:07:09 +0100456/* Make sure no other definition is already present. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200457# undef ASSERT
Ouss4e0b26872020-08-11 16:07:09 +0100458
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200459# define ASSERT(cond, args) \
460 do { \
461 if (!(cond)) { \
462 if (verbose != 0) \
463 mbedtls_printf args; \
464 \
465 return -1; \
466 } \
467 } while (0)
Manuel Pégourié-Gonnardc0dfcd42018-05-10 11:42:07 +0200468
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469int mbedtls_poly1305_self_test(int verbose)
Daniel Kingadc32c02016-05-16 18:25:45 -0300470{
Daniel Kinge6e79682016-05-24 11:16:17 -0300471 unsigned char mac[16];
Manuel Pégourié-Gonnardb7e99002018-05-07 10:14:18 +0200472 unsigned i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000473 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Kingadc32c02016-05-16 18:25:45 -0300474
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200475 for (i = 0U; i < 2U; i++) {
476 if (verbose != 0)
477 mbedtls_printf(" Poly1305 test %u ", i);
Daniel Kingdedf4a32016-05-18 10:07:53 -0300478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200479 ret = mbedtls_poly1305_mac(test_keys[i], test_data[i], test_data_len[i],
480 mac);
481 ASSERT(0 == ret, ("error code: %i\n", ret));
Daniel Kingadc32c02016-05-16 18:25:45 -0300482
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200483 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
Daniel Kingadc32c02016-05-16 18:25:45 -0300484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485 if (verbose != 0)
486 mbedtls_printf("passed\n");
Daniel Kingdedf4a32016-05-18 10:07:53 -0300487 }
488
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200489 if (verbose != 0)
490 mbedtls_printf("\n");
Daniel Kingadc32c02016-05-16 18:25:45 -0300491
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492 return 0;
Daniel Kingadc32c02016-05-16 18:25:45 -0300493}
494
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200495# endif /* MBEDTLS_SELF_TEST */
Daniel Kingadc32c02016-05-16 18:25:45 -0300496
497#endif /* MBEDTLS_POLY1305_C */