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