4 * \brief Poly1305 authentication algorithm.
\r
6 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
\r
7 * SPDX-License-Identifier: Apache-2.0
\r
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
\r
10 * not use this file except in compliance with the License.
\r
11 * You may obtain a copy of the License at
\r
13 * http://www.apache.org/licenses/LICENSE-2.0
\r
15 * Unless required by applicable law or agreed to in writing, software
\r
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
\r
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
18 * See the License for the specific language governing permissions and
\r
19 * limitations under the License.
\r
21 * This file is part of mbed TLS (https://tls.mbed.org)
\r
23 #if !defined(MBEDTLS_CONFIG_FILE)
\r
24 #include "mbedtls/config.h"
\r
26 #include MBEDTLS_CONFIG_FILE
\r
29 #if defined(MBEDTLS_POLY1305_C)
\r
31 #include "mbedtls/poly1305.h"
\r
32 #include "mbedtls/platform_util.h"
\r
36 #if defined(MBEDTLS_SELF_TEST)
\r
37 #if defined(MBEDTLS_PLATFORM_C)
\r
38 #include "mbedtls/platform.h"
\r
41 #define mbedtls_printf printf
\r
42 #endif /* MBEDTLS_PLATFORM_C */
\r
43 #endif /* MBEDTLS_SELF_TEST */
\r
45 #if !defined(MBEDTLS_POLY1305_ALT)
\r
47 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
\r
48 !defined(inline) && !defined(__cplusplus)
\r
49 #define inline __inline
\r
52 /* Parameter validation macros */
\r
53 #define POLY1305_VALIDATE_RET( cond ) \
\r
54 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
\r
55 #define POLY1305_VALIDATE( cond ) \
\r
56 MBEDTLS_INTERNAL_VALIDATE( cond )
\r
58 #define POLY1305_BLOCK_SIZE_BYTES ( 16U )
\r
60 #define BYTES_TO_U32_LE( data, offset ) \
\r
61 ( (uint32_t) (data)[offset] \
\r
62 | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
\r
63 | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
\r
64 | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
\r
68 * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
\r
69 * However we provided an alternative for platforms without such a multiplier.
\r
71 #if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
\r
72 static uint64_t mul64( uint32_t a, uint32_t b )
\r
74 /* a = al + 2**16 ah, b = bl + 2**16 bh */
\r
75 const uint16_t al = (uint16_t) a;
\r
76 const uint16_t bl = (uint16_t) b;
\r
77 const uint16_t ah = a >> 16;
\r
78 const uint16_t bh = b >> 16;
\r
80 /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
\r
81 const uint32_t lo = (uint32_t) al * bl;
\r
82 const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
\r
83 const uint32_t hi = (uint32_t) ah * bh;
\r
85 return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
\r
88 static inline uint64_t mul64( uint32_t a, uint32_t b )
\r
90 return( (uint64_t) a * b );
\r
96 * \brief Process blocks with Poly1305.
\r
98 * \param ctx The Poly1305 context.
\r
99 * \param nblocks Number of blocks to process. Note that this
\r
100 * function only processes full blocks.
\r
101 * \param input Buffer containing the input block(s).
\r
102 * \param needs_padding Set to 0 if the padding bit has already been
\r
103 * applied to the input data before calling this
\r
104 * function. Otherwise, set this parameter to 1.
\r
106 static void poly1305_process( mbedtls_poly1305_context *ctx,
\r
108 const unsigned char *input,
\r
109 uint32_t needs_padding )
\r
111 uint64_t d0, d1, d2, d3;
\r
112 uint32_t acc0, acc1, acc2, acc3, acc4;
\r
113 uint32_t r0, r1, r2, r3;
\r
114 uint32_t rs1, rs2, rs3;
\r
115 size_t offset = 0U;
\r
123 rs1 = r1 + ( r1 >> 2U );
\r
124 rs2 = r2 + ( r2 >> 2U );
\r
125 rs3 = r3 + ( r3 >> 2U );
\r
127 acc0 = ctx->acc[0];
\r
128 acc1 = ctx->acc[1];
\r
129 acc2 = ctx->acc[2];
\r
130 acc3 = ctx->acc[3];
\r
131 acc4 = ctx->acc[4];
\r
133 /* Process full blocks */
\r
134 for( i = 0U; i < nblocks; i++ )
\r
136 /* The input block is treated as a 128-bit little-endian integer */
\r
137 d0 = BYTES_TO_U32_LE( input, offset + 0 );
\r
138 d1 = BYTES_TO_U32_LE( input, offset + 4 );
\r
139 d2 = BYTES_TO_U32_LE( input, offset + 8 );
\r
140 d3 = BYTES_TO_U32_LE( input, offset + 12 );
\r
142 /* Compute: acc += (padded) block as a 130-bit integer */
\r
143 d0 += (uint64_t) acc0;
\r
144 d1 += (uint64_t) acc1 + ( d0 >> 32U );
\r
145 d2 += (uint64_t) acc2 + ( d1 >> 32U );
\r
146 d3 += (uint64_t) acc3 + ( d2 >> 32U );
\r
147 acc0 = (uint32_t) d0;
\r
148 acc1 = (uint32_t) d1;
\r
149 acc2 = (uint32_t) d2;
\r
150 acc3 = (uint32_t) d3;
\r
151 acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
\r
153 /* Compute: acc *= r */
\r
154 d0 = mul64( acc0, r0 ) +
\r
155 mul64( acc1, rs3 ) +
\r
156 mul64( acc2, rs2 ) +
\r
157 mul64( acc3, rs1 );
\r
158 d1 = mul64( acc0, r1 ) +
\r
159 mul64( acc1, r0 ) +
\r
160 mul64( acc2, rs3 ) +
\r
161 mul64( acc3, rs2 ) +
\r
162 mul64( acc4, rs1 );
\r
163 d2 = mul64( acc0, r2 ) +
\r
164 mul64( acc1, r1 ) +
\r
165 mul64( acc2, r0 ) +
\r
166 mul64( acc3, rs3 ) +
\r
167 mul64( acc4, rs2 );
\r
168 d3 = mul64( acc0, r3 ) +
\r
169 mul64( acc1, r2 ) +
\r
170 mul64( acc2, r1 ) +
\r
171 mul64( acc3, r0 ) +
\r
172 mul64( acc4, rs3 );
\r
175 /* Compute: acc %= (2^130 - 5) (partial remainder) */
\r
176 d1 += ( d0 >> 32 );
\r
177 d2 += ( d1 >> 32 );
\r
178 d3 += ( d2 >> 32 );
\r
179 acc0 = (uint32_t) d0;
\r
180 acc1 = (uint32_t) d1;
\r
181 acc2 = (uint32_t) d2;
\r
182 acc3 = (uint32_t) d3;
\r
183 acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
\r
185 d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
\r
187 acc0 = (uint32_t) d0;
\r
188 d0 = (uint64_t) acc1 + ( d0 >> 32U );
\r
189 acc1 = (uint32_t) d0;
\r
190 d0 = (uint64_t) acc2 + ( d0 >> 32U );
\r
191 acc2 = (uint32_t) d0;
\r
192 d0 = (uint64_t) acc3 + ( d0 >> 32U );
\r
193 acc3 = (uint32_t) d0;
\r
194 d0 = (uint64_t) acc4 + ( d0 >> 32U );
\r
195 acc4 = (uint32_t) d0;
\r
197 offset += POLY1305_BLOCK_SIZE_BYTES;
\r
200 ctx->acc[0] = acc0;
\r
201 ctx->acc[1] = acc1;
\r
202 ctx->acc[2] = acc2;
\r
203 ctx->acc[3] = acc3;
\r
204 ctx->acc[4] = acc4;
\r
208 * \brief Compute the Poly1305 MAC
\r
210 * \param ctx The Poly1305 context.
\r
211 * \param mac The buffer to where the MAC is written. Must be
\r
212 * big enough to contain the 16-byte MAC.
\r
214 static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
\r
215 unsigned char mac[16] )
\r
218 uint32_t g0, g1, g2, g3, g4;
\r
219 uint32_t acc0, acc1, acc2, acc3, acc4;
\r
223 acc0 = ctx->acc[0];
\r
224 acc1 = ctx->acc[1];
\r
225 acc2 = ctx->acc[2];
\r
226 acc3 = ctx->acc[3];
\r
227 acc4 = ctx->acc[4];
\r
229 /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
\r
230 * We do this by calculating acc - (2^130 - 5), then checking if
\r
231 * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
\r
234 /* Calculate acc + -(2^130 - 5) */
\r
235 d = ( (uint64_t) acc0 + 5U );
\r
237 d = ( (uint64_t) acc1 + ( d >> 32 ) );
\r
239 d = ( (uint64_t) acc2 + ( d >> 32 ) );
\r
241 d = ( (uint64_t) acc3 + ( d >> 32 ) );
\r
243 g4 = acc4 + (uint32_t) ( d >> 32U );
\r
245 /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
\r
246 mask = (uint32_t) 0U - ( g4 >> 2U );
\r
249 /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
\r
250 acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
\r
251 acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
\r
252 acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
\r
253 acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
\r
256 d = (uint64_t) acc0 + ctx->s[0];
\r
257 acc0 = (uint32_t) d;
\r
258 d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
\r
259 acc1 = (uint32_t) d;
\r
260 d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
\r
261 acc2 = (uint32_t) d;
\r
262 acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
\r
264 /* Compute MAC (128 least significant bits of the accumulator) */
\r
265 mac[ 0] = (unsigned char)( acc0 );
\r
266 mac[ 1] = (unsigned char)( acc0 >> 8 );
\r
267 mac[ 2] = (unsigned char)( acc0 >> 16 );
\r
268 mac[ 3] = (unsigned char)( acc0 >> 24 );
\r
269 mac[ 4] = (unsigned char)( acc1 );
\r
270 mac[ 5] = (unsigned char)( acc1 >> 8 );
\r
271 mac[ 6] = (unsigned char)( acc1 >> 16 );
\r
272 mac[ 7] = (unsigned char)( acc1 >> 24 );
\r
273 mac[ 8] = (unsigned char)( acc2 );
\r
274 mac[ 9] = (unsigned char)( acc2 >> 8 );
\r
275 mac[10] = (unsigned char)( acc2 >> 16 );
\r
276 mac[11] = (unsigned char)( acc2 >> 24 );
\r
277 mac[12] = (unsigned char)( acc3 );
\r
278 mac[13] = (unsigned char)( acc3 >> 8 );
\r
279 mac[14] = (unsigned char)( acc3 >> 16 );
\r
280 mac[15] = (unsigned char)( acc3 >> 24 );
\r
283 void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
\r
285 POLY1305_VALIDATE( ctx != NULL );
\r
287 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
\r
290 void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
\r
295 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
\r
298 int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
\r
299 const unsigned char key[32] )
\r
301 POLY1305_VALIDATE_RET( ctx != NULL );
\r
302 POLY1305_VALIDATE_RET( key != NULL );
\r
304 /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
\r
305 ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
\r
306 ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
\r
307 ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
\r
308 ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
\r
310 ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
\r
311 ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
\r
312 ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
\r
313 ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
\r
315 /* Initial accumulator state */
\r
322 /* Queue initially empty */
\r
323 mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
\r
324 ctx->queue_len = 0U;
\r
329 int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
\r
330 const unsigned char *input,
\r
333 size_t offset = 0U;
\r
334 size_t remaining = ilen;
\r
335 size_t queue_free_len;
\r
337 POLY1305_VALIDATE_RET( ctx != NULL );
\r
338 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
\r
340 if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
\r
342 queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
\r
344 if( ilen < queue_free_len )
\r
346 /* Not enough data to complete the block.
\r
347 * Store this data with the other leftovers.
\r
349 memcpy( &ctx->queue[ctx->queue_len],
\r
353 ctx->queue_len += ilen;
\r
359 /* Enough data to produce a complete block */
\r
360 memcpy( &ctx->queue[ctx->queue_len],
\r
364 ctx->queue_len = 0U;
\r
366 poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
\r
368 offset += queue_free_len;
\r
369 remaining -= queue_free_len;
\r
373 if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
\r
375 nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
\r
377 poly1305_process( ctx, nblocks, &input[offset], 1U );
\r
379 offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
\r
380 remaining %= POLY1305_BLOCK_SIZE_BYTES;
\r
383 if( remaining > 0U )
\r
385 /* Store partial block */
\r
386 ctx->queue_len = remaining;
\r
387 memcpy( ctx->queue, &input[offset], remaining );
\r
393 int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
\r
394 unsigned char mac[16] )
\r
396 POLY1305_VALIDATE_RET( ctx != NULL );
\r
397 POLY1305_VALIDATE_RET( mac != NULL );
\r
399 /* Process any leftover data */
\r
400 if( ctx->queue_len > 0U )
\r
402 /* Add padding bit */
\r
403 ctx->queue[ctx->queue_len] = 1U;
\r
406 /* Pad with zeroes */
\r
407 memset( &ctx->queue[ctx->queue_len],
\r
409 POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
\r
411 poly1305_process( ctx, 1U, /* Process 1 block */
\r
412 ctx->queue, 0U ); /* Already padded above */
\r
415 poly1305_compute_mac( ctx, mac );
\r
420 int mbedtls_poly1305_mac( const unsigned char key[32],
\r
421 const unsigned char *input,
\r
423 unsigned char mac[16] )
\r
425 mbedtls_poly1305_context ctx;
\r
427 POLY1305_VALIDATE_RET( key != NULL );
\r
428 POLY1305_VALIDATE_RET( mac != NULL );
\r
429 POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
\r
431 mbedtls_poly1305_init( &ctx );
\r
433 ret = mbedtls_poly1305_starts( &ctx, key );
\r
437 ret = mbedtls_poly1305_update( &ctx, input, ilen );
\r
441 ret = mbedtls_poly1305_finish( &ctx, mac );
\r
444 mbedtls_poly1305_free( &ctx );
\r
448 #endif /* MBEDTLS_POLY1305_ALT */
\r
450 #if defined(MBEDTLS_SELF_TEST)
\r
452 static const unsigned char test_keys[2][32] =
\r
455 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
\r
456 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
\r
457 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
\r
458 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
\r
461 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
\r
462 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
\r
463 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
\r
464 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
\r
468 static const unsigned char test_data[2][127] =
\r
471 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
\r
472 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
\r
473 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
\r
474 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
\r
478 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
\r
479 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
\r
480 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
\r
481 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
\r
482 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
\r
483 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
\r
484 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
\r
485 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
\r
486 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
\r
487 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
\r
488 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
\r
489 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
\r
490 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
\r
491 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
\r
492 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
\r
493 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
\r
497 static const size_t test_data_len[2] =
\r
503 static const unsigned char test_mac[2][16] =
\r
506 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
\r
507 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
\r
510 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
\r
511 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
\r
515 #define ASSERT( cond, args ) \
\r
520 if( verbose != 0 ) \
\r
521 mbedtls_printf args; \
\r
528 int mbedtls_poly1305_self_test( int verbose )
\r
530 unsigned char mac[16];
\r
534 for( i = 0U; i < 2U; i++ )
\r
537 mbedtls_printf( " Poly1305 test %u ", i );
\r
539 ret = mbedtls_poly1305_mac( test_keys[i],
\r
543 ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
\r
545 ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
\r
548 mbedtls_printf( "passed\n" );
\r
552 mbedtls_printf( "\n" );
\r
557 #endif /* MBEDTLS_SELF_TEST */
\r
559 #endif /* MBEDTLS_POLY1305_C */
\r