1 /*
2 * NIST SP800-38D compliant GCM implementation
3 *
4 * Copyright The Mbed TLS Contributors
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
20 /*
21 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
28 */
29
30 #include "common.h"
31
32 #if defined(MBEDTLS_GCM_C)
33
34 #include "mbedtls/gcm.h"
35 #include "mbedtls/platform_util.h"
36 #include "mbedtls/error.h"
37
38 #include <string.h>
39
40 #if defined(MBEDTLS_AESNI_C)
41 #include "aesni.h"
42 #endif
43
44 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
45 #include "mbedtls/aes.h"
46 #include "mbedtls/platform.h"
47 #if !defined(MBEDTLS_PLATFORM_C)
48 #include <stdio.h>
49 #define mbedtls_printf printf
50 #endif /* MBEDTLS_PLATFORM_C */
51 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
52
53 #if !defined(MBEDTLS_GCM_ALT)
54
55 /* Parameter validation macros */
56 #define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58 #define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
61 /*
62 * Initialize a context
63 */
mbedtls_gcm_init(mbedtls_gcm_context * ctx)64 void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65 {
66 GCM_VALIDATE( ctx != NULL );
67 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68 }
69
70 /*
71 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
gcm_gen_table(mbedtls_gcm_context * ctx)78 static int gcm_gen_table( mbedtls_gcm_context *ctx )
79 {
80 int ret, i, j;
81 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
84 size_t olen = 0;
85
86 memset( h, 0, 16 );
87 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
88 return( ret );
89
90 /* pack h as two 64-bits ints, big-endian */
91 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
93 vh = (uint64_t) hi << 32 | lo;
94
95 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
96 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
97 vl = (uint64_t) hi << 32 | lo;
98
99 /* 8 = 1000 corresponds to 1 in GF(2^128) */
100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
103 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
104 /* With CLMUL support, we need only h, not the rest of the table */
105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
106 return( 0 );
107 #endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
113 for( i = 4; i > 0; i >>= 1 )
114 {
115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
123 for( i = 2; i <= 8; i *= 2 )
124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
134
135 return( 0 );
136 }
137
mbedtls_gcm_setkey(mbedtls_gcm_context * ctx,mbedtls_cipher_id_t cipher,const unsigned char * key,unsigned int keybits)138 int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
141 unsigned int keybits )
142 {
143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
144 const mbedtls_cipher_info_t *cipher_info;
145
146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
152 if( cipher_info == NULL )
153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
154
155 if( cipher_info->block_size != 16 )
156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
157
158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
161 return( ret );
162
163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
164 MBEDTLS_ENCRYPT ) ) != 0 )
165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
171
172 return( 0 );
173 }
174
175 /*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
180 static const uint64_t last4[16] =
181 {
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186 };
187
188 /*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
gcm_mult(mbedtls_gcm_context * ctx,const unsigned char x[16],unsigned char output[16])192 static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
193 unsigned char output[16] )
194 {
195 int i = 0;
196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
199 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
201 unsigned char h[16];
202
203 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
207
208 mbedtls_aesni_gcm_mult( output, x, h );
209 return;
210 }
211 #endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
212
213 lo = x[15] & 0xf;
214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
221 hi = ( x[i] >> 4 ) & 0xf;
222
223 if( i != 15 )
224 {
225 rem = (unsigned char) zl & 0xf;
226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
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[hi];
239 zl ^= ctx->HL[hi];
240 }
241
242 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
243 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
244 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
245 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
246 }
247
mbedtls_gcm_starts(mbedtls_gcm_context * ctx,int mode,const unsigned char * iv,size_t iv_len)248 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
249 int mode,
250 const unsigned char *iv, size_t iv_len )
251 {
252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
253 unsigned char work_buf[16];
254 size_t i;
255 const unsigned char *p;
256 size_t use_len, olen = 0;
257
258 GCM_VALIDATE_RET( ctx != NULL );
259 GCM_VALIDATE_RET( iv != NULL );
260
261 /* IV is limited to 2^64 bits, so 2^61 bytes */
262 /* IV is not allowed to be zero length */
263 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
264 return( MBEDTLS_ERR_GCM_BAD_INPUT );
265
266 memset( ctx->y, 0x00, sizeof(ctx->y) );
267 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
268
269 ctx->mode = mode;
270 ctx->len = 0;
271 ctx->add_len = 0;
272
273 if( iv_len == 12 )
274 {
275 memcpy( ctx->y, iv, iv_len );
276 ctx->y[15] = 1;
277 }
278 else
279 {
280 memset( work_buf, 0x00, 16 );
281 MBEDTLS_PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
282
283 p = iv;
284 while( iv_len > 0 )
285 {
286 use_len = ( iv_len < 16 ) ? iv_len : 16;
287
288 for( i = 0; i < use_len; i++ )
289 ctx->y[i] ^= p[i];
290
291 gcm_mult( ctx, ctx->y, ctx->y );
292
293 iv_len -= use_len;
294 p += use_len;
295 }
296
297 for( i = 0; i < 16; i++ )
298 ctx->y[i] ^= work_buf[i];
299
300 gcm_mult( ctx, ctx->y, ctx->y );
301 }
302
303 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
304 ctx->base_ectr, &olen ) ) != 0 )
305 {
306 return( ret );
307 }
308
309 return( 0 );
310 }
311
312 /**
313 * mbedtls_gcm_context::buf contains the partial state of the computation of
314 * the authentication tag.
315 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
316 * different stages of the computation:
317 * * len == 0 && add_len == 0: initial state
318 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
319 * a partial block of AD that has been
320 * xored in but not yet multiplied in.
321 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
322 * the data ends now.
323 * * len % 16 != 0: the first `len % 16` bytes have
324 * a partial block of ciphertext that has
325 * been xored in but not yet multiplied in.
326 * * len > 0 && len % 16 == 0: the authentication tag is correct if
327 * the data ends now.
328 */
mbedtls_gcm_update_ad(mbedtls_gcm_context * ctx,const unsigned char * add,size_t add_len)329 int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
330 const unsigned char *add, size_t add_len )
331 {
332 const unsigned char *p;
333 size_t use_len, i, offset;
334
335 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
336
337 /* IV is limited to 2^64 bits, so 2^61 bytes */
338 if( (uint64_t) add_len >> 61 != 0 )
339 return( MBEDTLS_ERR_GCM_BAD_INPUT );
340
341 offset = ctx->add_len % 16;
342 p = add;
343
344 if( offset != 0 )
345 {
346 use_len = 16 - offset;
347 if( use_len > add_len )
348 use_len = add_len;
349
350 for( i = 0; i < use_len; i++ )
351 ctx->buf[i+offset] ^= p[i];
352
353 if( offset + use_len == 16 )
354 gcm_mult( ctx, ctx->buf, ctx->buf );
355
356 ctx->add_len += use_len;
357 add_len -= use_len;
358 p += use_len;
359 }
360
361 ctx->add_len += add_len;
362
363 while( add_len >= 16 )
364 {
365 for( i = 0; i < 16; i++ )
366 ctx->buf[i] ^= p[i];
367
368 gcm_mult( ctx, ctx->buf, ctx->buf );
369
370 add_len -= 16;
371 p += 16;
372 }
373
374 if( add_len > 0 )
375 {
376 for( i = 0; i < add_len; i++ )
377 ctx->buf[i] ^= p[i];
378 }
379
380 return( 0 );
381 }
382
383 /* Increment the counter. */
gcm_incr(unsigned char y[16])384 static void gcm_incr( unsigned char y[16] )
385 {
386 size_t i;
387 for( i = 16; i > 12; i-- )
388 if( ++y[i - 1] != 0 )
389 break;
390 }
391
392 /* Calculate and apply the encryption mask. Process use_len bytes of data,
393 * starting at position offset in the mask block. */
gcm_mask(mbedtls_gcm_context * ctx,unsigned char ectr[16],size_t offset,size_t use_len,const unsigned char * input,unsigned char * output)394 static int gcm_mask( mbedtls_gcm_context *ctx,
395 unsigned char ectr[16],
396 size_t offset, size_t use_len,
397 const unsigned char *input,
398 unsigned char *output )
399 {
400 size_t i;
401 size_t olen = 0;
402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
403
404 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
405 &olen ) ) != 0 )
406 {
407 mbedtls_platform_zeroize( ectr, 16 );
408 return( ret );
409 }
410
411 for( i = 0; i < use_len; i++ )
412 {
413 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
414 ctx->buf[offset + i] ^= input[i];
415 output[i] = ectr[offset + i] ^ input[i];
416 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
417 ctx->buf[offset + i] ^= output[i];
418 }
419 return( 0 );
420 }
421
mbedtls_gcm_update(mbedtls_gcm_context * ctx,const unsigned char * input,size_t input_length,unsigned char * output,size_t output_size,size_t * output_length)422 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
423 const unsigned char *input, size_t input_length,
424 unsigned char *output, size_t output_size,
425 size_t *output_length )
426 {
427 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
428 const unsigned char *p = input;
429 unsigned char *out_p = output;
430 size_t offset;
431 unsigned char ectr[16];
432
433 if( output_size < input_length )
434 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
435 GCM_VALIDATE_RET( output_length != NULL );
436 *output_length = input_length;
437
438 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
439 * on a potentially null pointer.
440 * Returning early also means that the last partial block of AD remains
441 * untouched for mbedtls_gcm_finish */
442 if( input_length == 0 )
443 return( 0 );
444
445 GCM_VALIDATE_RET( ctx != NULL );
446 GCM_VALIDATE_RET( input != NULL );
447 GCM_VALIDATE_RET( output != NULL );
448
449 if( output > input && (size_t) ( output - input ) < input_length )
450 return( MBEDTLS_ERR_GCM_BAD_INPUT );
451
452 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
453 * Also check for possible overflow */
454 if( ctx->len + input_length < ctx->len ||
455 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
456 {
457 return( MBEDTLS_ERR_GCM_BAD_INPUT );
458 }
459
460 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
461 {
462 gcm_mult( ctx, ctx->buf, ctx->buf );
463 }
464
465 offset = ctx->len % 16;
466 if( offset != 0 )
467 {
468 size_t use_len = 16 - offset;
469 if( use_len > input_length )
470 use_len = input_length;
471
472 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
473 return( ret );
474
475 if( offset + use_len == 16 )
476 gcm_mult( ctx, ctx->buf, ctx->buf );
477
478 ctx->len += use_len;
479 input_length -= use_len;
480 p += use_len;
481 out_p += use_len;
482 }
483
484 ctx->len += input_length;
485
486 while( input_length >= 16 )
487 {
488 gcm_incr( ctx->y );
489 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
490 return( ret );
491
492 gcm_mult( ctx, ctx->buf, ctx->buf );
493
494 input_length -= 16;
495 p += 16;
496 out_p += 16;
497 }
498
499 if( input_length > 0 )
500 {
501 gcm_incr( ctx->y );
502 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
503 return( ret );
504 }
505
506 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
507 return( 0 );
508 }
509
mbedtls_gcm_finish(mbedtls_gcm_context * ctx,unsigned char * output,size_t output_size,size_t * output_length,unsigned char * tag,size_t tag_len)510 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
511 unsigned char *output, size_t output_size,
512 size_t *output_length,
513 unsigned char *tag, size_t tag_len )
514 {
515 unsigned char work_buf[16];
516 size_t i;
517 uint64_t orig_len;
518 uint64_t orig_add_len;
519
520 GCM_VALIDATE_RET( ctx != NULL );
521 GCM_VALIDATE_RET( tag != NULL );
522
523 /* We never pass any output in finish(). The output parameter exists only
524 * for the sake of alternative implementations. */
525 (void) output;
526 (void) output_size;
527 *output_length = 0;
528
529 orig_len = ctx->len * 8;
530 orig_add_len = ctx->add_len * 8;
531
532 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
533 {
534 gcm_mult( ctx, ctx->buf, ctx->buf );
535 }
536
537 if( tag_len > 16 || tag_len < 4 )
538 return( MBEDTLS_ERR_GCM_BAD_INPUT );
539
540 if( ctx->len % 16 != 0 )
541 gcm_mult( ctx, ctx->buf, ctx->buf );
542
543 memcpy( tag, ctx->base_ectr, tag_len );
544
545 if( orig_len || orig_add_len )
546 {
547 memset( work_buf, 0x00, 16 );
548
549 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
550 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
551 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
552 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
553
554 for( i = 0; i < 16; i++ )
555 ctx->buf[i] ^= work_buf[i];
556
557 gcm_mult( ctx, ctx->buf, ctx->buf );
558
559 for( i = 0; i < tag_len; i++ )
560 tag[i] ^= ctx->buf[i];
561 }
562
563 return( 0 );
564 }
565
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)566 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
567 int mode,
568 size_t length,
569 const unsigned char *iv,
570 size_t iv_len,
571 const unsigned char *add,
572 size_t add_len,
573 const unsigned char *input,
574 unsigned char *output,
575 size_t tag_len,
576 unsigned char *tag )
577 {
578 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
579 size_t olen;
580
581 GCM_VALIDATE_RET( ctx != NULL );
582 GCM_VALIDATE_RET( iv != NULL );
583 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
584 GCM_VALIDATE_RET( length == 0 || input != NULL );
585 GCM_VALIDATE_RET( length == 0 || output != NULL );
586 GCM_VALIDATE_RET( tag != NULL );
587
588 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
589 return( ret );
590
591 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
592 return( ret );
593
594 if( ( ret = mbedtls_gcm_update( ctx, input, length,
595 output, length, &olen ) ) != 0 )
596 return( ret );
597
598 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
599 return( ret );
600
601 return( 0 );
602 }
603
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)604 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
605 size_t length,
606 const unsigned char *iv,
607 size_t iv_len,
608 const unsigned char *add,
609 size_t add_len,
610 const unsigned char *tag,
611 size_t tag_len,
612 const unsigned char *input,
613 unsigned char *output )
614 {
615 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
616 unsigned char check_tag[16];
617 size_t i;
618 int diff;
619
620 GCM_VALIDATE_RET( ctx != NULL );
621 GCM_VALIDATE_RET( iv != NULL );
622 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
623 GCM_VALIDATE_RET( tag != NULL );
624 GCM_VALIDATE_RET( length == 0 || input != NULL );
625 GCM_VALIDATE_RET( length == 0 || output != NULL );
626
627 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
628 iv, iv_len, add, add_len,
629 input, output, tag_len, check_tag ) ) != 0 )
630 {
631 return( ret );
632 }
633
634 /* Check tag in "constant-time" */
635 for( diff = 0, i = 0; i < tag_len; i++ )
636 diff |= tag[i] ^ check_tag[i];
637
638 if( diff != 0 )
639 {
640 mbedtls_platform_zeroize( output, length );
641 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
642 }
643
644 return( 0 );
645 }
646
mbedtls_gcm_free(mbedtls_gcm_context * ctx)647 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
648 {
649 if( ctx == NULL )
650 return;
651 mbedtls_cipher_free( &ctx->cipher_ctx );
652 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
653 }
654
655 #endif /* !MBEDTLS_GCM_ALT */
656
657 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
658 /*
659 * AES-GCM test vectors from:
660 *
661 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
662 */
663 #define MAX_TESTS 6
664
665 static const int key_index_test_data[MAX_TESTS] =
666 { 0, 0, 1, 1, 1, 1 };
667
668 static const unsigned char key_test_data[MAX_TESTS][32] =
669 {
670 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
674 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
675 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
676 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
677 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
678 };
679
680 static const size_t iv_len_test_data[MAX_TESTS] =
681 { 12, 12, 12, 12, 8, 60 };
682
683 static const int iv_index_test_data[MAX_TESTS] =
684 { 0, 0, 1, 1, 1, 2 };
685
686 static const unsigned char iv_test_data[MAX_TESTS][64] =
687 {
688 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00 },
690 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
691 0xde, 0xca, 0xf8, 0x88 },
692 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
693 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
694 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
695 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
696 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
697 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
698 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
699 0xa6, 0x37, 0xb3, 0x9b },
700 };
701
702 static const size_t add_len_test_data[MAX_TESTS] =
703 { 0, 0, 0, 20, 20, 20 };
704
705 static const int add_index_test_data[MAX_TESTS] =
706 { 0, 0, 0, 1, 1, 1 };
707
708 static const unsigned char additional_test_data[MAX_TESTS][64] =
709 {
710 { 0x00 },
711 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
712 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
713 0xab, 0xad, 0xda, 0xd2 },
714 };
715
716 static const size_t pt_len_test_data[MAX_TESTS] =
717 { 0, 16, 64, 60, 60, 60 };
718
719 static const int pt_index_test_data[MAX_TESTS] =
720 { 0, 0, 1, 1, 1, 1 };
721
722 static const unsigned char pt_test_data[MAX_TESTS][64] =
723 {
724 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
726 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
727 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
728 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
729 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
730 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
731 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
732 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
733 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
734 };
735
736 static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
737 {
738 { 0x00 },
739 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
740 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
741 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
742 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
743 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
744 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
745 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
746 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
747 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
748 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
749 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
750 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
751 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
752 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
753 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
754 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
755 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
756 0x3d, 0x58, 0xe0, 0x91 },
757 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
758 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
759 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
760 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
761 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
762 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
763 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
764 0xc2, 0x3f, 0x45, 0x98 },
765 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
766 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
767 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
768 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
769 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
770 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
771 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
772 0x4c, 0x34, 0xae, 0xe5 },
773 { 0x00 },
774 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
775 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
776 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
777 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
778 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
779 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
780 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
781 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
782 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
783 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
784 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
785 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
786 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
787 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
788 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
789 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
790 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
791 0xcc, 0xda, 0x27, 0x10 },
792 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
793 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
794 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
795 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
796 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
797 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
798 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
799 0xa0, 0xf0, 0x62, 0xf7 },
800 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
801 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
802 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
803 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
804 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
805 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
806 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
807 0xe9, 0xb7, 0x37, 0x3b },
808 { 0x00 },
809 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
810 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
811 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
812 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
813 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
814 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
815 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
816 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
817 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
818 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
819 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
820 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
821 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
822 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
823 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
824 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
825 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
826 0xbc, 0xc9, 0xf6, 0x62 },
827 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
828 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
829 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
830 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
831 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
832 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
833 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
834 0xf4, 0x7c, 0x9b, 0x1f },
835 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
836 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
837 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
838 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
839 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
840 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
841 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
842 0x44, 0xae, 0x7e, 0x3f },
843 };
844
845 static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
846 {
847 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
848 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
849 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
850 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
851 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
852 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
853 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
854 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
855 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
856 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
857 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
858 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
859 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
860 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
861 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
862 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
863 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
864 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
865 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
866 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
867 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
868 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
869 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
870 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
871 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
872 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
873 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
874 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
875 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
876 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
877 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
878 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
879 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
880 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
881 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
882 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
883 };
884
mbedtls_gcm_self_test(int verbose)885 int mbedtls_gcm_self_test( int verbose )
886 {
887 mbedtls_gcm_context ctx;
888 unsigned char buf[64];
889 unsigned char tag_buf[16];
890 int i, j, ret;
891 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
892 size_t olen;
893
894 for( j = 0; j < 3; j++ )
895 {
896 int key_len = 128 + 64 * j;
897
898 for( i = 0; i < MAX_TESTS; i++ )
899 {
900 mbedtls_gcm_init( &ctx );
901
902 if( verbose != 0 )
903 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
904 key_len, i, "enc" );
905
906 ret = mbedtls_gcm_setkey( &ctx, cipher,
907 key_test_data[key_index_test_data[i]],
908 key_len );
909 /*
910 * AES-192 is an optional feature that may be unavailable when
911 * there is an alternative underlying implementation i.e. when
912 * MBEDTLS_AES_ALT is defined.
913 */
914 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
915 {
916 mbedtls_printf( "skipped\n" );
917 break;
918 }
919 else if( ret != 0 )
920 {
921 goto exit;
922 }
923
924 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
925 pt_len_test_data[i],
926 iv_test_data[iv_index_test_data[i]],
927 iv_len_test_data[i],
928 additional_test_data[add_index_test_data[i]],
929 add_len_test_data[i],
930 pt_test_data[pt_index_test_data[i]],
931 buf, 16, tag_buf );
932 #if defined(MBEDTLS_GCM_ALT)
933 /* Allow alternative implementations to only support 12-byte nonces. */
934 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
935 iv_len_test_data[i] != 12 )
936 {
937 mbedtls_printf( "skipped\n" );
938 break;
939 }
940 #endif /* defined(MBEDTLS_GCM_ALT) */
941 if( ret != 0 )
942 goto exit;
943
944 if ( memcmp( buf, ct_test_data[j * 6 + i],
945 pt_len_test_data[i] ) != 0 ||
946 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
947 {
948 ret = 1;
949 goto exit;
950 }
951
952 mbedtls_gcm_free( &ctx );
953
954 if( verbose != 0 )
955 mbedtls_printf( "passed\n" );
956
957 mbedtls_gcm_init( &ctx );
958
959 if( verbose != 0 )
960 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
961 key_len, i, "dec" );
962
963 ret = mbedtls_gcm_setkey( &ctx, cipher,
964 key_test_data[key_index_test_data[i]],
965 key_len );
966 if( ret != 0 )
967 goto exit;
968
969 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
970 pt_len_test_data[i],
971 iv_test_data[iv_index_test_data[i]],
972 iv_len_test_data[i],
973 additional_test_data[add_index_test_data[i]],
974 add_len_test_data[i],
975 ct_test_data[j * 6 + i], buf, 16, tag_buf );
976
977 if( ret != 0 )
978 goto exit;
979
980 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
981 pt_len_test_data[i] ) != 0 ||
982 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
983 {
984 ret = 1;
985 goto exit;
986 }
987
988 mbedtls_gcm_free( &ctx );
989
990 if( verbose != 0 )
991 mbedtls_printf( "passed\n" );
992
993 mbedtls_gcm_init( &ctx );
994
995 if( verbose != 0 )
996 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
997 key_len, i, "enc" );
998
999 ret = mbedtls_gcm_setkey( &ctx, cipher,
1000 key_test_data[key_index_test_data[i]],
1001 key_len );
1002 if( ret != 0 )
1003 goto exit;
1004
1005 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
1006 iv_test_data[iv_index_test_data[i]],
1007 iv_len_test_data[i] );
1008 if( ret != 0 )
1009 goto exit;
1010
1011 ret = mbedtls_gcm_update_ad( &ctx,
1012 additional_test_data[add_index_test_data[i]],
1013 add_len_test_data[i] );
1014 if( ret != 0 )
1015 goto exit;
1016
1017 if( pt_len_test_data[i] > 32 )
1018 {
1019 size_t rest_len = pt_len_test_data[i] - 32;
1020 ret = mbedtls_gcm_update( &ctx,
1021 pt_test_data[pt_index_test_data[i]],
1022 32,
1023 buf, sizeof( buf ), &olen );
1024 if( ret != 0 )
1025 goto exit;
1026 if( olen != 32 )
1027 goto exit;
1028
1029 ret = mbedtls_gcm_update( &ctx,
1030 pt_test_data[pt_index_test_data[i]] + 32,
1031 rest_len,
1032 buf + 32, sizeof( buf ) - 32, &olen );
1033 if( ret != 0 )
1034 goto exit;
1035 if( olen != rest_len )
1036 goto exit;
1037 }
1038 else
1039 {
1040 ret = mbedtls_gcm_update( &ctx,
1041 pt_test_data[pt_index_test_data[i]],
1042 pt_len_test_data[i],
1043 buf, sizeof( buf ), &olen );
1044 if( ret != 0 )
1045 goto exit;
1046 if( olen != pt_len_test_data[i] )
1047 goto exit;
1048 }
1049
1050 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
1051 if( ret != 0 )
1052 goto exit;
1053
1054 if( memcmp( buf, ct_test_data[j * 6 + i],
1055 pt_len_test_data[i] ) != 0 ||
1056 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
1057 {
1058 ret = 1;
1059 goto exit;
1060 }
1061
1062 mbedtls_gcm_free( &ctx );
1063
1064 if( verbose != 0 )
1065 mbedtls_printf( "passed\n" );
1066
1067 mbedtls_gcm_init( &ctx );
1068
1069 if( verbose != 0 )
1070 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
1071 key_len, i, "dec" );
1072
1073 ret = mbedtls_gcm_setkey( &ctx, cipher,
1074 key_test_data[key_index_test_data[i]],
1075 key_len );
1076 if( ret != 0 )
1077 goto exit;
1078
1079 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
1080 iv_test_data[iv_index_test_data[i]],
1081 iv_len_test_data[i] );
1082 if( ret != 0 )
1083 goto exit;
1084 ret = mbedtls_gcm_update_ad( &ctx,
1085 additional_test_data[add_index_test_data[i]],
1086 add_len_test_data[i] );
1087 if( ret != 0 )
1088 goto exit;
1089
1090 if( pt_len_test_data[i] > 32 )
1091 {
1092 size_t rest_len = pt_len_test_data[i] - 32;
1093 ret = mbedtls_gcm_update( &ctx,
1094 ct_test_data[j * 6 + i], 32,
1095 buf, sizeof( buf ), &olen );
1096 if( ret != 0 )
1097 goto exit;
1098 if( olen != 32 )
1099 goto exit;
1100
1101 ret = mbedtls_gcm_update( &ctx,
1102 ct_test_data[j * 6 + i] + 32,
1103 rest_len,
1104 buf + 32, sizeof( buf ) - 32, &olen );
1105 if( ret != 0 )
1106 goto exit;
1107 if( olen != rest_len )
1108 goto exit;
1109 }
1110 else
1111 {
1112 ret = mbedtls_gcm_update( &ctx,
1113 ct_test_data[j * 6 + i],
1114 pt_len_test_data[i],
1115 buf, sizeof( buf ), &olen );
1116 if( ret != 0 )
1117 goto exit;
1118 if( olen != pt_len_test_data[i] )
1119 goto exit;
1120 }
1121
1122 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
1123 if( ret != 0 )
1124 goto exit;
1125
1126 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1127 pt_len_test_data[i] ) != 0 ||
1128 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
1129 {
1130 ret = 1;
1131 goto exit;
1132 }
1133
1134 mbedtls_gcm_free( &ctx );
1135
1136 if( verbose != 0 )
1137 mbedtls_printf( "passed\n" );
1138 }
1139 }
1140
1141 if( verbose != 0 )
1142 mbedtls_printf( "\n" );
1143
1144 ret = 0;
1145
1146 exit:
1147 if( ret != 0 )
1148 {
1149 if( verbose != 0 )
1150 mbedtls_printf( "failed\n" );
1151 mbedtls_gcm_free( &ctx );
1152 }
1153
1154 return( ret );
1155 }
1156
1157 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1158
1159 #endif /* MBEDTLS_GCM_C */
1160