blob: 9a61a85ce8dedd8be8ebc476b5555b7a39941be5 [file] [log] [blame]
Daniel King5d77eaa2016-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
296 if ( ( ctx == NULL ) || ( input == NULL ) )
297 {
298 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
299 }
300
301 if ( ctx->queue_len > 0U )
302 {
303 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
304
305 if ( ilen < queue_free_len )
306 {
307 /* Not enough data to complete the block.
308 * Store this data with the other leftovers.
309 */
310 memcpy( &ctx->queue[ctx->queue_len],
311 input,
312 ilen );
313
314 ctx->queue_len += ilen;
315
316 remaining = 0U;
317 }
318 else
319 {
320 /* Enough data to produce a complete block */
321 memcpy( &ctx->queue[ctx->queue_len],
322 input,
323 queue_free_len );
324
325 ctx->queue_len = 0U;
326
327 mbedtls_poly1305_process( ctx,
328 1U,
329 ctx->queue,
330 1U ); /* add padding bit */
331
332 offset += queue_free_len;
333 remaining -= queue_free_len;
334 }
335 }
336
337 if ( remaining >= POLY1305_BLOCK_SIZE_BYTES )
338 {
339 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
340
341 mbedtls_poly1305_process( ctx, nblocks, &input[offset], 1U );
342
343 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
344 remaining %= POLY1305_BLOCK_SIZE_BYTES;
345 }
346
347 if ( remaining > 0U )
348 {
349 /* Store partial block */
350 ctx->queue_len = remaining;
351 memcpy( ctx->queue, &input[offset], remaining );
352 }
353
354 return( 0 );
355}
356
357int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
358 unsigned char mac[16] )
359{
360 if ( ( ctx == NULL ) || ( mac == NULL ) )
361 {
362 return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
363 }
364
365 /* Process any leftover data */
366 if ( ctx->queue_len > 0U )
367 {
368 /* Add padding bit */
369 ctx->queue[ctx->queue_len] = 1U;
370 ctx->queue_len++;
371
372 /* Pad with zeroes */
373 memset( &ctx->queue[ctx->queue_len],
374 0,
375 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
376
377 mbedtls_poly1305_process( ctx,
378 1U, /* Process 1 block */
379 ctx->queue,
380 0U ); /* Don't add padding bit (it was just added above) */
381 }
382
383 mbedtls_poly1305_compute_mac( ctx, mac );
384
385 return( 0 );
386}
387
388#endif /* MBEDTLS_POLY1305_ALT */
389
390int mbedtls_poly1305_mac( const unsigned char key[32],
391 size_t ilen,
392 const unsigned char *input,
393 unsigned char mac[16] )
394{
395 mbedtls_poly1305_context ctx;
396 int result;
397
398 mbedtls_poly1305_init( &ctx );
399
400 result = mbedtls_poly1305_setkey( &ctx, key );
401 if ( result != 0 )
402 goto cleanup;
403
404 result = mbedtls_poly1305_update( &ctx, ilen, input );
405 if ( result != 0 )
406 goto cleanup;
407
408 result = mbedtls_poly1305_finish( &ctx, mac );
409
410cleanup:
411 mbedtls_poly1305_free( &ctx );
412 return( 0 );
413}
414
415#if defined(MBEDTLS_SELF_TEST)
416
417static const unsigned char test_keys[2][32] =
418{
419 {
420 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
421 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
422 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
423 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
424 },
425 {
426 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
427 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
428 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
429 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
430 }
431};
432
433static const unsigned char test_data[2][127] =
434{
435 {
436 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
437 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
438 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
439 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
440 0x75, 0x70
441 },
442 {
443 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
444 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
445 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
446 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
447 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
448 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
449 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
450 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
451 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
452 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
453 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
454 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
455 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
456 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
457 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
458 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
459 }
460};
461
462static const size_t test_data_len[2] =
463{
464 34U,
465 127U
466};
467
468static const unsigned char test_mac[2][16] =
469{
470 {
471 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
472 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
473 },
474 {
475 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
476 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
477 }
478};
479
480int mbedtls_poly1305_self_test( int verbose )
481{
482 uint8_t mac[16];
483 size_t i;
484 int result;
485
486 for ( i = 0U; i < 2U; i++ )
487 {
488 result = mbedtls_poly1305_mac( test_keys[i],
489 test_data_len[i],
490 test_data[i],
491 mac );
492 if ( result != 0 )
493 {
494 if ( verbose != 0 )
495 {
496 mbedtls_printf( "Poly1305 test %zi error code: %i\n", i, result );
497 }
498
499 return( -1 );
500 }
501
502 if ( memcmp( mac, test_mac[i], 16U ) != 0 )
503 {
504 if ( verbose != 0 )
505 {
506 mbedtls_printf( "Poly1305 test %zi failed\n", i );
507 }
508
509 return( -1 );
510 }
511 }
512
513 return( 0 );
514}
515
516#endif /* MBEDTLS_SELF_TEST */
517
518#endif /* MBEDTLS_POLY1305_C */