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