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