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