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