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