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