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