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