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