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