Merge pull request #2747 from Eltrick/stylise-dormakaba
[RRG-proxmark3.git] / common / mbedtls / poly1305.c
blobb6982b59306fb58224cf295b73d6f358fdd5bddd
1 /**
2 * \file poly1305.c
4 * \brief Poly1305 authentication algorithm.
6 * Copyright The Mbed TLS Contributors
7 * SPDX-License-Identifier: Apache-2.0
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "common.h"
23 #if defined(MBEDTLS_POLY1305_C)
25 #include "mbedtls/poly1305.h"
26 #include "mbedtls/platform_util.h"
27 #include "mbedtls/error.h"
29 #include <string.h>
31 #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 */
40 #if !defined(MBEDTLS_POLY1305_ALT)
42 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
43 !defined(inline) && !defined(__cplusplus)
44 #define inline __inline
45 #endif
47 /* Parameter validation macros */
48 #define POLY1305_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
50 #define POLY1305_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
53 #define POLY1305_BLOCK_SIZE_BYTES ( 16U )
55 #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 ) \
63 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
64 * However we provided an alternative for platforms without such a multiplier.
66 #if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
67 static uint64_t mul64(uint32_t a, uint32_t b) {
68 /* a = al + 2**16 ah, b = bl + 2**16 bh */
69 const uint16_t al = (uint16_t) a;
70 const uint16_t bl = (uint16_t) b;
71 const uint16_t ah = a >> 16;
72 const uint16_t bh = b >> 16;
74 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
75 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;
79 return (lo + (me << 16) + ((uint64_t) hi << 32));
81 #else
82 static inline uint64_t mul64(uint32_t a, uint32_t b) {
83 return ((uint64_t) a * b);
85 #endif
88 /**
89 * \brief Process blocks with Poly1305.
91 * \param ctx The Poly1305 context.
92 * \param nblocks Number of blocks to process. Note that this
93 * function only processes full blocks.
94 * \param input Buffer containing the input block(s).
95 * \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.
99 static void poly1305_process(mbedtls_poly1305_context *ctx,
100 size_t nblocks,
101 const unsigned char *input,
102 uint32_t needs_padding) {
103 uint64_t d0, d1, d2, d3;
104 uint32_t acc0, acc1, acc2, acc3, acc4;
105 uint32_t r0, r1, r2, r3;
106 uint32_t rs1, rs2, rs3;
107 size_t offset = 0U;
108 size_t i;
110 r0 = ctx->r[0];
111 r1 = ctx->r[1];
112 r2 = ctx->r[2];
113 r3 = ctx->r[3];
115 rs1 = r1 + (r1 >> 2U);
116 rs2 = r2 + (r2 >> 2U);
117 rs3 = r3 + (r3 >> 2U);
119 acc0 = ctx->acc[0];
120 acc1 = ctx->acc[1];
121 acc2 = ctx->acc[2];
122 acc3 = ctx->acc[3];
123 acc4 = ctx->acc[4];
125 /* Process full blocks */
126 for (i = 0U; i < nblocks; i++) {
127 /* The input block is treated as a 128-bit little-endian integer */
128 d0 = BYTES_TO_U32_LE(input, offset + 0);
129 d1 = BYTES_TO_U32_LE(input, offset + 4);
130 d2 = BYTES_TO_U32_LE(input, offset + 8);
131 d3 = BYTES_TO_U32_LE(input, offset + 12);
133 /* Compute: acc += (padded) block as a 130-bit integer */
134 d0 += (uint64_t) acc0;
135 d1 += (uint64_t) acc1 + (d0 >> 32U);
136 d2 += (uint64_t) acc2 + (d1 >> 32U);
137 d3 += (uint64_t) acc3 + (d2 >> 32U);
138 acc0 = (uint32_t) d0;
139 acc1 = (uint32_t) d1;
140 acc2 = (uint32_t) d2;
141 acc3 = (uint32_t) d3;
142 acc4 += (uint32_t)(d3 >> 32U) + needs_padding;
144 /* Compute: acc *= r */
145 d0 = mul64(acc0, r0) +
146 mul64(acc1, rs3) +
147 mul64(acc2, rs2) +
148 mul64(acc3, rs1);
149 d1 = mul64(acc0, r1) +
150 mul64(acc1, r0) +
151 mul64(acc2, rs3) +
152 mul64(acc3, rs2) +
153 mul64(acc4, rs1);
154 d2 = mul64(acc0, r2) +
155 mul64(acc1, r1) +
156 mul64(acc2, r0) +
157 mul64(acc3, rs3) +
158 mul64(acc4, rs2);
159 d3 = mul64(acc0, r3) +
160 mul64(acc1, r2) +
161 mul64(acc2, r1) +
162 mul64(acc3, r0) +
163 mul64(acc4, rs3);
164 acc4 *= r0;
166 /* Compute: acc %= (2^130 - 5) (partial remainder) */
167 d1 += (d0 >> 32);
168 d2 += (d1 >> 32);
169 d3 += (d2 >> 32);
170 acc0 = (uint32_t) d0;
171 acc1 = (uint32_t) d1;
172 acc2 = (uint32_t) d2;
173 acc3 = (uint32_t) d3;
174 acc4 = (uint32_t)(d3 >> 32) + acc4;
176 d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU);
177 acc4 &= 3U;
178 acc0 = (uint32_t) d0;
179 d0 = (uint64_t) acc1 + (d0 >> 32U);
180 acc1 = (uint32_t) d0;
181 d0 = (uint64_t) acc2 + (d0 >> 32U);
182 acc2 = (uint32_t) d0;
183 d0 = (uint64_t) acc3 + (d0 >> 32U);
184 acc3 = (uint32_t) d0;
185 d0 = (uint64_t) acc4 + (d0 >> 32U);
186 acc4 = (uint32_t) d0;
188 offset += POLY1305_BLOCK_SIZE_BYTES;
191 ctx->acc[0] = acc0;
192 ctx->acc[1] = acc1;
193 ctx->acc[2] = acc2;
194 ctx->acc[3] = acc3;
195 ctx->acc[4] = acc4;
199 * \brief Compute the Poly1305 MAC
201 * \param ctx The Poly1305 context.
202 * \param mac The buffer to where the MAC is written. Must be
203 * big enough to contain the 16-byte MAC.
205 static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx,
206 unsigned char mac[16]) {
207 uint64_t d;
208 uint32_t g0, g1, g2, g3, g4;
209 uint32_t acc0, acc1, acc2, acc3, acc4;
210 uint32_t mask;
211 uint32_t mask_inv;
213 acc0 = ctx->acc[0];
214 acc1 = ctx->acc[1];
215 acc2 = ctx->acc[2];
216 acc3 = ctx->acc[3];
217 acc4 = ctx->acc[4];
219 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
220 * We do this by calculating acc - (2^130 - 5), then checking if
221 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
224 /* Calculate acc + -(2^130 - 5) */
225 d = ((uint64_t) acc0 + 5U);
226 g0 = (uint32_t) d;
227 d = ((uint64_t) acc1 + (d >> 32));
228 g1 = (uint32_t) d;
229 d = ((uint64_t) acc2 + (d >> 32));
230 g2 = (uint32_t) d;
231 d = ((uint64_t) acc3 + (d >> 32));
232 g3 = (uint32_t) d;
233 g4 = acc4 + (uint32_t)(d >> 32U);
235 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
236 mask = (uint32_t) 0U - (g4 >> 2U);
237 mask_inv = ~mask;
239 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
240 acc0 = (acc0 & mask_inv) | (g0 & mask);
241 acc1 = (acc1 & mask_inv) | (g1 & mask);
242 acc2 = (acc2 & mask_inv) | (g2 & mask);
243 acc3 = (acc3 & mask_inv) | (g3 & mask);
245 /* Add 's' */
246 d = (uint64_t) acc0 + ctx->s[0];
247 acc0 = (uint32_t) d;
248 d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U);
249 acc1 = (uint32_t) d;
250 d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U);
251 acc2 = (uint32_t) d;
252 acc3 += ctx->s[3] + (uint32_t)(d >> 32U);
254 /* Compute MAC (128 least significant bits of the accumulator) */
255 mac[ 0] = (unsigned char)(acc0);
256 mac[ 1] = (unsigned char)(acc0 >> 8);
257 mac[ 2] = (unsigned char)(acc0 >> 16);
258 mac[ 3] = (unsigned char)(acc0 >> 24);
259 mac[ 4] = (unsigned char)(acc1);
260 mac[ 5] = (unsigned char)(acc1 >> 8);
261 mac[ 6] = (unsigned char)(acc1 >> 16);
262 mac[ 7] = (unsigned char)(acc1 >> 24);
263 mac[ 8] = (unsigned char)(acc2);
264 mac[ 9] = (unsigned char)(acc2 >> 8);
265 mac[10] = (unsigned char)(acc2 >> 16);
266 mac[11] = (unsigned char)(acc2 >> 24);
267 mac[12] = (unsigned char)(acc3);
268 mac[13] = (unsigned char)(acc3 >> 8);
269 mac[14] = (unsigned char)(acc3 >> 16);
270 mac[15] = (unsigned char)(acc3 >> 24);
273 void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx) {
274 POLY1305_VALIDATE(ctx != NULL);
276 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
279 void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx) {
280 if (ctx == NULL)
281 return;
283 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context));
286 int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
287 const unsigned char key[32]) {
288 POLY1305_VALIDATE_RET(ctx != NULL);
289 POLY1305_VALIDATE_RET(key != NULL);
291 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
292 ctx->r[0] = BYTES_TO_U32_LE(key, 0) & 0x0FFFFFFFU;
293 ctx->r[1] = BYTES_TO_U32_LE(key, 4) & 0x0FFFFFFCU;
294 ctx->r[2] = BYTES_TO_U32_LE(key, 8) & 0x0FFFFFFCU;
295 ctx->r[3] = BYTES_TO_U32_LE(key, 12) & 0x0FFFFFFCU;
297 ctx->s[0] = BYTES_TO_U32_LE(key, 16);
298 ctx->s[1] = BYTES_TO_U32_LE(key, 20);
299 ctx->s[2] = BYTES_TO_U32_LE(key, 24);
300 ctx->s[3] = BYTES_TO_U32_LE(key, 28);
302 /* Initial accumulator state */
303 ctx->acc[0] = 0U;
304 ctx->acc[1] = 0U;
305 ctx->acc[2] = 0U;
306 ctx->acc[3] = 0U;
307 ctx->acc[4] = 0U;
309 /* Queue initially empty */
310 mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue));
311 ctx->queue_len = 0U;
313 return (0);
316 int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
317 const unsigned char *input,
318 size_t ilen) {
319 size_t offset = 0U;
320 size_t remaining = ilen;
321 size_t queue_free_len;
322 size_t nblocks;
323 POLY1305_VALIDATE_RET(ctx != NULL);
324 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
326 if ((remaining > 0U) && (ctx->queue_len > 0U)) {
327 queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
329 if (ilen < queue_free_len) {
330 /* Not enough data to complete the block.
331 * Store this data with the other leftovers.
333 memcpy(&ctx->queue[ctx->queue_len],
334 input,
335 ilen);
337 ctx->queue_len += ilen;
339 remaining = 0U;
340 } else {
341 /* Enough data to produce a complete block */
342 memcpy(&ctx->queue[ctx->queue_len],
343 input,
344 queue_free_len);
346 ctx->queue_len = 0U;
348 poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */
350 offset += queue_free_len;
351 remaining -= queue_free_len;
355 if (remaining >= POLY1305_BLOCK_SIZE_BYTES) {
356 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
358 poly1305_process(ctx, nblocks, &input[offset], 1U);
360 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
361 remaining %= POLY1305_BLOCK_SIZE_BYTES;
364 if (remaining > 0U) {
365 /* Store partial block */
366 ctx->queue_len = remaining;
367 memcpy(ctx->queue, &input[offset], remaining);
370 return (0);
373 int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
374 unsigned char mac[16]) {
375 POLY1305_VALIDATE_RET(ctx != NULL);
376 POLY1305_VALIDATE_RET(mac != NULL);
378 /* Process any leftover data */
379 if (ctx->queue_len > 0U) {
380 /* Add padding bit */
381 ctx->queue[ctx->queue_len] = 1U;
382 ctx->queue_len++;
384 /* Pad with zeroes */
385 memset(&ctx->queue[ctx->queue_len],
387 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len);
389 poly1305_process(ctx, 1U, /* Process 1 block */
390 ctx->queue, 0U); /* Already padded above */
393 poly1305_compute_mac(ctx, mac);
395 return (0);
398 int mbedtls_poly1305_mac(const unsigned char key[32],
399 const unsigned char *input,
400 size_t ilen,
401 unsigned char mac[16]) {
402 mbedtls_poly1305_context ctx;
403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404 POLY1305_VALIDATE_RET(key != NULL);
405 POLY1305_VALIDATE_RET(mac != NULL);
406 POLY1305_VALIDATE_RET(ilen == 0 || input != NULL);
408 mbedtls_poly1305_init(&ctx);
410 ret = mbedtls_poly1305_starts(&ctx, key);
411 if (ret != 0)
412 goto cleanup;
414 ret = mbedtls_poly1305_update(&ctx, input, ilen);
415 if (ret != 0)
416 goto cleanup;
418 ret = mbedtls_poly1305_finish(&ctx, mac);
420 cleanup:
421 mbedtls_poly1305_free(&ctx);
422 return (ret);
425 #endif /* MBEDTLS_POLY1305_ALT */
427 #if defined(MBEDTLS_SELF_TEST)
429 static const unsigned char test_keys[2][32] = {
431 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
432 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
433 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
434 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
437 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
438 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
439 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
440 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
444 static const unsigned char test_data[2][127] = {
446 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
447 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
448 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
449 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
450 0x75, 0x70
453 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
454 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
455 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
456 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
457 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
458 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
459 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
460 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
461 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
462 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
463 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
464 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
465 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
466 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
467 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
468 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
472 static const size_t test_data_len[2] = {
473 34U,
474 127U
477 static const unsigned char test_mac[2][16] = {
479 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
480 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
483 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
484 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
488 /* Make sure no other definition is already present. */
489 #undef ASSERT
491 #define ASSERT( cond, args ) \
492 do \
494 if( ! ( cond ) ) \
496 if( verbose != 0 ) \
497 mbedtls_printf args; \
499 return( -1 ); \
502 while( 0 )
504 int mbedtls_poly1305_self_test(int verbose) {
505 unsigned char mac[16];
506 unsigned i;
507 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
509 for (i = 0U; i < 2U; i++) {
510 if (verbose != 0)
511 mbedtls_printf(" Poly1305 test %u ", i);
513 ret = mbedtls_poly1305_mac(test_keys[i],
514 test_data[i],
515 test_data_len[i],
516 mac);
517 ASSERT(0 == ret, ("error code: %i\n", ret));
519 ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n"));
521 if (verbose != 0)
522 mbedtls_printf("passed\n");
525 if (verbose != 0)
526 mbedtls_printf("\n");
528 return (0);
531 #endif /* MBEDTLS_SELF_TEST */
533 #endif /* MBEDTLS_POLY1305_C */