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 uint64_t iv_bits;
258
259 GCM_VALIDATE_RET( ctx != NULL );
260 GCM_VALIDATE_RET( iv != NULL );
261
262 /* IV is limited to 2^64 bits, so 2^61 bytes */
263 /* IV is not allowed to be zero length */
264 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
265 return( MBEDTLS_ERR_GCM_BAD_INPUT );
266
267 memset( ctx->y, 0x00, sizeof(ctx->y) );
268 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
269
270 ctx->mode = mode;
271 ctx->len = 0;
272 ctx->add_len = 0;
273
274 if( iv_len == 12 )
275 {
276 memcpy( ctx->y, iv, iv_len );
277 ctx->y[15] = 1;
278 }
279 else
280 {
281 memset( work_buf, 0x00, 16 );
282 iv_bits = (uint64_t)iv_len * 8;
283 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
284
285 p = iv;
286 while( iv_len > 0 )
287 {
288 use_len = ( iv_len < 16 ) ? iv_len : 16;
289
290 for( i = 0; i < use_len; i++ )
291 ctx->y[i] ^= p[i];
292
293 gcm_mult( ctx, ctx->y, ctx->y );
294
295 iv_len -= use_len;
296 p += use_len;
297 }
298
299 for( i = 0; i < 16; i++ )
300 ctx->y[i] ^= work_buf[i];
301
302 gcm_mult( ctx, ctx->y, ctx->y );
303 }
304
305 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
306 ctx->base_ectr, &olen ) ) != 0 )
307 {
308 return( ret );
309 }
310
311 return( 0 );
312 }
313
314 /**
315 * mbedtls_gcm_context::buf contains the partial state of the computation of
316 * the authentication tag.
317 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
318 * different stages of the computation:
319 * * len == 0 && add_len == 0: initial state
320 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
321 * a partial block of AD that has been
322 * xored in but not yet multiplied in.
323 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
324 * the data ends now.
325 * * len % 16 != 0: the first `len % 16` bytes have
326 * a partial block of ciphertext that has
327 * been xored in but not yet multiplied in.
328 * * len > 0 && len % 16 == 0: the authentication tag is correct if
329 * the data ends now.
330 */
mbedtls_gcm_update_ad(mbedtls_gcm_context * ctx,const unsigned char * add,size_t add_len)331 int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
332 const unsigned char *add, size_t add_len )
333 {
334 const unsigned char *p;
335 size_t use_len, i, offset;
336
337 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
338
339 /* IV is limited to 2^64 bits, so 2^61 bytes */
340 if( (uint64_t) add_len >> 61 != 0 )
341 return( MBEDTLS_ERR_GCM_BAD_INPUT );
342
343 offset = ctx->add_len % 16;
344 p = add;
345
346 if( offset != 0 )
347 {
348 use_len = 16 - offset;
349 if( use_len > add_len )
350 use_len = add_len;
351
352 for( i = 0; i < use_len; i++ )
353 ctx->buf[i+offset] ^= p[i];
354
355 if( offset + use_len == 16 )
356 gcm_mult( ctx, ctx->buf, ctx->buf );
357
358 ctx->add_len += use_len;
359 add_len -= use_len;
360 p += use_len;
361 }
362
363 ctx->add_len += add_len;
364
365 while( add_len >= 16 )
366 {
367 for( i = 0; i < 16; i++ )
368 ctx->buf[i] ^= p[i];
369
370 gcm_mult( ctx, ctx->buf, ctx->buf );
371
372 add_len -= 16;
373 p += 16;
374 }
375
376 if( add_len > 0 )
377 {
378 for( i = 0; i < add_len; i++ )
379 ctx->buf[i] ^= p[i];
380 }
381
382 return( 0 );
383 }
384
385 /* Increment the counter. */
gcm_incr(unsigned char y[16])386 static void gcm_incr( unsigned char y[16] )
387 {
388 size_t i;
389 for( i = 16; i > 12; i-- )
390 if( ++y[i - 1] != 0 )
391 break;
392 }
393
394 /* Calculate and apply the encryption mask. Process use_len bytes of data,
395 * 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)396 static int gcm_mask( mbedtls_gcm_context *ctx,
397 unsigned char ectr[16],
398 size_t offset, size_t use_len,
399 const unsigned char *input,
400 unsigned char *output )
401 {
402 size_t i;
403 size_t olen = 0;
404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
405
406 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
407 &olen ) ) != 0 )
408 {
409 mbedtls_platform_zeroize( ectr, 16 );
410 return( ret );
411 }
412
413 for( i = 0; i < use_len; i++ )
414 {
415 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
416 ctx->buf[offset + i] ^= input[i];
417 output[i] = ectr[offset + i] ^ input[i];
418 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
419 ctx->buf[offset + i] ^= output[i];
420 }
421 return( 0 );
422 }
423
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)424 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
425 const unsigned char *input, size_t input_length,
426 unsigned char *output, size_t output_size,
427 size_t *output_length )
428 {
429 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
430 const unsigned char *p = input;
431 unsigned char *out_p = output;
432 size_t offset;
433 unsigned char ectr[16];
434
435 if( output_size < input_length )
436 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
437 GCM_VALIDATE_RET( output_length != NULL );
438 *output_length = input_length;
439
440 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
441 * on a potentially null pointer.
442 * Returning early also means that the last partial block of AD remains
443 * untouched for mbedtls_gcm_finish */
444 if( input_length == 0 )
445 return( 0 );
446
447 GCM_VALIDATE_RET( ctx != NULL );
448 GCM_VALIDATE_RET( input != NULL );
449 GCM_VALIDATE_RET( output != NULL );
450
451 if( output > input && (size_t) ( output - input ) < input_length )
452 return( MBEDTLS_ERR_GCM_BAD_INPUT );
453
454 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
455 * Also check for possible overflow */
456 if( ctx->len + input_length < ctx->len ||
457 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
458 {
459 return( MBEDTLS_ERR_GCM_BAD_INPUT );
460 }
461
462 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
463 {
464 gcm_mult( ctx, ctx->buf, ctx->buf );
465 }
466
467 offset = ctx->len % 16;
468 if( offset != 0 )
469 {
470 size_t use_len = 16 - offset;
471 if( use_len > input_length )
472 use_len = input_length;
473
474 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
475 return( ret );
476
477 if( offset + use_len == 16 )
478 gcm_mult( ctx, ctx->buf, ctx->buf );
479
480 ctx->len += use_len;
481 input_length -= use_len;
482 p += use_len;
483 out_p += use_len;
484 }
485
486 ctx->len += input_length;
487
488 while( input_length >= 16 )
489 {
490 gcm_incr( ctx->y );
491 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
492 return( ret );
493
494 gcm_mult( ctx, ctx->buf, ctx->buf );
495
496 input_length -= 16;
497 p += 16;
498 out_p += 16;
499 }
500
501 if( input_length > 0 )
502 {
503 gcm_incr( ctx->y );
504 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
505 return( ret );
506 }
507
508 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
509 return( 0 );
510 }
511
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)512 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
513 unsigned char *output, size_t output_size,
514 size_t *output_length,
515 unsigned char *tag, size_t tag_len )
516 {
517 unsigned char work_buf[16];
518 size_t i;
519 uint64_t orig_len;
520 uint64_t orig_add_len;
521
522 GCM_VALIDATE_RET( ctx != NULL );
523 GCM_VALIDATE_RET( tag != NULL );
524
525 /* We never pass any output in finish(). The output parameter exists only
526 * for the sake of alternative implementations. */
527 (void) output;
528 (void) output_size;
529 *output_length = 0;
530
531 orig_len = ctx->len * 8;
532 orig_add_len = ctx->add_len * 8;
533
534 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
535 {
536 gcm_mult( ctx, ctx->buf, ctx->buf );
537 }
538
539 if( tag_len > 16 || tag_len < 4 )
540 return( MBEDTLS_ERR_GCM_BAD_INPUT );
541
542 if( ctx->len % 16 != 0 )
543 gcm_mult( ctx, ctx->buf, ctx->buf );
544
545 memcpy( tag, ctx->base_ectr, tag_len );
546
547 if( orig_len || orig_add_len )
548 {
549 memset( work_buf, 0x00, 16 );
550
551 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
552 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
553 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
554 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
555
556 for( i = 0; i < 16; i++ )
557 ctx->buf[i] ^= work_buf[i];
558
559 gcm_mult( ctx, ctx->buf, ctx->buf );
560
561 for( i = 0; i < tag_len; i++ )
562 tag[i] ^= ctx->buf[i];
563 }
564
565 return( 0 );
566 }
567
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)568 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
569 int mode,
570 size_t length,
571 const unsigned char *iv,
572 size_t iv_len,
573 const unsigned char *add,
574 size_t add_len,
575 const unsigned char *input,
576 unsigned char *output,
577 size_t tag_len,
578 unsigned char *tag )
579 {
580 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
581 size_t olen;
582
583 GCM_VALIDATE_RET( ctx != NULL );
584 GCM_VALIDATE_RET( iv != NULL );
585 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
586 GCM_VALIDATE_RET( length == 0 || input != NULL );
587 GCM_VALIDATE_RET( length == 0 || output != NULL );
588 GCM_VALIDATE_RET( tag != NULL );
589
590 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
591 return( ret );
592
593 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
594 return( ret );
595
596 if( ( ret = mbedtls_gcm_update( ctx, input, length,
597 output, length, &olen ) ) != 0 )
598 return( ret );
599
600 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
601 return( ret );
602
603 return( 0 );
604 }
605
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)606 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
607 size_t length,
608 const unsigned char *iv,
609 size_t iv_len,
610 const unsigned char *add,
611 size_t add_len,
612 const unsigned char *tag,
613 size_t tag_len,
614 const unsigned char *input,
615 unsigned char *output )
616 {
617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
618 unsigned char check_tag[16];
619 size_t i;
620 int diff;
621
622 GCM_VALIDATE_RET( ctx != NULL );
623 GCM_VALIDATE_RET( iv != NULL );
624 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
625 GCM_VALIDATE_RET( tag != NULL );
626 GCM_VALIDATE_RET( length == 0 || input != NULL );
627 GCM_VALIDATE_RET( length == 0 || output != NULL );
628
629 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
630 iv, iv_len, add, add_len,
631 input, output, tag_len, check_tag ) ) != 0 )
632 {
633 return( ret );
634 }
635
636 /* Check tag in "constant-time" */
637 for( diff = 0, i = 0; i < tag_len; i++ )
638 diff |= tag[i] ^ check_tag[i];
639
640 if( diff != 0 )
641 {
642 mbedtls_platform_zeroize( output, length );
643 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
644 }
645
646 return( 0 );
647 }
648
mbedtls_gcm_free(mbedtls_gcm_context * ctx)649 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
650 {
651 if( ctx == NULL )
652 return;
653 mbedtls_cipher_free( &ctx->cipher_ctx );
654 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
655 }
656
657 #endif /* !MBEDTLS_GCM_ALT */
658
659 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
660 /*
661 * AES-GCM test vectors from:
662 *
663 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
664 */
665 #define MAX_TESTS 6
666
667 static const int key_index_test_data[MAX_TESTS] =
668 { 0, 0, 1, 1, 1, 1 };
669
670 static const unsigned char key_test_data[MAX_TESTS][32] =
671 {
672 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
676 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
677 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
678 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
679 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
680 };
681
682 static const size_t iv_len_test_data[MAX_TESTS] =
683 { 12, 12, 12, 12, 8, 60 };
684
685 static const int iv_index_test_data[MAX_TESTS] =
686 { 0, 0, 1, 1, 1, 2 };
687
688 static const unsigned char iv_test_data[MAX_TESTS][64] =
689 {
690 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00 },
692 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
693 0xde, 0xca, 0xf8, 0x88 },
694 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
695 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
696 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
697 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
698 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
699 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
700 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
701 0xa6, 0x37, 0xb3, 0x9b },
702 };
703
704 static const size_t add_len_test_data[MAX_TESTS] =
705 { 0, 0, 0, 20, 20, 20 };
706
707 static const int add_index_test_data[MAX_TESTS] =
708 { 0, 0, 0, 1, 1, 1 };
709
710 static const unsigned char additional_test_data[MAX_TESTS][64] =
711 {
712 { 0x00 },
713 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
714 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
715 0xab, 0xad, 0xda, 0xd2 },
716 };
717
718 static const size_t pt_len_test_data[MAX_TESTS] =
719 { 0, 16, 64, 60, 60, 60 };
720
721 static const int pt_index_test_data[MAX_TESTS] =
722 { 0, 0, 1, 1, 1, 1 };
723
724 static const unsigned char pt_test_data[MAX_TESTS][64] =
725 {
726 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
728 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
729 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
730 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
731 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
732 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
733 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
734 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
735 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
736 };
737
738 static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
739 {
740 { 0x00 },
741 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
742 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
743 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
744 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
745 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
746 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
747 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
748 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
749 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
750 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
751 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
752 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
753 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
754 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
755 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
756 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
757 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
758 0x3d, 0x58, 0xe0, 0x91 },
759 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
760 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
761 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
762 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
763 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
764 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
765 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
766 0xc2, 0x3f, 0x45, 0x98 },
767 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
768 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
769 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
770 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
771 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
772 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
773 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
774 0x4c, 0x34, 0xae, 0xe5 },
775 { 0x00 },
776 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
777 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
778 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
779 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
780 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
781 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
782 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
783 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
784 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
785 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
786 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
787 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
788 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
789 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
790 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
791 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
792 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
793 0xcc, 0xda, 0x27, 0x10 },
794 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
795 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
796 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
797 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
798 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
799 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
800 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
801 0xa0, 0xf0, 0x62, 0xf7 },
802 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
803 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
804 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
805 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
806 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
807 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
808 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
809 0xe9, 0xb7, 0x37, 0x3b },
810 { 0x00 },
811 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
812 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
813 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
814 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
815 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
816 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
817 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
818 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
819 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
820 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
821 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
822 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
823 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
824 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
825 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
826 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
827 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
828 0xbc, 0xc9, 0xf6, 0x62 },
829 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
830 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
831 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
832 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
833 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
834 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
835 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
836 0xf4, 0x7c, 0x9b, 0x1f },
837 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
838 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
839 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
840 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
841 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
842 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
843 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
844 0x44, 0xae, 0x7e, 0x3f },
845 };
846
847 static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
848 {
849 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
850 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
851 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
852 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
853 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
854 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
855 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
856 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
857 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
858 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
859 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
860 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
861 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
862 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
863 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
864 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
865 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
866 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
867 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
868 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
869 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
870 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
871 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
872 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
873 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
874 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
875 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
876 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
877 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
878 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
879 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
880 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
881 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
882 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
883 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
884 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
885 };
886
mbedtls_gcm_self_test(int verbose)887 int mbedtls_gcm_self_test( int verbose )
888 {
889 mbedtls_gcm_context ctx;
890 unsigned char buf[64];
891 unsigned char tag_buf[16];
892 int i, j, ret;
893 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
894 size_t olen;
895
896 for( j = 0; j < 3; j++ )
897 {
898 int key_len = 128 + 64 * j;
899
900 for( i = 0; i < MAX_TESTS; i++ )
901 {
902 mbedtls_gcm_init( &ctx );
903
904 if( verbose != 0 )
905 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
906 key_len, i, "enc" );
907
908 ret = mbedtls_gcm_setkey( &ctx, cipher,
909 key_test_data[key_index_test_data[i]],
910 key_len );
911 /*
912 * AES-192 is an optional feature that may be unavailable when
913 * there is an alternative underlying implementation i.e. when
914 * MBEDTLS_AES_ALT is defined.
915 */
916 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
917 {
918 mbedtls_printf( "skipped\n" );
919 break;
920 }
921 else if( ret != 0 )
922 {
923 goto exit;
924 }
925
926 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
927 pt_len_test_data[i],
928 iv_test_data[iv_index_test_data[i]],
929 iv_len_test_data[i],
930 additional_test_data[add_index_test_data[i]],
931 add_len_test_data[i],
932 pt_test_data[pt_index_test_data[i]],
933 buf, 16, tag_buf );
934 #if defined(MBEDTLS_GCM_ALT)
935 /* Allow alternative implementations to only support 12-byte nonces. */
936 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
937 iv_len_test_data[i] != 12 )
938 {
939 mbedtls_printf( "skipped\n" );
940 break;
941 }
942 #endif /* defined(MBEDTLS_GCM_ALT) */
943 if( ret != 0 )
944 goto exit;
945
946 if ( memcmp( buf, ct_test_data[j * 6 + i],
947 pt_len_test_data[i] ) != 0 ||
948 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
949 {
950 ret = 1;
951 goto exit;
952 }
953
954 mbedtls_gcm_free( &ctx );
955
956 if( verbose != 0 )
957 mbedtls_printf( "passed\n" );
958
959 mbedtls_gcm_init( &ctx );
960
961 if( verbose != 0 )
962 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
963 key_len, i, "dec" );
964
965 ret = mbedtls_gcm_setkey( &ctx, cipher,
966 key_test_data[key_index_test_data[i]],
967 key_len );
968 if( ret != 0 )
969 goto exit;
970
971 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
972 pt_len_test_data[i],
973 iv_test_data[iv_index_test_data[i]],
974 iv_len_test_data[i],
975 additional_test_data[add_index_test_data[i]],
976 add_len_test_data[i],
977 ct_test_data[j * 6 + i], buf, 16, tag_buf );
978
979 if( ret != 0 )
980 goto exit;
981
982 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
983 pt_len_test_data[i] ) != 0 ||
984 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
985 {
986 ret = 1;
987 goto exit;
988 }
989
990 mbedtls_gcm_free( &ctx );
991
992 if( verbose != 0 )
993 mbedtls_printf( "passed\n" );
994
995 mbedtls_gcm_init( &ctx );
996
997 if( verbose != 0 )
998 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
999 key_len, i, "enc" );
1000
1001 ret = mbedtls_gcm_setkey( &ctx, cipher,
1002 key_test_data[key_index_test_data[i]],
1003 key_len );
1004 if( ret != 0 )
1005 goto exit;
1006
1007 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
1008 iv_test_data[iv_index_test_data[i]],
1009 iv_len_test_data[i] );
1010 if( ret != 0 )
1011 goto exit;
1012
1013 ret = mbedtls_gcm_update_ad( &ctx,
1014 additional_test_data[add_index_test_data[i]],
1015 add_len_test_data[i] );
1016 if( ret != 0 )
1017 goto exit;
1018
1019 if( pt_len_test_data[i] > 32 )
1020 {
1021 size_t rest_len = pt_len_test_data[i] - 32;
1022 ret = mbedtls_gcm_update( &ctx,
1023 pt_test_data[pt_index_test_data[i]],
1024 32,
1025 buf, sizeof( buf ), &olen );
1026 if( ret != 0 )
1027 goto exit;
1028 if( olen != 32 )
1029 goto exit;
1030
1031 ret = mbedtls_gcm_update( &ctx,
1032 pt_test_data[pt_index_test_data[i]] + 32,
1033 rest_len,
1034 buf + 32, sizeof( buf ) - 32, &olen );
1035 if( ret != 0 )
1036 goto exit;
1037 if( olen != rest_len )
1038 goto exit;
1039 }
1040 else
1041 {
1042 ret = mbedtls_gcm_update( &ctx,
1043 pt_test_data[pt_index_test_data[i]],
1044 pt_len_test_data[i],
1045 buf, sizeof( buf ), &olen );
1046 if( ret != 0 )
1047 goto exit;
1048 if( olen != pt_len_test_data[i] )
1049 goto exit;
1050 }
1051
1052 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
1053 if( ret != 0 )
1054 goto exit;
1055
1056 if( memcmp( buf, ct_test_data[j * 6 + i],
1057 pt_len_test_data[i] ) != 0 ||
1058 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
1059 {
1060 ret = 1;
1061 goto exit;
1062 }
1063
1064 mbedtls_gcm_free( &ctx );
1065
1066 if( verbose != 0 )
1067 mbedtls_printf( "passed\n" );
1068
1069 mbedtls_gcm_init( &ctx );
1070
1071 if( verbose != 0 )
1072 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
1073 key_len, i, "dec" );
1074
1075 ret = mbedtls_gcm_setkey( &ctx, cipher,
1076 key_test_data[key_index_test_data[i]],
1077 key_len );
1078 if( ret != 0 )
1079 goto exit;
1080
1081 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
1082 iv_test_data[iv_index_test_data[i]],
1083 iv_len_test_data[i] );
1084 if( ret != 0 )
1085 goto exit;
1086 ret = mbedtls_gcm_update_ad( &ctx,
1087 additional_test_data[add_index_test_data[i]],
1088 add_len_test_data[i] );
1089 if( ret != 0 )
1090 goto exit;
1091
1092 if( pt_len_test_data[i] > 32 )
1093 {
1094 size_t rest_len = pt_len_test_data[i] - 32;
1095 ret = mbedtls_gcm_update( &ctx,
1096 ct_test_data[j * 6 + i], 32,
1097 buf, sizeof( buf ), &olen );
1098 if( ret != 0 )
1099 goto exit;
1100 if( olen != 32 )
1101 goto exit;
1102
1103 ret = mbedtls_gcm_update( &ctx,
1104 ct_test_data[j * 6 + i] + 32,
1105 rest_len,
1106 buf + 32, sizeof( buf ) - 32, &olen );
1107 if( ret != 0 )
1108 goto exit;
1109 if( olen != rest_len )
1110 goto exit;
1111 }
1112 else
1113 {
1114 ret = mbedtls_gcm_update( &ctx,
1115 ct_test_data[j * 6 + i],
1116 pt_len_test_data[i],
1117 buf, sizeof( buf ), &olen );
1118 if( ret != 0 )
1119 goto exit;
1120 if( olen != pt_len_test_data[i] )
1121 goto exit;
1122 }
1123
1124 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
1125 if( ret != 0 )
1126 goto exit;
1127
1128 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1129 pt_len_test_data[i] ) != 0 ||
1130 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
1131 {
1132 ret = 1;
1133 goto exit;
1134 }
1135
1136 mbedtls_gcm_free( &ctx );
1137
1138 if( verbose != 0 )
1139 mbedtls_printf( "passed\n" );
1140 }
1141 }
1142
1143 if( verbose != 0 )
1144 mbedtls_printf( "\n" );
1145
1146 ret = 0;
1147
1148 exit:
1149 if( ret != 0 )
1150 {
1151 if( verbose != 0 )
1152 mbedtls_printf( "failed\n" );
1153 mbedtls_gcm_free( &ctx );
1154 }
1155
1156 return( ret );
1157 }
1158
1159 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1160
1161 #endif /* MBEDTLS_GCM_C */
1162