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