PolarSSL v1.3.9
gcm.c
Go to the documentation of this file.
1/*
2 * NIST SP800-38D compliant GCM implementation
3 *
4 * Copyright (C) 2006-2014, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26/*
27 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
28 *
29 * See also:
30 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
31 *
32 * We use the algorithm described as Shoup's method with 4-bit tables in
33 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
34 */
35
36#if !defined(POLARSSL_CONFIG_FILE)
37#include "polarssl/config.h"
38#else
39#include POLARSSL_CONFIG_FILE
40#endif
41
42#if defined(POLARSSL_GCM_C)
43
44#include "polarssl/gcm.h"
45
46#if defined(POLARSSL_AESNI_C)
47#include "polarssl/aesni.h"
48#endif
49
50#if defined(POLARSSL_PLATFORM_C)
51#include "polarssl/platform.h"
52#else
53#define polarssl_printf printf
54#endif
55
56/*
57 * 32-bit integer manipulation macros (big endian)
58 */
59#ifndef GET_UINT32_BE
60#define GET_UINT32_BE(n,b,i) \
61{ \
62 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
63 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
65 | ( (uint32_t) (b)[(i) + 3] ); \
66}
67#endif
68
69#ifndef PUT_UINT32_BE
70#define PUT_UINT32_BE(n,b,i) \
71{ \
72 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
73 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
74 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
75 (b)[(i) + 3] = (unsigned char) ( (n) ); \
76}
77#endif
78
79/* Implementation that should never be optimized out by the compiler */
80static void polarssl_zeroize( void *v, size_t n ) {
81 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
82}
83
84/*
85 * Precompute small multiples of H, that is set
86 * HH[i] || HL[i] = H times i,
87 * where i is seen as a field element as in [MGV], ie high-order bits
88 * correspond to low powers of P. The result is stored in the same way, that
89 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
90 * corresponds to P^127.
91 */
92static int gcm_gen_table( gcm_context *ctx )
93{
94 int ret, i, j;
95 uint64_t hi, lo;
96 uint64_t vl, vh;
97 unsigned char h[16];
98 size_t olen = 0;
99
100 memset( h, 0, 16 );
101 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
102 return( ret );
103
104 /* pack h as two 64-bits ints, big-endian */
105 GET_UINT32_BE( hi, h, 0 );
106 GET_UINT32_BE( lo, h, 4 );
107 vh = (uint64_t) hi << 32 | lo;
108
109 GET_UINT32_BE( hi, h, 8 );
110 GET_UINT32_BE( lo, h, 12 );
111 vl = (uint64_t) hi << 32 | lo;
112
113 /* 8 = 1000 corresponds to 1 in GF(2^128) */
114 ctx->HL[8] = vl;
115 ctx->HH[8] = vh;
116
117#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
118 /* With CLMUL support, we need only h, not the rest of the table */
119 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
120 return( 0 );
121#endif
122
123 /* 0 corresponds to 0 in GF(2^128) */
124 ctx->HH[0] = 0;
125 ctx->HL[0] = 0;
126
127 for( i = 4; i > 0; i >>= 1 )
128 {
129 uint32_t T = ( vl & 1 ) * 0xe1000000U;
130 vl = ( vh << 63 ) | ( vl >> 1 );
131 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
132
133 ctx->HL[i] = vl;
134 ctx->HH[i] = vh;
135 }
136
137 for( i = 2; i < 16; i <<= 1 )
138 {
139 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
140 vh = *HiH;
141 vl = *HiL;
142 for( j = 1; j < i; j++ )
143 {
144 HiH[j] = vh ^ ctx->HH[j];
145 HiL[j] = vl ^ ctx->HL[j];
146 }
147 }
148
149 return( 0 );
150}
151
152int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
153 unsigned int keysize )
154{
155 int ret;
156 const cipher_info_t *cipher_info;
157
158 memset( ctx, 0, sizeof(gcm_context) );
159
160 cipher_init( &ctx->cipher_ctx );
161
162 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
163 if( cipher_info == NULL )
165
166 if( cipher_info->block_size != 16 )
168
169 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
170 return( ret );
171
172 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
173 POLARSSL_ENCRYPT ) ) != 0 )
174 {
175 return( ret );
176 }
177
178 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
179 return( ret );
180
181 return( 0 );
182}
183
184/*
185 * Shoup's method for multiplication use this table with
186 * last4[x] = x times P^128
187 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
188 */
189static const uint64_t last4[16] =
190{
191 0x0000, 0x1c20, 0x3840, 0x2460,
192 0x7080, 0x6ca0, 0x48c0, 0x54e0,
193 0xe100, 0xfd20, 0xd940, 0xc560,
194 0x9180, 0x8da0, 0xa9c0, 0xb5e0
195};
196
197/*
198 * Sets output to x times H using the precomputed tables.
199 * x and output are seen as elements of GF(2^128) as in [MGV].
200 */
201static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
202 unsigned char output[16] )
203{
204 int i = 0;
205 unsigned char lo, hi, rem;
206 uint64_t zh, zl;
207
208#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
209 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
210 unsigned char h[16];
211
212 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
213 PUT_UINT32_BE( ctx->HH[8], h, 4 );
214 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
215 PUT_UINT32_BE( ctx->HL[8], h, 12 );
216
217 aesni_gcm_mult( output, x, h );
218 return;
219 }
220#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
221
222 lo = x[15] & 0xf;
223
224 zh = ctx->HH[lo];
225 zl = ctx->HL[lo];
226
227 for( i = 15; i >= 0; i-- )
228 {
229 lo = x[i] & 0xf;
230 hi = x[i] >> 4;
231
232 if( i != 15 )
233 {
234 rem = (unsigned char) zl & 0xf;
235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[lo];
239 zl ^= ctx->HL[lo];
240
241 }
242
243 rem = (unsigned char) zl & 0xf;
244 zl = ( zh << 60 ) | ( zl >> 4 );
245 zh = ( zh >> 4 );
246 zh ^= (uint64_t) last4[rem] << 48;
247 zh ^= ctx->HH[hi];
248 zl ^= ctx->HL[hi];
249 }
250
251 PUT_UINT32_BE( zh >> 32, output, 0 );
252 PUT_UINT32_BE( zh, output, 4 );
253 PUT_UINT32_BE( zl >> 32, output, 8 );
254 PUT_UINT32_BE( zl, output, 12 );
255}
256
257int gcm_starts( gcm_context *ctx,
258 int mode,
259 const unsigned char *iv,
260 size_t iv_len,
261 const unsigned char *add,
262 size_t add_len )
263{
264 int ret;
265 unsigned char work_buf[16];
266 size_t i;
267 const unsigned char *p;
268 size_t use_len, olen = 0;
269
270 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
271 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
272 ( (uint64_t) add_len ) >> 61 != 0 )
273 {
275 }
276
277 memset( ctx->y, 0x00, sizeof(ctx->y) );
278 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
279
280 ctx->mode = mode;
281 ctx->len = 0;
282 ctx->add_len = 0;
283
284 if( iv_len == 12 )
285 {
286 memcpy( ctx->y, iv, iv_len );
287 ctx->y[15] = 1;
288 }
289 else
290 {
291 memset( work_buf, 0x00, 16 );
292 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
293
294 p = iv;
295 while( iv_len > 0 )
296 {
297 use_len = ( iv_len < 16 ) ? iv_len : 16;
298
299 for( i = 0; i < use_len; i++ )
300 ctx->y[i] ^= p[i];
301
302 gcm_mult( ctx, ctx->y, ctx->y );
303
304 iv_len -= use_len;
305 p += use_len;
306 }
307
308 for( i = 0; i < 16; i++ )
309 ctx->y[i] ^= work_buf[i];
310
311 gcm_mult( ctx, ctx->y, ctx->y );
312 }
313
314 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
315 &olen ) ) != 0 )
316 {
317 return( ret );
318 }
319
320 ctx->add_len = add_len;
321 p = add;
322 while( add_len > 0 )
323 {
324 use_len = ( add_len < 16 ) ? add_len : 16;
325
326 for( i = 0; i < use_len; i++ )
327 ctx->buf[i] ^= p[i];
328
329 gcm_mult( ctx, ctx->buf, ctx->buf );
330
331 add_len -= use_len;
332 p += use_len;
333 }
334
335 return( 0 );
336}
337
338int gcm_update( gcm_context *ctx,
339 size_t length,
340 const unsigned char *input,
341 unsigned char *output )
342{
343 int ret;
344 unsigned char ectr[16];
345 size_t i;
346 const unsigned char *p;
347 unsigned char *out_p = output;
348 size_t use_len, olen = 0;
349
350 if( output > input && (size_t) ( output - input ) < length )
352
353 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
354 * Also check for possible overflow */
355 if( ctx->len + length < ctx->len ||
356 (uint64_t) ctx->len + length > 0x03FFFFE0ull )
357 {
359 }
360
361 ctx->len += length;
362
363 p = input;
364 while( length > 0 )
365 {
366 use_len = ( length < 16 ) ? length : 16;
367
368 for( i = 16; i > 12; i-- )
369 if( ++ctx->y[i - 1] != 0 )
370 break;
371
372 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
373 &olen ) ) != 0 )
374 {
375 return( ret );
376 }
377
378 for( i = 0; i < use_len; i++ )
379 {
380 if( ctx->mode == GCM_DECRYPT )
381 ctx->buf[i] ^= p[i];
382 out_p[i] = ectr[i] ^ p[i];
383 if( ctx->mode == GCM_ENCRYPT )
384 ctx->buf[i] ^= out_p[i];
385 }
386
387 gcm_mult( ctx, ctx->buf, ctx->buf );
388
389 length -= use_len;
390 p += use_len;
391 out_p += use_len;
392 }
393
394 return( 0 );
395}
396
397int gcm_finish( gcm_context *ctx,
398 unsigned char *tag,
399 size_t tag_len )
400{
401 unsigned char work_buf[16];
402 size_t i;
403 uint64_t orig_len = ctx->len * 8;
404 uint64_t orig_add_len = ctx->add_len * 8;
405
406 if( tag_len > 16 || tag_len < 4 )
408
409 if( tag_len != 0 )
410 memcpy( tag, ctx->base_ectr, tag_len );
411
412 if( orig_len || orig_add_len )
413 {
414 memset( work_buf, 0x00, 16 );
415
416 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
417 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
418 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
419 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
420
421 for( i = 0; i < 16; i++ )
422 ctx->buf[i] ^= work_buf[i];
423
424 gcm_mult( ctx, ctx->buf, ctx->buf );
425
426 for( i = 0; i < tag_len; i++ )
427 tag[i] ^= ctx->buf[i];
428 }
429
430 return( 0 );
431}
432
434 int mode,
435 size_t length,
436 const unsigned char *iv,
437 size_t iv_len,
438 const unsigned char *add,
439 size_t add_len,
440 const unsigned char *input,
441 unsigned char *output,
442 size_t tag_len,
443 unsigned char *tag )
444{
445 int ret;
446
447 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
448 return( ret );
449
450 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
451 return( ret );
452
453 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
454 return( ret );
455
456 return( 0 );
457}
458
460 size_t length,
461 const unsigned char *iv,
462 size_t iv_len,
463 const unsigned char *add,
464 size_t add_len,
465 const unsigned char *tag,
466 size_t tag_len,
467 const unsigned char *input,
468 unsigned char *output )
469{
470 int ret;
471 unsigned char check_tag[16];
472 size_t i;
473 int diff;
474
475 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
476 iv, iv_len, add, add_len,
477 input, output, tag_len, check_tag ) ) != 0 )
478 {
479 return( ret );
480 }
481
482 /* Check tag in "constant-time" */
483 for( diff = 0, i = 0; i < tag_len; i++ )
484 diff |= tag[i] ^ check_tag[i];
485
486 if( diff != 0 )
487 {
488 polarssl_zeroize( output, length );
490 }
491
492 return( 0 );
493}
494
495void gcm_free( gcm_context *ctx )
496{
497 cipher_free( &ctx->cipher_ctx );
498 polarssl_zeroize( ctx, sizeof( gcm_context ) );
499}
500
501#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
502
503#include <stdio.h>
504
505/*
506 * AES-GCM test vectors from:
507 *
508 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
509 */
510#define MAX_TESTS 6
511
512int key_index[MAX_TESTS] =
513 { 0, 0, 1, 1, 1, 1 };
514
515unsigned char key[MAX_TESTS][32] =
516{
517 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
521 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
522 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
523 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
524 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
525};
526
527size_t iv_len[MAX_TESTS] =
528 { 12, 12, 12, 12, 8, 60 };
529
530int iv_index[MAX_TESTS] =
531 { 0, 0, 1, 1, 1, 2 };
532
533unsigned char iv[MAX_TESTS][64] =
534{
535 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00 },
537 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
538 0xde, 0xca, 0xf8, 0x88 },
539 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
540 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
541 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
542 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
543 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
544 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
545 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
546 0xa6, 0x37, 0xb3, 0x9b },
547};
548
549size_t add_len[MAX_TESTS] =
550 { 0, 0, 0, 20, 20, 20 };
551
552int add_index[MAX_TESTS] =
553 { 0, 0, 0, 1, 1, 1 };
554
555unsigned char additional[MAX_TESTS][64] =
556{
557 { 0x00 },
558 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
559 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
560 0xab, 0xad, 0xda, 0xd2 },
561};
562
563size_t pt_len[MAX_TESTS] =
564 { 0, 16, 64, 60, 60, 60 };
565
566int pt_index[MAX_TESTS] =
567 { 0, 0, 1, 1, 1, 1 };
568
569unsigned char pt[MAX_TESTS][64] =
570{
571 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
573 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
574 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
575 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
576 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
577 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
578 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
579 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
580 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
581};
582
583unsigned char ct[MAX_TESTS * 3][64] =
584{
585 { 0x00 },
586 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
587 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
588 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
589 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
590 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
591 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
592 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
593 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
594 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
595 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
596 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
597 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
598 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
599 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
600 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
601 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
602 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
603 0x3d, 0x58, 0xe0, 0x91 },
604 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
605 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
606 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
607 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
608 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
609 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
610 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
611 0xc2, 0x3f, 0x45, 0x98 },
612 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
613 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
614 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
615 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
616 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
617 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
618 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
619 0x4c, 0x34, 0xae, 0xe5 },
620 { 0x00 },
621 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
622 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
623 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
624 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
625 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
626 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
627 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
628 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
629 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
630 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
631 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
632 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
633 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
634 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
635 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
636 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
637 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
638 0xcc, 0xda, 0x27, 0x10 },
639 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
640 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
641 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
642 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
643 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
644 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
645 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
646 0xa0, 0xf0, 0x62, 0xf7 },
647 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
648 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
649 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
650 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
651 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
652 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
653 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
654 0xe9, 0xb7, 0x37, 0x3b },
655 { 0x00 },
656 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
657 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
658 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
659 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
660 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
661 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
662 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
663 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
664 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
665 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
666 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
667 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
668 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
669 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
670 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
671 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
672 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
673 0xbc, 0xc9, 0xf6, 0x62 },
674 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
675 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
676 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
677 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
678 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
679 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
680 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
681 0xf4, 0x7c, 0x9b, 0x1f },
682 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
683 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
684 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
685 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
686 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
687 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
688 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
689 0x44, 0xae, 0x7e, 0x3f },
690};
691
692unsigned char tag[MAX_TESTS * 3][16] =
693{
694 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
695 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
696 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
697 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
698 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
699 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
700 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
701 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
702 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
703 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
704 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
705 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
706 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
707 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
708 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
709 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
710 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
711 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
712 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
713 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
714 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
715 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
716 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
717 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
718 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
719 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
720 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
721 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
722 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
723 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
724 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
725 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
726 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
727 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
728 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
729 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
730};
731
732int gcm_self_test( int verbose )
733{
734 gcm_context ctx;
735 unsigned char buf[64];
736 unsigned char tag_buf[16];
737 int i, j, ret;
739
740 for( j = 0; j < 3; j++ )
741 {
742 int key_len = 128 + 64 * j;
743
744 for( i = 0; i < MAX_TESTS; i++ )
745 {
746 if( verbose != 0 )
747 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
748 key_len, i, "enc" );
749
750 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
751
752 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
753 pt_len[i],
754 iv[iv_index[i]], iv_len[i],
755 additional[add_index[i]], add_len[i],
756 pt[pt_index[i]], buf, 16, tag_buf );
757
758 if( ret != 0 ||
759 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
760 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
761 {
762 if( verbose != 0 )
763 polarssl_printf( "failed\n" );
764
765 return( 1 );
766 }
767
768 gcm_free( &ctx );
769
770 if( verbose != 0 )
771 polarssl_printf( "passed\n" );
772
773 if( verbose != 0 )
774 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
775 key_len, i, "dec" );
776
777 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
778
779 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
780 pt_len[i],
781 iv[iv_index[i]], iv_len[i],
782 additional[add_index[i]], add_len[i],
783 ct[j * 6 + i], buf, 16, tag_buf );
784
785 if( ret != 0 ||
786 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
787 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
788 {
789 if( verbose != 0 )
790 polarssl_printf( "failed\n" );
791
792 return( 1 );
793 }
794
795 gcm_free( &ctx );
796
797 if( verbose != 0 )
798 polarssl_printf( "passed\n" );
799
800 if( verbose != 0 )
801 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
802 key_len, i, "enc" );
803
804 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
805
806 ret = gcm_starts( &ctx, GCM_ENCRYPT,
807 iv[iv_index[i]], iv_len[i],
808 additional[add_index[i]], add_len[i] );
809 if( ret != 0 )
810 {
811 if( verbose != 0 )
812 polarssl_printf( "failed\n" );
813
814 return( 1 );
815 }
816
817 if( pt_len[i] > 32 )
818 {
819 size_t rest_len = pt_len[i] - 32;
820 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
821 if( ret != 0 )
822 {
823 if( verbose != 0 )
824 polarssl_printf( "failed\n" );
825
826 return( 1 );
827 }
828
829 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
830 buf + 32 );
831 if( ret != 0 )
832 {
833 if( verbose != 0 )
834 polarssl_printf( "failed\n" );
835
836 return( 1 );
837 }
838 }
839 else
840 {
841 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
842 if( ret != 0 )
843 {
844 if( verbose != 0 )
845 polarssl_printf( "failed\n" );
846
847 return( 1 );
848 }
849 }
850
851 ret = gcm_finish( &ctx, tag_buf, 16 );
852 if( ret != 0 ||
853 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
854 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
855 {
856 if( verbose != 0 )
857 polarssl_printf( "failed\n" );
858
859 return( 1 );
860 }
861
862 gcm_free( &ctx );
863
864 if( verbose != 0 )
865 polarssl_printf( "passed\n" );
866
867 if( verbose != 0 )
868 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
869 key_len, i, "dec" );
870
871 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
872
873 ret = gcm_starts( &ctx, GCM_DECRYPT,
874 iv[iv_index[i]], iv_len[i],
875 additional[add_index[i]], add_len[i] );
876 if( ret != 0 )
877 {
878 if( verbose != 0 )
879 polarssl_printf( "failed\n" );
880
881 return( 1 );
882 }
883
884 if( pt_len[i] > 32 )
885 {
886 size_t rest_len = pt_len[i] - 32;
887 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
888 if( ret != 0 )
889 {
890 if( verbose != 0 )
891 polarssl_printf( "failed\n" );
892
893 return( 1 );
894 }
895
896 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
897 buf + 32 );
898 if( ret != 0 )
899 {
900 if( verbose != 0 )
901 polarssl_printf( "failed\n" );
902
903 return( 1 );
904 }
905 }
906 else
907 {
908 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
909 if( ret != 0 )
910 {
911 if( verbose != 0 )
912 polarssl_printf( "failed\n" );
913
914 return( 1 );
915 }
916 }
917
918 ret = gcm_finish( &ctx, tag_buf, 16 );
919 if( ret != 0 ||
920 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
921 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
922 {
923 if( verbose != 0 )
924 polarssl_printf( "failed\n" );
925
926 return( 1 );
927 }
928
929 gcm_free( &ctx );
930
931 if( verbose != 0 )
932 polarssl_printf( "passed\n" );
933
934 }
935 }
936
937 if( verbose != 0 )
938 polarssl_printf( "\n" );
939
940 return( 0 );
941}
942
943
944
945#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
946
947#endif /* POLARSSL_GCM_C */
AES-NI for hardware AES acceleration on some Intel processors.
#define POLARSSL_AESNI_CLMUL
Definition aesni.h:33
cipher_id_t
Definition cipher.h:71
@ POLARSSL_CIPHER_ID_AES
Definition cipher.h:74
void cipher_init(cipher_context_t *ctx)
Initialize a cipher_context (as NONE)
@ POLARSSL_ENCRYPT
Definition cipher.h:157
int cipher_setkey(cipher_context_t *ctx, const unsigned char *key, int key_length, const operation_t operation)
Set the key to use with the given context.
int cipher_init_ctx(cipher_context_t *ctx, const cipher_info_t *cipher_info)
Initialises and fills the cipher context structure with the appropriate values.
void cipher_free(cipher_context_t *ctx)
Free and clear the cipher-specific context of ctx.
@ POLARSSL_MODE_ECB
Definition cipher.h:136
int cipher_update(cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
Generic cipher update function.
const cipher_info_t * cipher_info_from_values(const cipher_id_t cipher_id, int key_length, const cipher_mode_t mode)
Returns the cipher information structure associated with the given cipher id, key size and mode.
Configuration options (set of defines)
Galois/Counter mode for 128-bit block ciphers.
void gcm_free(gcm_context *ctx)
Free a GCM context and underlying cipher sub-context.
int gcm_starts(gcm_context *ctx, int mode, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len)
Generic GCM stream start function.
#define POLARSSL_ERR_GCM_AUTH_FAILED
Authenticated decryption failed.
Definition gcm.h:43
#define POLARSSL_ERR_GCM_BAD_INPUT
Bad input parameters to function.
Definition gcm.h:44
int gcm_auth_decrypt(gcm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *tag, size_t tag_len, const unsigned char *input, unsigned char *output)
GCM buffer authenticated decryption using a block cipher.
int gcm_self_test(int verbose)
Checkup routine.
int gcm_finish(gcm_context *ctx, unsigned char *tag, size_t tag_len)
Generic GCM finalisation function.
#define GCM_DECRYPT
Definition gcm.h:41
#define GCM_ENCRYPT
Definition gcm.h:40
int gcm_init(gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, unsigned int keysize)
GCM initialization (encryption)
int gcm_update(gcm_context *ctx, size_t length, const unsigned char *input, unsigned char *output)
Generic GCM update function.
int gcm_crypt_and_tag(gcm_context *ctx, int mode, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, size_t tag_len, unsigned char *tag)
GCM buffer encryption/decryption using a block cipher.
PolarSSL Platform abstraction layer.
Cipher information.
Definition cipher.h:226
unsigned int block_size
block size, in bytes
Definition cipher.h:248
GCM context structure.
Definition gcm.h:53
uint64_t add_len
Definition gcm.h:58
uint64_t len
Definition gcm.h:57
cipher_context_t cipher_ctx
Definition gcm.h:54
unsigned char buf[16]
Definition gcm.h:61
unsigned char base_ectr[16]
Definition gcm.h:59
uint64_t HH[16]
Definition gcm.h:56
uint64_t HL[16]
Definition gcm.h:55
int mode
Definition gcm.h:62
unsigned char y[16]
Definition gcm.h:60
#define GET_UINT32_BE(n, b, i)
#define PUT_UINT32_BE(n, b, i)
#define polarssl_printf