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