blob: f9bdf2c939256b4797be149356dda5ec64102892 [file] [log] [blame]
Daniel Kingadc32c02016-05-16 18:25:45 -03001/**
2 * \file poly1305.c
3 *
4 * \brief Poly1305 authentication algorithm.
5 *
6 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
7 * 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.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23#if !defined(MBEDTLS_CONFIG_FILE)
24#include "mbedtls/config.h"
25#else
26#include MBEDTLS_CONFIG_FILE
27#endif
28
29#if defined(MBEDTLS_POLY1305_C)
30
31#if !defined(MBEDTLS_POLY1305_ALT)
32
33#include "mbedtls/poly1305.h"
34
35#include <string.h>
36
37#if defined(MBEDTLS_SELF_TEST)
38#if defined(MBEDTLS_PLATFORM_C)
39#include "mbedtls/platform.h"
40#else
41#include <stdio.h>
42#define mbedtls_printf printf
43#endif /* MBEDTLS_PLATFORM_C */
44#endif /* MBEDTLS_SELF_TEST */
45
46#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
47
48#define BYTES_TO_U32_LE( data, offset ) \
49 ( (uint32_t)data[offset] | \
50 (uint32_t)( (uint32_t)data[(offset) + 1] << 8 ) | \
51 (uint32_t)( (uint32_t)data[(offset) + 2] << 16 ) | \
52 (uint32_t)( (uint32_t)data[(offset) + 3] << 24 ) \
53 )
54
55/* Implementation that should never be optimized out by the compiler */
56static void mbedtls_zeroize( void *v, size_t n ) {
57 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
58}
59
60/**
61 * \brief Process blocks with Poly1305.
62 *
63 * \param ctx The Poly1305 context.
64 * \param nblocks Number of blocks to process. Note that this function
65 * only processes full blocks.
66 * \param input Buffer containing the input block(s).
67 * \param needs_padding Set to 0 if the padding bit has already been applied
68 * to the input data before calling this function.
69 * Otherwise, set this parameter to 1.
70 */
71static void mbedtls_poly1305_process( mbedtls_poly1305_context *ctx,
72 size_t nblocks,
73 const unsigned char *input,
74 uint32_t needs_padding )
75{
76 uint64_t d0, d1, d2, d3;
77 uint32_t acc0, acc1, acc2, acc3, acc4;
78 uint32_t r0, r1, r2, r3;
79 uint32_t rs1, rs2, rs3;
80 size_t offset = 0U;
81 size_t i;
82
83 r0 = ctx->r[0];
84 r1 = ctx->r[1];
85 r2 = ctx->r[2];
86 r3 = ctx->r[3];
87
88 rs1 = r1 + ( r1 >> 2U );
89 rs2 = r2 + ( r2 >> 2U );
90 rs3 = r3 + ( r3 >> 2U );
91
92 acc0 = ctx->acc[0];
93 acc1 = ctx->acc[1];
94 acc2 = ctx->acc[2];
95 acc3 = ctx->acc[3];
96 acc4 = ctx->acc[4];
97
98 /* Process full blocks */
99 for ( i = 0U; i < nblocks; i++ )
100 {
101 /* Compute: acc += block */
102 /* Note that the input block is treated as a 128-bit little-endian integer */
103 d0 = (uint64_t)acc0 + BYTES_TO_U32_LE( input, offset + 0 );
104 d1 = (uint64_t)acc1 + BYTES_TO_U32_LE( input, offset + 4 ) + ( d0 >> 32U );
105 d2 = (uint64_t)acc2 + BYTES_TO_U32_LE( input, offset + 8 ) + ( d1 >> 32U );
106 d3 = (uint64_t)acc3 + BYTES_TO_U32_LE( input, offset + 12 ) + ( d2 >> 32U );
107 acc0 = (uint32_t)d0;
108 acc1 = (uint32_t)d1;
109 acc2 = (uint32_t)d2;
110 acc3 = (uint32_t)d3;
111 acc4 += (uint32_t)( d3 >> 32U ) + needs_padding;
112
113 /* Compute: acc *= r */
114 d0 = ( (uint64_t)acc0 * r0 ) +
115 ( (uint64_t)acc1 * rs3 ) +
116 ( (uint64_t)acc2 * rs2 ) +
117 ( (uint64_t)acc3 * rs1 );
118 d1 = ( (uint64_t)acc0 * r1 ) +
119 ( (uint64_t)acc1 * r0 ) +
120 ( (uint64_t)acc2 * rs3 ) +
121 ( (uint64_t)acc3 * rs2 ) +
122 ( (uint64_t)acc4 * rs1 );
123 d2 = ( (uint64_t)acc0 * r2 ) +
124 ( (uint64_t)acc1 * r1 ) +
125 ( (uint64_t)acc2 * r0 ) +
126 ( (uint64_t)acc3 * rs3 ) +
127 ( (uint64_t)acc4 * rs2 );
128 d3 = ( (uint64_t)acc0 * r3 ) +
129 ( (uint64_t)acc1 * r2 ) +
130 ( (uint64_t)acc2 * r1 ) +
131 ( (uint64_t)acc3 * r0 ) +
132 ( (uint64_t)acc4 * rs3 );
133 acc4 *= r0;
134
135 /* Compute: acc %= (2^130 - 5) (partial remainder) */
136 d1 += ( d0 >> 32 );
137 d2 += ( d1 >> 32 );
138 d3 += ( d2 >> 32 );
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 >> 32 ) + acc4;
144
145 d0 = (uint64_t)acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
146 acc4 &= 3U;
147 acc0 = (uint32_t)d0;
148 d0 = (uint64_t)acc1 + ( d0 >> 32U );
149 acc1 = (uint32_t)d0;
150 d0 = (uint64_t)acc2 + ( d0 >> 32U );
151 acc2 = (uint32_t)d0;
152 d0 = (uint64_t)acc3 + ( d0 >> 32U );
153 acc3 = (uint32_t)d0;
154 d0 = (uint64_t)acc4 + ( d0 >> 32U );
155 acc4 = (uint32_t)d0;
156
157 offset += POLY1305_BLOCK_SIZE_BYTES;
158 }
159
160 ctx->acc[0] = acc0;
161 ctx->acc[1] = acc1;
162 ctx->acc[2] = acc2;
163 ctx->acc[3] = acc3;
164 ctx->acc[4] = acc4;
165}
166
167/**
168 * \brief Compute the Poly1305 MAC
169 *
170 * \param ctx The Poly1305 context.
171 * \param mac The buffer to where the MAC is written. Must be
172 * big enough to contain the 16-byte MAC.
173 */
174static void mbedtls_poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
175 unsigned char mac[16] )
176{
177 uint64_t d;
178 uint32_t g0, g1, g2, g3, g4;
179 uint32_t acc0, acc1, acc2, acc3, acc4;
180 uint32_t mask;
181 uint32_t mask_inv;
182
183 acc0 = ctx->acc[0];
184 acc1 = ctx->acc[1];
185 acc2 = ctx->acc[2];
186 acc3 = ctx->acc[3];
187 acc4 = ctx->acc[4];
188
189 /* Before adding 's' we need to ensure that the accumulator is mod 2^130 - 5.
190 * We do this by calculating acc - (2^130 - 5), then checking if
191 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
192 */
193
194 /* Calculate acc + -(2^130 - 5) */
195 d = ( (uint64_t)acc0 + 5U );
196 g0 = (uint32_t)d;
197 d = ( (uint64_t)acc1 + ( d >> 32 ) );
198 g1 = (uint32_t)d;
199 d = ( (uint64_t)acc2 + ( d >> 32 ) );
200 g2 = (uint32_t)d;
201 d = ( (uint64_t)acc3 + ( d >> 32 ) );
202 g3 = (uint32_t)d;
203 g4 = acc4 + (uint32_t)( d >> 32U );
204
205 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
206 mask = (uint32_t)0U - ( g4 >> 2U );
207 mask_inv = ~mask;
208
209 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
210 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
211 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
212 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
213 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
214
215 /* Add 's' */
216 d = (uint64_t)acc0 + ctx->s[0];
217 acc0 = (uint32_t)d;
218 d = (uint64_t)acc1 + ctx->s[1] + ( d >> 32U );
219 acc1 = (uint32_t)d;
220 d = (uint64_t)acc2 + ctx->s[2] + ( d >> 32U );
221 acc2 = (uint32_t)d;
222 acc3 += ctx->s[3] + (uint32_t)( d >> 32U );
223
224 /* Compute MAC (128 least significant bits of the accumulator) */
225 mac[0] = (uint8_t)acc0;
226 mac[1] = (uint8_t)( acc0 >> 8 );
227 mac[2] = (uint8_t)( acc0 >> 16 );
228 mac[3] = (uint8_t)( acc0 >> 24 );
229 mac[4] = (uint8_t)acc1;
230 mac[5] = (uint8_t)( acc1 >> 8 );
231 mac[6] = (uint8_t)( acc1 >> 16 );
232 mac[7] = (uint8_t)( acc1 >> 24 );
233 mac[8] = (uint8_t)acc2;
234 mac[9] = (uint8_t)( acc2 >> 8 );
235 mac[10] = (uint8_t)( acc2 >> 16 );
236 mac[11] = (uint8_t)( acc2 >> 24 );
237 mac[12] = (uint8_t)acc3;
238 mac[13] = (uint8_t)( acc3 >> 8 );
239 mac[14] = (uint8_t)( acc3 >> 16 );
240 mac[15] = (uint8_t)( acc3 >> 24 );
241}
242
243void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
244{
245 if ( ctx != NULL )
246 {
247 mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) );
248 }
249}
250
251void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
252{
253 if ( ctx != NULL )
254 {
255 mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) );
256 }
257}
258
259int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx,
260 const unsigned char key[32] )
261{
262 if ( ctx == NULL )
263 {
264 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
265 }
266
267 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
268 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
269 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
270 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
271 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
272
273 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
274 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
275 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
276 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
277
278 /* Initial accumulator state */
279 ctx->acc[0] = 0U;
280 ctx->acc[1] = 0U;
281 ctx->acc[2] = 0U;
282 ctx->acc[3] = 0U;
283
284 return 0;
285}
286
287int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
288 size_t ilen,
289 const unsigned char* input )
290{
291 size_t offset = 0U;
292 size_t remaining = ilen;
293 size_t queue_free_len;
294 size_t nblocks;
295
Daniel Kinga310c5e2016-05-17 15:56:26 -0300296 if ( ctx == NULL )
Daniel Kingadc32c02016-05-16 18:25:45 -0300297 {
298 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
299 }
Daniel Kinga310c5e2016-05-17 15:56:26 -0300300 else if ( ( ilen > 0U ) && ( input == NULL ) )
301 {
302 /* input pointer is allowed to be NULL only if ilen == 0 */
303 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
304 }
Daniel Kingadc32c02016-05-16 18:25:45 -0300305
Daniel Kinga310c5e2016-05-17 15:56:26 -0300306 if ( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
Daniel Kingadc32c02016-05-16 18:25:45 -0300307 {
308 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
309
310 if ( ilen < queue_free_len )
311 {
312 /* Not enough data to complete the block.
313 * Store this data with the other leftovers.
314 */
315 memcpy( &ctx->queue[ctx->queue_len],
316 input,
317 ilen );
318
319 ctx->queue_len += ilen;
320
321 remaining = 0U;
322 }
323 else
324 {
325 /* Enough data to produce a complete block */
326 memcpy( &ctx->queue[ctx->queue_len],
327 input,
328 queue_free_len );
329
330 ctx->queue_len = 0U;
331
332 mbedtls_poly1305_process( ctx,
333 1U,
334 ctx->queue,
335 1U ); /* add padding bit */
336
337 offset += queue_free_len;
338 remaining -= queue_free_len;
339 }
340 }
341
342 if ( remaining >= POLY1305_BLOCK_SIZE_BYTES )
343 {
344 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
345
346 mbedtls_poly1305_process( ctx, nblocks, &input[offset], 1U );
347
348 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
349 remaining %= POLY1305_BLOCK_SIZE_BYTES;
350 }
351
352 if ( remaining > 0U )
353 {
354 /* Store partial block */
355 ctx->queue_len = remaining;
356 memcpy( ctx->queue, &input[offset], remaining );
357 }
358
359 return( 0 );
360}
361
362int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
363 unsigned char mac[16] )
364{
365 if ( ( ctx == NULL ) || ( mac == NULL ) )
366 {
367 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
368 }
369
370 /* Process any leftover data */
371 if ( ctx->queue_len > 0U )
372 {
373 /* Add padding bit */
374 ctx->queue[ctx->queue_len] = 1U;
375 ctx->queue_len++;
376
377 /* Pad with zeroes */
378 memset( &ctx->queue[ctx->queue_len],
379 0,
380 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
381
382 mbedtls_poly1305_process( ctx,
383 1U, /* Process 1 block */
384 ctx->queue,
385 0U ); /* Don't add padding bit (it was just added above) */
386 }
387
388 mbedtls_poly1305_compute_mac( ctx, mac );
389
390 return( 0 );
391}
392
393#endif /* MBEDTLS_POLY1305_ALT */
394
395int mbedtls_poly1305_mac( const unsigned char key[32],
396 size_t ilen,
397 const unsigned char *input,
398 unsigned char mac[16] )
399{
400 mbedtls_poly1305_context ctx;
401 int result;
402
403 mbedtls_poly1305_init( &ctx );
404
405 result = mbedtls_poly1305_setkey( &ctx, key );
406 if ( result != 0 )
407 goto cleanup;
408
409 result = mbedtls_poly1305_update( &ctx, ilen, input );
410 if ( result != 0 )
411 goto cleanup;
412
413 result = mbedtls_poly1305_finish( &ctx, mac );
414
415cleanup:
416 mbedtls_poly1305_free( &ctx );
417 return( 0 );
418}
419
420#if defined(MBEDTLS_SELF_TEST)
421
422static const unsigned char test_keys[2][32] =
423{
424 {
425 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
426 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
427 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
428 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
429 },
430 {
431 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
432 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
433 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
434 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
435 }
436};
437
438static const unsigned char test_data[2][127] =
439{
440 {
441 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
442 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
443 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
444 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
445 0x75, 0x70
446 },
447 {
448 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
449 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
450 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
451 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
452 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
453 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
454 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
455 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
456 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
457 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
458 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
459 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
460 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
461 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
462 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
463 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
464 }
465};
466
467static const size_t test_data_len[2] =
468{
469 34U,
470 127U
471};
472
473static const unsigned char test_mac[2][16] =
474{
475 {
476 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
477 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
478 },
479 {
480 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
481 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
482 }
483};
484
485int mbedtls_poly1305_self_test( int verbose )
486{
487 uint8_t mac[16];
488 size_t i;
489 int result;
490
491 for ( i = 0U; i < 2U; i++ )
492 {
493 result = mbedtls_poly1305_mac( test_keys[i],
494 test_data_len[i],
495 test_data[i],
496 mac );
497 if ( result != 0 )
498 {
499 if ( verbose != 0 )
500 {
501 mbedtls_printf( "Poly1305 test %zi error code: %i\n", i, result );
502 }
503
504 return( -1 );
505 }
506
507 if ( memcmp( mac, test_mac[i], 16U ) != 0 )
508 {
509 if ( verbose != 0 )
510 {
511 mbedtls_printf( "Poly1305 test %zi failed\n", i );
512 }
513
514 return( -1 );
515 }
516 }
517
518 return( 0 );
519}
520
521#endif /* MBEDTLS_SELF_TEST */
522
523#endif /* MBEDTLS_POLY1305_C */