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