xref: /optee_os/lib/libmbedtls/mbedtls/library/gcm.c (revision c6672fdcd95b9a895eb5b4191f8ba3483a34a442)
1 // SPDX-License-Identifier: Apache-2.0
2 /*
3  *  NIST SP800-38D compliant GCM implementation
4  *
5  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 */
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  */
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  */
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 
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  */
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 
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     /* IV is not allowed to be zero length */
281     if( iv_len == 0 ||
282       ( (uint64_t) iv_len  ) >> 61 != 0 ||
283       ( (uint64_t) add_len ) >> 61 != 0 )
284     {
285         return( MBEDTLS_ERR_GCM_BAD_INPUT );
286     }
287 
288     memset( ctx->y, 0x00, sizeof(ctx->y) );
289     memset( ctx->buf, 0x00, sizeof(ctx->buf) );
290 
291     ctx->mode = mode;
292     ctx->len = 0;
293     ctx->add_len = 0;
294 
295     if( iv_len == 12 )
296     {
297         memcpy( ctx->y, iv, iv_len );
298         ctx->y[15] = 1;
299     }
300     else
301     {
302         memset( work_buf, 0x00, 16 );
303         PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
304 
305         p = iv;
306         while( iv_len > 0 )
307         {
308             use_len = ( iv_len < 16 ) ? iv_len : 16;
309 
310             for( i = 0; i < use_len; i++ )
311                 ctx->y[i] ^= p[i];
312 
313             gcm_mult( ctx, ctx->y, ctx->y );
314 
315             iv_len -= use_len;
316             p += use_len;
317         }
318 
319         for( i = 0; i < 16; i++ )
320             ctx->y[i] ^= work_buf[i];
321 
322         gcm_mult( ctx, ctx->y, ctx->y );
323     }
324 
325     if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
326                              &olen ) ) != 0 )
327     {
328         return( ret );
329     }
330 
331     ctx->add_len = add_len;
332     p = add;
333     while( add_len > 0 )
334     {
335         use_len = ( add_len < 16 ) ? add_len : 16;
336 
337         for( i = 0; i < use_len; i++ )
338             ctx->buf[i] ^= p[i];
339 
340         gcm_mult( ctx, ctx->buf, ctx->buf );
341 
342         add_len -= use_len;
343         p += use_len;
344     }
345 
346     return( 0 );
347 }
348 
349 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
350                 size_t length,
351                 const unsigned char *input,
352                 unsigned char *output )
353 {
354     int ret;
355     unsigned char ectr[16];
356     size_t i;
357     const unsigned char *p;
358     unsigned char *out_p = output;
359     size_t use_len, olen = 0;
360 
361     if( output > input && (size_t) ( output - input ) < length )
362         return( MBEDTLS_ERR_GCM_BAD_INPUT );
363 
364     /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
365      * Also check for possible overflow */
366     if( ctx->len + length < ctx->len ||
367         (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
368     {
369         return( MBEDTLS_ERR_GCM_BAD_INPUT );
370     }
371 
372     ctx->len += length;
373 
374     p = input;
375     while( length > 0 )
376     {
377         use_len = ( length < 16 ) ? length : 16;
378 
379         for( i = 16; i > 12; i-- )
380             if( ++ctx->y[i - 1] != 0 )
381                 break;
382 
383         if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
384                                    &olen ) ) != 0 )
385         {
386             return( ret );
387         }
388 
389         for( i = 0; i < use_len; i++ )
390         {
391             if( ctx->mode == MBEDTLS_GCM_DECRYPT )
392                 ctx->buf[i] ^= p[i];
393             out_p[i] = ectr[i] ^ p[i];
394             if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
395                 ctx->buf[i] ^= out_p[i];
396         }
397 
398         gcm_mult( ctx, ctx->buf, ctx->buf );
399 
400         length -= use_len;
401         p += use_len;
402         out_p += use_len;
403     }
404 
405     return( 0 );
406 }
407 
408 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
409                 unsigned char *tag,
410                 size_t tag_len )
411 {
412     unsigned char work_buf[16];
413     size_t i;
414     uint64_t orig_len = ctx->len * 8;
415     uint64_t orig_add_len = ctx->add_len * 8;
416 
417     if( tag_len > 16 || tag_len < 4 )
418         return( MBEDTLS_ERR_GCM_BAD_INPUT );
419 
420     memcpy( tag, ctx->base_ectr, tag_len );
421 
422     if( orig_len || orig_add_len )
423     {
424         memset( work_buf, 0x00, 16 );
425 
426         PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0  );
427         PUT_UINT32_BE( ( orig_add_len       ), work_buf, 4  );
428         PUT_UINT32_BE( ( orig_len     >> 32 ), work_buf, 8  );
429         PUT_UINT32_BE( ( orig_len           ), work_buf, 12 );
430 
431         for( i = 0; i < 16; i++ )
432             ctx->buf[i] ^= work_buf[i];
433 
434         gcm_mult( ctx, ctx->buf, ctx->buf );
435 
436         for( i = 0; i < tag_len; i++ )
437             tag[i] ^= ctx->buf[i];
438     }
439 
440     return( 0 );
441 }
442 
443 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
444                        int mode,
445                        size_t length,
446                        const unsigned char *iv,
447                        size_t iv_len,
448                        const unsigned char *add,
449                        size_t add_len,
450                        const unsigned char *input,
451                        unsigned char *output,
452                        size_t tag_len,
453                        unsigned char *tag )
454 {
455     int ret;
456 
457     if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
458         return( ret );
459 
460     if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
461         return( ret );
462 
463     if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
464         return( ret );
465 
466     return( 0 );
467 }
468 
469 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
470                       size_t length,
471                       const unsigned char *iv,
472                       size_t iv_len,
473                       const unsigned char *add,
474                       size_t add_len,
475                       const unsigned char *tag,
476                       size_t tag_len,
477                       const unsigned char *input,
478                       unsigned char *output )
479 {
480     int ret;
481     unsigned char check_tag[16];
482     size_t i;
483     int diff;
484 
485     if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
486                                    iv, iv_len, add, add_len,
487                                    input, output, tag_len, check_tag ) ) != 0 )
488     {
489         return( ret );
490     }
491 
492     /* Check tag in "constant-time" */
493     for( diff = 0, i = 0; i < tag_len; i++ )
494         diff |= tag[i] ^ check_tag[i];
495 
496     if( diff != 0 )
497     {
498         mbedtls_zeroize( output, length );
499         return( MBEDTLS_ERR_GCM_AUTH_FAILED );
500     }
501 
502     return( 0 );
503 }
504 
505 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
506 {
507     mbedtls_cipher_free( &ctx->cipher_ctx );
508     mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
509 }
510 
511 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
512 /*
513  * AES-GCM test vectors from:
514  *
515  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
516  */
517 #define MAX_TESTS   6
518 
519 static const int key_index[MAX_TESTS] =
520     { 0, 0, 1, 1, 1, 1 };
521 
522 static const unsigned char key[MAX_TESTS][32] =
523 {
524     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
528     { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
529       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
530       0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
531       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
532 };
533 
534 static const size_t iv_len[MAX_TESTS] =
535     { 12, 12, 12, 12, 8, 60 };
536 
537 static const int iv_index[MAX_TESTS] =
538     { 0, 0, 1, 1, 1, 2 };
539 
540 static const unsigned char iv[MAX_TESTS][64] =
541 {
542     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543       0x00, 0x00, 0x00, 0x00 },
544     { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
545       0xde, 0xca, 0xf8, 0x88 },
546     { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
547       0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
548       0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
549       0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
550       0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
551       0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
552       0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
553       0xa6, 0x37, 0xb3, 0x9b },
554 };
555 
556 static const size_t add_len[MAX_TESTS] =
557     { 0, 0, 0, 20, 20, 20 };
558 
559 static const int add_index[MAX_TESTS] =
560     { 0, 0, 0, 1, 1, 1 };
561 
562 static const unsigned char additional[MAX_TESTS][64] =
563 {
564     { 0x00 },
565     { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
566       0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
567       0xab, 0xad, 0xda, 0xd2 },
568 };
569 
570 static const size_t pt_len[MAX_TESTS] =
571     { 0, 16, 64, 60, 60, 60 };
572 
573 static const int pt_index[MAX_TESTS] =
574     { 0, 0, 1, 1, 1, 1 };
575 
576 static const unsigned char pt[MAX_TESTS][64] =
577 {
578     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
580     { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
581       0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
582       0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
583       0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
584       0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
585       0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
586       0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
587       0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
588 };
589 
590 static const unsigned char ct[MAX_TESTS * 3][64] =
591 {
592     { 0x00 },
593     { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
594       0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
595     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
596       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
597       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
598       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
599       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
600       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
601       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
602       0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
603     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
604       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
605       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
606       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
607       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
608       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
609       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
610       0x3d, 0x58, 0xe0, 0x91 },
611     { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
612       0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
613       0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
614       0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
615       0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
616       0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
617       0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
618       0xc2, 0x3f, 0x45, 0x98 },
619     { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
620       0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
621       0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
622       0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
623       0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
624       0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
625       0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
626       0x4c, 0x34, 0xae, 0xe5 },
627     { 0x00 },
628     { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
629       0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
630     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
631       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
632       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
633       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
634       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
635       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
636       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
637       0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
638     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
639       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
640       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
641       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
642       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
643       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
644       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
645       0xcc, 0xda, 0x27, 0x10 },
646     { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
647       0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
648       0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
649       0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
650       0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
651       0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
652       0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
653       0xa0, 0xf0, 0x62, 0xf7 },
654     { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
655       0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
656       0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
657       0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
658       0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
659       0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
660       0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
661       0xe9, 0xb7, 0x37, 0x3b },
662     { 0x00 },
663     { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
664       0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
665     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
666       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
667       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
668       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
669       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
670       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
671       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
672       0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
673     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
674       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
675       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
676       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
677       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
678       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
679       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
680       0xbc, 0xc9, 0xf6, 0x62 },
681     { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
682       0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
683       0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
684       0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
685       0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
686       0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
687       0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
688       0xf4, 0x7c, 0x9b, 0x1f },
689     { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
690       0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
691       0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
692       0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
693       0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
694       0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
695       0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
696       0x44, 0xae, 0x7e, 0x3f },
697 };
698 
699 static const unsigned char tag[MAX_TESTS * 3][16] =
700 {
701     { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
702       0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
703     { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
704       0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
705     { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
706       0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
707     { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
708       0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
709     { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
710       0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
711     { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
712       0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
713     { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
714       0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
715     { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
716       0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
717     { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
718       0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
719     { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
720       0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
721     { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
722       0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
723     { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
724       0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
725     { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
726       0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
727     { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
728       0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
729     { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
730       0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
731     { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
732       0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
733     { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
734       0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
735     { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
736       0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
737 };
738 
739 int mbedtls_gcm_self_test( int verbose )
740 {
741     mbedtls_gcm_context ctx;
742     unsigned char buf[64];
743     unsigned char tag_buf[16];
744     int i, j, ret;
745     mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
746 
747     mbedtls_gcm_init( &ctx );
748 
749     for( j = 0; j < 3; j++ )
750     {
751         int key_len = 128 + 64 * j;
752 
753         for( i = 0; i < MAX_TESTS; i++ )
754         {
755             if( verbose != 0 )
756                 mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
757                                  key_len, i, "enc" );
758 
759             mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
760 
761             ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
762                                      pt_len[i],
763                                      iv[iv_index[i]], iv_len[i],
764                                      additional[add_index[i]], add_len[i],
765                                      pt[pt_index[i]], buf, 16, tag_buf );
766 
767             if( ret != 0 ||
768                 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
769                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
770             {
771                 if( verbose != 0 )
772                     mbedtls_printf( "failed\n" );
773 
774                 return( 1 );
775             }
776 
777             mbedtls_gcm_free( &ctx );
778 
779             if( verbose != 0 )
780                 mbedtls_printf( "passed\n" );
781 
782             if( verbose != 0 )
783                 mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
784                                  key_len, i, "dec" );
785 
786             mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
787 
788             ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
789                                      pt_len[i],
790                                      iv[iv_index[i]], iv_len[i],
791                                      additional[add_index[i]], add_len[i],
792                                      ct[j * 6 + i], buf, 16, tag_buf );
793 
794             if( ret != 0 ||
795                 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
796                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
797             {
798                 if( verbose != 0 )
799                     mbedtls_printf( "failed\n" );
800 
801                 return( 1 );
802             }
803 
804             mbedtls_gcm_free( &ctx );
805 
806             if( verbose != 0 )
807                 mbedtls_printf( "passed\n" );
808 
809             if( verbose != 0 )
810                 mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
811                                  key_len, i, "enc" );
812 
813             mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
814 
815             ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
816                               iv[iv_index[i]], iv_len[i],
817                               additional[add_index[i]], add_len[i] );
818             if( ret != 0 )
819             {
820                 if( verbose != 0 )
821                     mbedtls_printf( "failed\n" );
822 
823                 return( 1 );
824             }
825 
826             if( pt_len[i] > 32 )
827             {
828                 size_t rest_len = pt_len[i] - 32;
829                 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
830                 if( ret != 0 )
831                 {
832                     if( verbose != 0 )
833                         mbedtls_printf( "failed\n" );
834 
835                     return( 1 );
836                 }
837 
838                 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
839                                   buf + 32 );
840                 if( ret != 0 )
841                 {
842                     if( verbose != 0 )
843                         mbedtls_printf( "failed\n" );
844 
845                     return( 1 );
846                 }
847             }
848             else
849             {
850                 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
851                 if( ret != 0 )
852                 {
853                     if( verbose != 0 )
854                         mbedtls_printf( "failed\n" );
855 
856                     return( 1 );
857                 }
858             }
859 
860             ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
861             if( ret != 0 ||
862                 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
863                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
864             {
865                 if( verbose != 0 )
866                     mbedtls_printf( "failed\n" );
867 
868                 return( 1 );
869             }
870 
871             mbedtls_gcm_free( &ctx );
872 
873             if( verbose != 0 )
874                 mbedtls_printf( "passed\n" );
875 
876             if( verbose != 0 )
877                 mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
878                                  key_len, i, "dec" );
879 
880             mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len );
881 
882             ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
883                               iv[iv_index[i]], iv_len[i],
884                               additional[add_index[i]], add_len[i] );
885             if( ret != 0 )
886             {
887                 if( verbose != 0 )
888                     mbedtls_printf( "failed\n" );
889 
890                 return( 1 );
891             }
892 
893             if( pt_len[i] > 32 )
894             {
895                 size_t rest_len = pt_len[i] - 32;
896                 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
897                 if( ret != 0 )
898                 {
899                     if( verbose != 0 )
900                         mbedtls_printf( "failed\n" );
901 
902                     return( 1 );
903                 }
904 
905                 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
906                                   buf + 32 );
907                 if( ret != 0 )
908                 {
909                     if( verbose != 0 )
910                         mbedtls_printf( "failed\n" );
911 
912                     return( 1 );
913                 }
914             }
915             else
916             {
917                 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
918                 if( ret != 0 )
919                 {
920                     if( verbose != 0 )
921                         mbedtls_printf( "failed\n" );
922 
923                     return( 1 );
924                 }
925             }
926 
927             ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
928             if( ret != 0 ||
929                 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
930                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
931             {
932                 if( verbose != 0 )
933                     mbedtls_printf( "failed\n" );
934 
935                 return( 1 );
936             }
937 
938             mbedtls_gcm_free( &ctx );
939 
940             if( verbose != 0 )
941                 mbedtls_printf( "passed\n" );
942 
943         }
944     }
945 
946     if( verbose != 0 )
947         mbedtls_printf( "\n" );
948 
949     return( 0 );
950 }
951 
952 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
953 
954 #endif /* MBEDTLS_GCM_C */
955