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