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