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