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