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