quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

gcm.c (44572B)


      1 /*
      2  *  NIST SP800-38D compliant GCM implementation
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  */
      7 
      8 /*
      9  * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
     10  *
     11  * See also:
     12  * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
     13  *
     14  * We use the algorithm described as Shoup's method with 4-bit tables in
     15  * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
     16  */
     17 
     18 #include "common.h"
     19 
     20 #if defined(MBEDTLS_GCM_C)
     21 
     22 #include "mbedtls/gcm.h"
     23 #include "mbedtls/platform.h"
     24 #include "mbedtls/platform_util.h"
     25 #include "mbedtls/error.h"
     26 #include "mbedtls/constant_time.h"
     27 
     28 #if defined(MBEDTLS_BLOCK_CIPHER_C)
     29 #include "block_cipher_internal.h"
     30 #endif
     31 
     32 #include <string.h>
     33 
     34 #if defined(MBEDTLS_AESNI_C)
     35 #include "aesni.h"
     36 #endif
     37 
     38 #if defined(MBEDTLS_AESCE_C)
     39 #include "aesce.h"
     40 #endif
     41 
     42 #if !defined(MBEDTLS_GCM_ALT)
     43 
     44 /* Used to select the acceleration mechanism */
     45 #define MBEDTLS_GCM_ACC_SMALLTABLE  0
     46 #define MBEDTLS_GCM_ACC_LARGETABLE  1
     47 #define MBEDTLS_GCM_ACC_AESNI       2
     48 #define MBEDTLS_GCM_ACC_AESCE       3
     49 
     50 /*
     51  * Initialize a context
     52  */
     53 void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
     54 {
     55     memset(ctx, 0, sizeof(mbedtls_gcm_context));
     56 }
     57 
     58 static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
     59 {
     60 #if defined(MBEDTLS_GCM_LARGE_TABLE)
     61     ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
     62 #else
     63     ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
     64 #endif
     65 
     66 #if defined(MBEDTLS_AESNI_HAVE_CODE)
     67     /* With CLMUL support, we need only h, not the rest of the table */
     68     if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
     69         ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
     70     }
     71 #endif
     72 
     73 #if defined(MBEDTLS_AESCE_HAVE_CODE)
     74     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
     75         ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
     76     }
     77 #endif
     78 }
     79 
     80 static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
     81 {
     82     uint8_t *u8Dst = (uint8_t *) dst;
     83     uint8_t *u8Src = (uint8_t *) src;
     84 
     85     MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
     86     u8Dst[8] |= (u8Src[7] & 0x01) << 7;
     87     MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
     88     u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
     89 }
     90 
     91 /*
     92  * Precompute small multiples of H, that is set
     93  *      HH[i] || HL[i] = H times i,
     94  * where i is seen as a field element as in [MGV], ie high-order bits
     95  * correspond to low powers of P. The result is stored in the same way, that
     96  * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
     97  * corresponds to P^127.
     98  */
     99 static int gcm_gen_table(mbedtls_gcm_context *ctx)
    100 {
    101     int ret, i, j;
    102     uint64_t u64h[2] = { 0 };
    103     uint8_t *h = (uint8_t *) u64h;
    104 
    105 #if defined(MBEDTLS_BLOCK_CIPHER_C)
    106     ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
    107 #else
    108     size_t olen = 0;
    109     ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
    110 #endif
    111     if (ret != 0) {
    112         return ret;
    113     }
    114 
    115     gcm_set_acceleration(ctx);
    116 
    117     /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
    118     ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
    119     ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
    120 
    121     switch (ctx->acceleration) {
    122 #if defined(MBEDTLS_AESNI_HAVE_CODE)
    123         case MBEDTLS_GCM_ACC_AESNI:
    124             return 0;
    125 #endif
    126 
    127 #if defined(MBEDTLS_AESCE_HAVE_CODE)
    128         case MBEDTLS_GCM_ACC_AESCE:
    129             return 0;
    130 #endif
    131 
    132         default:
    133             /* 0 corresponds to 0 in GF(2^128) */
    134             ctx->H[0][0] = 0;
    135             ctx->H[0][1] = 0;
    136 
    137             for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
    138                 gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
    139             }
    140 
    141 #if !defined(MBEDTLS_GCM_LARGE_TABLE)
    142             /* pack elements of H as 64-bits ints, big-endian */
    143             for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
    144                 MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
    145                 MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
    146             }
    147 #endif
    148 
    149             for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
    150                 for (j = 1; j < i; j++) {
    151                     mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
    152                                         (unsigned char *) ctx->H[i],
    153                                         (unsigned char *) ctx->H[j],
    154                                         16);
    155                 }
    156             }
    157     }
    158 
    159     return 0;
    160 }
    161 
    162 int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
    163                        mbedtls_cipher_id_t cipher,
    164                        const unsigned char *key,
    165                        unsigned int keybits)
    166 {
    167     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    168 
    169     if (keybits != 128 && keybits != 192 && keybits != 256) {
    170         return MBEDTLS_ERR_GCM_BAD_INPUT;
    171     }
    172 
    173 #if defined(MBEDTLS_BLOCK_CIPHER_C)
    174     mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
    175 
    176     if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
    177         return ret;
    178     }
    179 
    180     if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
    181         return ret;
    182     }
    183 #else
    184     const mbedtls_cipher_info_t *cipher_info;
    185 
    186     cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
    187                                                   MBEDTLS_MODE_ECB);
    188     if (cipher_info == NULL) {
    189         return MBEDTLS_ERR_GCM_BAD_INPUT;
    190     }
    191 
    192     if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
    193         return MBEDTLS_ERR_GCM_BAD_INPUT;
    194     }
    195 
    196     mbedtls_cipher_free(&ctx->cipher_ctx);
    197 
    198     if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
    199         return ret;
    200     }
    201 
    202     if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
    203                                      MBEDTLS_ENCRYPT)) != 0) {
    204         return ret;
    205     }
    206 #endif
    207 
    208     if ((ret = gcm_gen_table(ctx)) != 0) {
    209         return ret;
    210     }
    211 
    212     return 0;
    213 }
    214 
    215 #if defined(MBEDTLS_GCM_LARGE_TABLE)
    216 static const uint16_t last8[256] = {
    217     0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05,
    218     0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b,
    219     0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19,
    220     0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17,
    221     0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d,
    222     0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33,
    223     0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21,
    224     0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f,
    225     0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75,
    226     0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b,
    227     0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69,
    228     0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67,
    229     0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d,
    230     0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43,
    231     0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51,
    232     0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f,
    233     0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4,
    234     0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea,
    235     0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8,
    236     0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6,
    237     0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc,
    238     0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2,
    239     0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0,
    240     0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece,
    241     0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94,
    242     0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a,
    243     0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88,
    244     0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86,
    245     0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac,
    246     0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2,
    247     0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0,
    248     0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe
    249 };
    250 
    251 static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2])
    252 {
    253     int i;
    254     uint64_t u64z[2];
    255     uint16_t *u16z = (uint16_t *) u64z;
    256     uint8_t *u8z = (uint8_t *) u64z;
    257     uint8_t rem;
    258 
    259     u64z[0] = 0;
    260     u64z[1] = 0;
    261 
    262     if (MBEDTLS_IS_BIG_ENDIAN) {
    263         for (i = 15; i > 0; i--) {
    264             mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
    265             rem = u8z[15];
    266 
    267             u64z[1] >>= 8;
    268             u8z[8] = u8z[7];
    269             u64z[0] >>= 8;
    270 
    271             u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
    272         }
    273     } else {
    274         for (i = 15; i > 0; i--) {
    275             mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
    276             rem = u8z[15];
    277 
    278             u64z[1] <<= 8;
    279             u8z[8] = u8z[7];
    280             u64z[0] <<= 8;
    281 
    282             u16z[0] ^= last8[rem];
    283         }
    284     }
    285 
    286     mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
    287 }
    288 #else
    289 /*
    290  * Shoup's method for multiplication use this table with
    291  *      last4[x] = x times P^128
    292  * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
    293  */
    294 static const uint16_t last4[16] =
    295 {
    296     0x0000, 0x1c20, 0x3840, 0x2460,
    297     0x7080, 0x6ca0, 0x48c0, 0x54e0,
    298     0xe100, 0xfd20, 0xd940, 0xc560,
    299     0x9180, 0x8da0, 0xa9c0, 0xb5e0
    300 };
    301 
    302 static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2])
    303 {
    304     int i = 0;
    305     unsigned char lo, hi, rem;
    306     uint64_t u64z[2];
    307     const uint64_t *pu64z = NULL;
    308     uint8_t *u8z = (uint8_t *) u64z;
    309 
    310     lo = x[15] & 0xf;
    311     hi = (x[15] >> 4) & 0xf;
    312 
    313     pu64z = H[lo];
    314 
    315     rem = (unsigned char) pu64z[1] & 0xf;
    316     u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
    317     u64z[0] = (pu64z[0] >> 4);
    318     u64z[0] ^= (uint64_t) last4[rem] << 48;
    319     mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
    320 
    321     for (i = 14; i >= 0; i--) {
    322         lo = x[i] & 0xf;
    323         hi = (x[i] >> 4) & 0xf;
    324 
    325         rem = (unsigned char) u64z[1] & 0xf;
    326         u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
    327         u64z[0] = (u64z[0] >> 4);
    328         u64z[0] ^= (uint64_t) last4[rem] << 48;
    329         mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
    330 
    331         rem = (unsigned char) u64z[1] & 0xf;
    332         u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
    333         u64z[0] = (u64z[0] >> 4);
    334         u64z[0] ^= (uint64_t) last4[rem] << 48;
    335         mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
    336     }
    337 
    338     MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
    339     MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
    340 }
    341 #endif
    342 
    343 /*
    344  * Sets output to x times H using the precomputed tables.
    345  * x and output are seen as elements of GF(2^128) as in [MGV].
    346  */
    347 static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
    348                      unsigned char output[16])
    349 {
    350     switch (ctx->acceleration) {
    351 #if defined(MBEDTLS_AESNI_HAVE_CODE)
    352         case MBEDTLS_GCM_ACC_AESNI:
    353             mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
    354             break;
    355 #endif
    356 
    357 #if defined(MBEDTLS_AESCE_HAVE_CODE)
    358         case MBEDTLS_GCM_ACC_AESCE:
    359             mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
    360             break;
    361 #endif
    362 
    363 #if defined(MBEDTLS_GCM_LARGE_TABLE)
    364         case MBEDTLS_GCM_ACC_LARGETABLE:
    365             gcm_mult_largetable(output, x, ctx->H);
    366             break;
    367 #else
    368         case MBEDTLS_GCM_ACC_SMALLTABLE:
    369             gcm_mult_smalltable(output, x, ctx->H);
    370             break;
    371 #endif
    372     }
    373 
    374     return;
    375 }
    376 
    377 int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
    378                        int mode,
    379                        const unsigned char *iv, size_t iv_len)
    380 {
    381     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    382     unsigned char work_buf[16];
    383     const unsigned char *p;
    384     size_t use_len;
    385     uint64_t iv_bits;
    386 #if !defined(MBEDTLS_BLOCK_CIPHER_C)
    387     size_t olen = 0;
    388 #endif
    389 
    390     /* IV is limited to 2^64 bits, so 2^61 bytes */
    391     /* IV is not allowed to be zero length */
    392     if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
    393         return MBEDTLS_ERR_GCM_BAD_INPUT;
    394     }
    395 
    396     memset(ctx->y, 0x00, sizeof(ctx->y));
    397     memset(ctx->buf, 0x00, sizeof(ctx->buf));
    398 
    399     ctx->mode = mode;
    400     ctx->len = 0;
    401     ctx->add_len = 0;
    402 
    403     if (iv_len == 12) {
    404         memcpy(ctx->y, iv, iv_len);
    405         ctx->y[15] = 1;
    406     } else {
    407         memset(work_buf, 0x00, 16);
    408         iv_bits = (uint64_t) iv_len * 8;
    409         MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
    410 
    411         p = iv;
    412         while (iv_len > 0) {
    413             use_len = (iv_len < 16) ? iv_len : 16;
    414 
    415 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
    416 #pragma GCC diagnostic push
    417 #pragma GCC diagnostic warning "-Wstringop-overflow=0"
    418 #endif
    419 
    420             mbedtls_xor(ctx->y, ctx->y, p, use_len);
    421 
    422 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
    423 #pragma GCC diagnostic pop
    424 #endif
    425 
    426             gcm_mult(ctx, ctx->y, ctx->y);
    427 
    428             iv_len -= use_len;
    429             p += use_len;
    430         }
    431 
    432         mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
    433 
    434         gcm_mult(ctx, ctx->y, ctx->y);
    435     }
    436 
    437 
    438 #if defined(MBEDTLS_BLOCK_CIPHER_C)
    439     ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
    440 #else
    441     ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
    442 #endif
    443     if (ret != 0) {
    444         return ret;
    445     }
    446 
    447     return 0;
    448 }
    449 
    450 /**
    451  * mbedtls_gcm_context::buf contains the partial state of the computation of
    452  * the authentication tag.
    453  * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
    454  * different stages of the computation:
    455  *     * len == 0 && add_len == 0:      initial state
    456  *     * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
    457  *                                      a partial block of AD that has been
    458  *                                      xored in but not yet multiplied in.
    459  *     * len == 0 && add_len % 16 == 0: the authentication tag is correct if
    460  *                                      the data ends now.
    461  *     * len % 16 != 0:                 the first `len % 16` bytes have
    462  *                                      a partial block of ciphertext that has
    463  *                                      been xored in but not yet multiplied in.
    464  *     * len > 0 && len % 16 == 0:      the authentication tag is correct if
    465  *                                      the data ends now.
    466  */
    467 int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
    468                           const unsigned char *add, size_t add_len)
    469 {
    470     const unsigned char *p;
    471     size_t use_len, offset;
    472     uint64_t new_add_len;
    473 
    474     /* AD is limited to 2^64 bits, ie 2^61 bytes
    475      * Also check for possible overflow */
    476 #if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
    477     if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
    478         return MBEDTLS_ERR_GCM_BAD_INPUT;
    479     }
    480 #endif
    481     new_add_len = ctx->add_len + (uint64_t) add_len;
    482     if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
    483         return MBEDTLS_ERR_GCM_BAD_INPUT;
    484     }
    485 
    486     offset = ctx->add_len % 16;
    487     p = add;
    488 
    489     if (offset != 0) {
    490         use_len = 16 - offset;
    491         if (use_len > add_len) {
    492             use_len = add_len;
    493         }
    494 
    495         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
    496 
    497         if (offset + use_len == 16) {
    498             gcm_mult(ctx, ctx->buf, ctx->buf);
    499         }
    500 
    501         ctx->add_len += use_len;
    502         add_len -= use_len;
    503         p += use_len;
    504     }
    505 
    506     ctx->add_len += add_len;
    507 
    508     while (add_len >= 16) {
    509         mbedtls_xor(ctx->buf, ctx->buf, p, 16);
    510 
    511         gcm_mult(ctx, ctx->buf, ctx->buf);
    512 
    513         add_len -= 16;
    514         p += 16;
    515     }
    516 
    517     if (add_len > 0) {
    518         mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
    519     }
    520 
    521     return 0;
    522 }
    523 
    524 /* Increment the counter. */
    525 static void gcm_incr(unsigned char y[16])
    526 {
    527     uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
    528     x++;
    529     MBEDTLS_PUT_UINT32_BE(x, y, 12);
    530 }
    531 
    532 /* Calculate and apply the encryption mask. Process use_len bytes of data,
    533  * starting at position offset in the mask block. */
    534 static int gcm_mask(mbedtls_gcm_context *ctx,
    535                     unsigned char ectr[16],
    536                     size_t offset, size_t use_len,
    537                     const unsigned char *input,
    538                     unsigned char *output)
    539 {
    540     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    541 
    542 #if defined(MBEDTLS_BLOCK_CIPHER_C)
    543     ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
    544 #else
    545     size_t olen = 0;
    546     ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
    547 #endif
    548     if (ret != 0) {
    549         mbedtls_platform_zeroize(ectr, 16);
    550         return ret;
    551     }
    552 
    553     if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
    554         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
    555     }
    556     mbedtls_xor(output, ectr + offset, input, use_len);
    557     if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
    558         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
    559     }
    560 
    561     return 0;
    562 }
    563 
    564 int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
    565                        const unsigned char *input, size_t input_length,
    566                        unsigned char *output, size_t output_size,
    567                        size_t *output_length)
    568 {
    569     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    570     const unsigned char *p = input;
    571     unsigned char *out_p = output;
    572     size_t offset;
    573     unsigned char ectr[16] = { 0 };
    574 
    575     if (output_size < input_length) {
    576         return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
    577     }
    578     *output_length = input_length;
    579 
    580     /* Exit early if input_length==0 so that we don't do any pointer arithmetic
    581      * on a potentially null pointer.
    582      * Returning early also means that the last partial block of AD remains
    583      * untouched for mbedtls_gcm_finish */
    584     if (input_length == 0) {
    585         return 0;
    586     }
    587 
    588     if (output > input && (size_t) (output - input) < input_length) {
    589         return MBEDTLS_ERR_GCM_BAD_INPUT;
    590     }
    591 
    592     /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
    593      * Also check for possible overflow */
    594     if (ctx->len + input_length < ctx->len ||
    595         (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
    596         return MBEDTLS_ERR_GCM_BAD_INPUT;
    597     }
    598 
    599     if (ctx->len == 0 && ctx->add_len % 16 != 0) {
    600         gcm_mult(ctx, ctx->buf, ctx->buf);
    601     }
    602 
    603     offset = ctx->len % 16;
    604     if (offset != 0) {
    605         size_t use_len = 16 - offset;
    606         if (use_len > input_length) {
    607             use_len = input_length;
    608         }
    609 
    610         if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
    611             return ret;
    612         }
    613 
    614         if (offset + use_len == 16) {
    615             gcm_mult(ctx, ctx->buf, ctx->buf);
    616         }
    617 
    618         ctx->len += use_len;
    619         input_length -= use_len;
    620         p += use_len;
    621         out_p += use_len;
    622     }
    623 
    624     ctx->len += input_length;
    625 
    626     while (input_length >= 16) {
    627         gcm_incr(ctx->y);
    628         if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
    629             return ret;
    630         }
    631 
    632         gcm_mult(ctx, ctx->buf, ctx->buf);
    633 
    634         input_length -= 16;
    635         p += 16;
    636         out_p += 16;
    637     }
    638 
    639     if (input_length > 0) {
    640         gcm_incr(ctx->y);
    641         if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
    642             return ret;
    643         }
    644     }
    645 
    646     mbedtls_platform_zeroize(ectr, sizeof(ectr));
    647     return 0;
    648 }
    649 
    650 int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
    651                        unsigned char *output, size_t output_size,
    652                        size_t *output_length,
    653                        unsigned char *tag, size_t tag_len)
    654 {
    655     unsigned char work_buf[16];
    656     uint64_t orig_len;
    657     uint64_t orig_add_len;
    658 
    659     /* We never pass any output in finish(). The output parameter exists only
    660      * for the sake of alternative implementations. */
    661     (void) output;
    662     (void) output_size;
    663     *output_length = 0;
    664 
    665     /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
    666      * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
    667      * the two multiplications would overflow. */
    668     orig_len = ctx->len * 8;
    669     orig_add_len = ctx->add_len * 8;
    670 
    671     if (ctx->len == 0 && ctx->add_len % 16 != 0) {
    672         gcm_mult(ctx, ctx->buf, ctx->buf);
    673     }
    674 
    675     if (tag_len > 16 || tag_len < 4) {
    676         return MBEDTLS_ERR_GCM_BAD_INPUT;
    677     }
    678 
    679     if (ctx->len % 16 != 0) {
    680         gcm_mult(ctx, ctx->buf, ctx->buf);
    681     }
    682 
    683     memcpy(tag, ctx->base_ectr, tag_len);
    684 
    685     if (orig_len || orig_add_len) {
    686         memset(work_buf, 0x00, 16);
    687 
    688         MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
    689         MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
    690         MBEDTLS_PUT_UINT32_BE((orig_len     >> 32), work_buf, 8);
    691         MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
    692 
    693         mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
    694 
    695         gcm_mult(ctx, ctx->buf, ctx->buf);
    696 
    697         mbedtls_xor(tag, tag, ctx->buf, tag_len);
    698     }
    699 
    700     return 0;
    701 }
    702 
    703 int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
    704                               int mode,
    705                               size_t length,
    706                               const unsigned char *iv,
    707                               size_t iv_len,
    708                               const unsigned char *add,
    709                               size_t add_len,
    710                               const unsigned char *input,
    711                               unsigned char *output,
    712                               size_t tag_len,
    713                               unsigned char *tag)
    714 {
    715     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    716     size_t olen;
    717 
    718     if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
    719         return ret;
    720     }
    721 
    722     if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
    723         return ret;
    724     }
    725 
    726     if ((ret = mbedtls_gcm_update(ctx, input, length,
    727                                   output, length, &olen)) != 0) {
    728         return ret;
    729     }
    730 
    731     if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
    732         return ret;
    733     }
    734 
    735     return 0;
    736 }
    737 
    738 int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
    739                              size_t length,
    740                              const unsigned char *iv,
    741                              size_t iv_len,
    742                              const unsigned char *add,
    743                              size_t add_len,
    744                              const unsigned char *tag,
    745                              size_t tag_len,
    746                              const unsigned char *input,
    747                              unsigned char *output)
    748 {
    749     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    750     unsigned char check_tag[16];
    751     int diff;
    752 
    753     if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
    754                                          iv, iv_len, add, add_len,
    755                                          input, output, tag_len, check_tag)) != 0) {
    756         return ret;
    757     }
    758 
    759     /* Check tag in "constant-time" */
    760     diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
    761 
    762     if (diff != 0) {
    763         mbedtls_platform_zeroize(output, length);
    764         return MBEDTLS_ERR_GCM_AUTH_FAILED;
    765     }
    766 
    767     return 0;
    768 }
    769 
    770 void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
    771 {
    772     if (ctx == NULL) {
    773         return;
    774     }
    775 #if defined(MBEDTLS_BLOCK_CIPHER_C)
    776     mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
    777 #else
    778     mbedtls_cipher_free(&ctx->cipher_ctx);
    779 #endif
    780     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
    781 }
    782 
    783 #endif /* !MBEDTLS_GCM_ALT */
    784 
    785 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
    786 /*
    787  * AES-GCM test vectors from:
    788  *
    789  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
    790  */
    791 #define MAX_TESTS   6
    792 
    793 static const int key_index_test_data[MAX_TESTS] =
    794 { 0, 0, 1, 1, 1, 1 };
    795 
    796 static const unsigned char key_test_data[][32] =
    797 {
    798     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    799       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    800       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    801       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    802     { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    803       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
    804       0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
    805       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
    806 };
    807 
    808 static const size_t iv_len_test_data[MAX_TESTS] =
    809 { 12, 12, 12, 12, 8, 60 };
    810 
    811 static const int iv_index_test_data[MAX_TESTS] =
    812 { 0, 0, 1, 1, 1, 2 };
    813 
    814 static const unsigned char iv_test_data[][64] =
    815 {
    816     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    817       0x00, 0x00, 0x00, 0x00 },
    818     { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
    819       0xde, 0xca, 0xf8, 0x88 },
    820     { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
    821       0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
    822       0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
    823       0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
    824       0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
    825       0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
    826       0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
    827       0xa6, 0x37, 0xb3, 0x9b },
    828 };
    829 
    830 static const size_t add_len_test_data[MAX_TESTS] =
    831 { 0, 0, 0, 20, 20, 20 };
    832 
    833 static const int add_index_test_data[MAX_TESTS] =
    834 { 0, 0, 0, 1, 1, 1 };
    835 
    836 static const unsigned char additional_test_data[][64] =
    837 {
    838     { 0x00 },
    839     { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
    840       0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
    841       0xab, 0xad, 0xda, 0xd2 },
    842 };
    843 
    844 static const size_t pt_len_test_data[MAX_TESTS] =
    845 { 0, 16, 64, 60, 60, 60 };
    846 
    847 static const int pt_index_test_data[MAX_TESTS] =
    848 { 0, 0, 1, 1, 1, 1 };
    849 
    850 static const unsigned char pt_test_data[][64] =
    851 {
    852     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    853       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    854     { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
    855       0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
    856       0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
    857       0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
    858       0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
    859       0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
    860       0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
    861       0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
    862 };
    863 
    864 static const unsigned char ct_test_data[][64] =
    865 {
    866     { 0x00 },
    867     { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
    868       0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
    869     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
    870       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
    871       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
    872       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
    873       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
    874       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
    875       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
    876       0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
    877     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
    878       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
    879       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
    880       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
    881       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
    882       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
    883       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
    884       0x3d, 0x58, 0xe0, 0x91 },
    885     { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
    886       0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
    887       0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
    888       0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
    889       0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
    890       0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
    891       0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
    892       0xc2, 0x3f, 0x45, 0x98 },
    893     { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
    894       0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
    895       0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
    896       0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
    897       0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
    898       0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
    899       0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
    900       0x4c, 0x34, 0xae, 0xe5 },
    901 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
    902     { 0x00 },
    903     { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
    904       0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
    905     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
    906       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
    907       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
    908       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
    909       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
    910       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
    911       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
    912       0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
    913     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
    914       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
    915       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
    916       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
    917       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
    918       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
    919       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
    920       0xcc, 0xda, 0x27, 0x10 },
    921     { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
    922       0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
    923       0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
    924       0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
    925       0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
    926       0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
    927       0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
    928       0xa0, 0xf0, 0x62, 0xf7 },
    929     { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
    930       0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
    931       0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
    932       0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
    933       0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
    934       0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
    935       0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
    936       0xe9, 0xb7, 0x37, 0x3b },
    937     { 0x00 },
    938     { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
    939       0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
    940     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
    941       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
    942       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
    943       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
    944       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
    945       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
    946       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
    947       0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
    948     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
    949       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
    950       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
    951       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
    952       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
    953       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
    954       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
    955       0xbc, 0xc9, 0xf6, 0x62 },
    956     { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
    957       0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
    958       0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
    959       0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
    960       0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
    961       0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
    962       0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
    963       0xf4, 0x7c, 0x9b, 0x1f },
    964     { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
    965       0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
    966       0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
    967       0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
    968       0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
    969       0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
    970       0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
    971       0x44, 0xae, 0x7e, 0x3f },
    972 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
    973 };
    974 
    975 static const unsigned char tag_test_data[][16] =
    976 {
    977     { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
    978       0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
    979     { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
    980       0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
    981     { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
    982       0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
    983     { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
    984       0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
    985     { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
    986       0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
    987     { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
    988       0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
    989 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
    990     { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
    991       0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
    992     { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
    993       0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
    994     { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
    995       0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
    996     { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
    997       0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
    998     { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
    999       0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
   1000     { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
   1001       0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
   1002     { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
   1003       0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
   1004     { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
   1005       0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
   1006     { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
   1007       0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
   1008     { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
   1009       0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
   1010     { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
   1011       0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
   1012     { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
   1013       0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
   1014 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
   1015 };
   1016 
   1017 int mbedtls_gcm_self_test(int verbose)
   1018 {
   1019     mbedtls_gcm_context ctx;
   1020     unsigned char buf[64];
   1021     unsigned char tag_buf[16];
   1022     int i, j, ret;
   1023     mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
   1024     size_t olen;
   1025 
   1026     if (verbose != 0) {
   1027 #if defined(MBEDTLS_GCM_ALT)
   1028         mbedtls_printf("  GCM note: alternative implementation.\n");
   1029 #else /* MBEDTLS_GCM_ALT */
   1030 #if defined(MBEDTLS_AESNI_HAVE_CODE)
   1031         if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
   1032             mbedtls_printf("  GCM note: using AESNI.\n");
   1033         } else
   1034 #endif
   1035 
   1036 #if defined(MBEDTLS_AESCE_HAVE_CODE)
   1037         if (MBEDTLS_AESCE_HAS_SUPPORT()) {
   1038             mbedtls_printf("  GCM note: using AESCE.\n");
   1039         } else
   1040 #endif
   1041 
   1042         mbedtls_printf("  GCM note: built-in implementation.\n");
   1043 #endif /* MBEDTLS_GCM_ALT */
   1044     }
   1045 
   1046     static const int loop_limit =
   1047         (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
   1048 
   1049     for (j = 0; j < loop_limit; j++) {
   1050         int key_len = 128 + 64 * j;
   1051 
   1052         for (i = 0; i < MAX_TESTS; i++) {
   1053             if (verbose != 0) {
   1054                 mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
   1055                                key_len, i, "enc");
   1056             }
   1057 
   1058             mbedtls_gcm_init(&ctx);
   1059 
   1060             ret = mbedtls_gcm_setkey(&ctx, cipher,
   1061                                      key_test_data[key_index_test_data[i]],
   1062                                      key_len);
   1063             /*
   1064              * AES-192 is an optional feature that may be unavailable when
   1065              * there is an alternative underlying implementation i.e. when
   1066              * MBEDTLS_AES_ALT is defined.
   1067              */
   1068             if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
   1069                 mbedtls_printf("skipped\n");
   1070                 break;
   1071             } else if (ret != 0) {
   1072                 goto exit;
   1073             }
   1074 
   1075             ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
   1076                                             pt_len_test_data[i],
   1077                                             iv_test_data[iv_index_test_data[i]],
   1078                                             iv_len_test_data[i],
   1079                                             additional_test_data[add_index_test_data[i]],
   1080                                             add_len_test_data[i],
   1081                                             pt_test_data[pt_index_test_data[i]],
   1082                                             buf, 16, tag_buf);
   1083 #if defined(MBEDTLS_GCM_ALT)
   1084             /* Allow alternative implementations to only support 12-byte nonces. */
   1085             if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
   1086                 iv_len_test_data[i] != 12) {
   1087                 mbedtls_printf("skipped\n");
   1088                 break;
   1089             }
   1090 #endif /* defined(MBEDTLS_GCM_ALT) */
   1091             if (ret != 0) {
   1092                 goto exit;
   1093             }
   1094 
   1095             if (memcmp(buf, ct_test_data[j * 6 + i],
   1096                        pt_len_test_data[i]) != 0 ||
   1097                 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
   1098                 ret = 1;
   1099                 goto exit;
   1100             }
   1101 
   1102             mbedtls_gcm_free(&ctx);
   1103 
   1104             if (verbose != 0) {
   1105                 mbedtls_printf("passed\n");
   1106             }
   1107 
   1108             mbedtls_gcm_init(&ctx);
   1109 
   1110             if (verbose != 0) {
   1111                 mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
   1112                                key_len, i, "dec");
   1113             }
   1114 
   1115             ret = mbedtls_gcm_setkey(&ctx, cipher,
   1116                                      key_test_data[key_index_test_data[i]],
   1117                                      key_len);
   1118             if (ret != 0) {
   1119                 goto exit;
   1120             }
   1121 
   1122             ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
   1123                                             pt_len_test_data[i],
   1124                                             iv_test_data[iv_index_test_data[i]],
   1125                                             iv_len_test_data[i],
   1126                                             additional_test_data[add_index_test_data[i]],
   1127                                             add_len_test_data[i],
   1128                                             ct_test_data[j * 6 + i], buf, 16, tag_buf);
   1129 
   1130             if (ret != 0) {
   1131                 goto exit;
   1132             }
   1133 
   1134             if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
   1135                        pt_len_test_data[i]) != 0 ||
   1136                 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
   1137                 ret = 1;
   1138                 goto exit;
   1139             }
   1140 
   1141             mbedtls_gcm_free(&ctx);
   1142 
   1143             if (verbose != 0) {
   1144                 mbedtls_printf("passed\n");
   1145             }
   1146 
   1147             mbedtls_gcm_init(&ctx);
   1148 
   1149             if (verbose != 0) {
   1150                 mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
   1151                                key_len, i, "enc");
   1152             }
   1153 
   1154             ret = mbedtls_gcm_setkey(&ctx, cipher,
   1155                                      key_test_data[key_index_test_data[i]],
   1156                                      key_len);
   1157             if (ret != 0) {
   1158                 goto exit;
   1159             }
   1160 
   1161             ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
   1162                                      iv_test_data[iv_index_test_data[i]],
   1163                                      iv_len_test_data[i]);
   1164             if (ret != 0) {
   1165                 goto exit;
   1166             }
   1167 
   1168             ret = mbedtls_gcm_update_ad(&ctx,
   1169                                         additional_test_data[add_index_test_data[i]],
   1170                                         add_len_test_data[i]);
   1171             if (ret != 0) {
   1172                 goto exit;
   1173             }
   1174 
   1175             if (pt_len_test_data[i] > 32) {
   1176                 size_t rest_len = pt_len_test_data[i] - 32;
   1177                 ret = mbedtls_gcm_update(&ctx,
   1178                                          pt_test_data[pt_index_test_data[i]],
   1179                                          32,
   1180                                          buf, sizeof(buf), &olen);
   1181                 if (ret != 0) {
   1182                     goto exit;
   1183                 }
   1184                 if (olen != 32) {
   1185                     goto exit;
   1186                 }
   1187 
   1188                 ret = mbedtls_gcm_update(&ctx,
   1189                                          pt_test_data[pt_index_test_data[i]] + 32,
   1190                                          rest_len,
   1191                                          buf + 32, sizeof(buf) - 32, &olen);
   1192                 if (ret != 0) {
   1193                     goto exit;
   1194                 }
   1195                 if (olen != rest_len) {
   1196                     goto exit;
   1197                 }
   1198             } else {
   1199                 ret = mbedtls_gcm_update(&ctx,
   1200                                          pt_test_data[pt_index_test_data[i]],
   1201                                          pt_len_test_data[i],
   1202                                          buf, sizeof(buf), &olen);
   1203                 if (ret != 0) {
   1204                     goto exit;
   1205                 }
   1206                 if (olen != pt_len_test_data[i]) {
   1207                     goto exit;
   1208                 }
   1209             }
   1210 
   1211             ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
   1212             if (ret != 0) {
   1213                 goto exit;
   1214             }
   1215 
   1216             if (memcmp(buf, ct_test_data[j * 6 + i],
   1217                        pt_len_test_data[i]) != 0 ||
   1218                 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
   1219                 ret = 1;
   1220                 goto exit;
   1221             }
   1222 
   1223             mbedtls_gcm_free(&ctx);
   1224 
   1225             if (verbose != 0) {
   1226                 mbedtls_printf("passed\n");
   1227             }
   1228 
   1229             mbedtls_gcm_init(&ctx);
   1230 
   1231             if (verbose != 0) {
   1232                 mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
   1233                                key_len, i, "dec");
   1234             }
   1235 
   1236             ret = mbedtls_gcm_setkey(&ctx, cipher,
   1237                                      key_test_data[key_index_test_data[i]],
   1238                                      key_len);
   1239             if (ret != 0) {
   1240                 goto exit;
   1241             }
   1242 
   1243             ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
   1244                                      iv_test_data[iv_index_test_data[i]],
   1245                                      iv_len_test_data[i]);
   1246             if (ret != 0) {
   1247                 goto exit;
   1248             }
   1249             ret = mbedtls_gcm_update_ad(&ctx,
   1250                                         additional_test_data[add_index_test_data[i]],
   1251                                         add_len_test_data[i]);
   1252             if (ret != 0) {
   1253                 goto exit;
   1254             }
   1255 
   1256             if (pt_len_test_data[i] > 32) {
   1257                 size_t rest_len = pt_len_test_data[i] - 32;
   1258                 ret = mbedtls_gcm_update(&ctx,
   1259                                          ct_test_data[j * 6 + i], 32,
   1260                                          buf, sizeof(buf), &olen);
   1261                 if (ret != 0) {
   1262                     goto exit;
   1263                 }
   1264                 if (olen != 32) {
   1265                     goto exit;
   1266                 }
   1267 
   1268                 ret = mbedtls_gcm_update(&ctx,
   1269                                          ct_test_data[j * 6 + i] + 32,
   1270                                          rest_len,
   1271                                          buf + 32, sizeof(buf) - 32, &olen);
   1272                 if (ret != 0) {
   1273                     goto exit;
   1274                 }
   1275                 if (olen != rest_len) {
   1276                     goto exit;
   1277                 }
   1278             } else {
   1279                 ret = mbedtls_gcm_update(&ctx,
   1280                                          ct_test_data[j * 6 + i],
   1281                                          pt_len_test_data[i],
   1282                                          buf, sizeof(buf), &olen);
   1283                 if (ret != 0) {
   1284                     goto exit;
   1285                 }
   1286                 if (olen != pt_len_test_data[i]) {
   1287                     goto exit;
   1288                 }
   1289             }
   1290 
   1291             ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
   1292             if (ret != 0) {
   1293                 goto exit;
   1294             }
   1295 
   1296             if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
   1297                        pt_len_test_data[i]) != 0 ||
   1298                 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
   1299                 ret = 1;
   1300                 goto exit;
   1301             }
   1302 
   1303             mbedtls_gcm_free(&ctx);
   1304 
   1305             if (verbose != 0) {
   1306                 mbedtls_printf("passed\n");
   1307             }
   1308         }
   1309     }
   1310 
   1311     if (verbose != 0) {
   1312         mbedtls_printf("\n");
   1313     }
   1314 
   1315     ret = 0;
   1316 
   1317 exit:
   1318     if (ret != 0) {
   1319         if (verbose != 0) {
   1320             mbedtls_printf("failed\n");
   1321         }
   1322         mbedtls_gcm_free(&ctx);
   1323     }
   1324 
   1325     return ret;
   1326 }
   1327 
   1328 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
   1329 
   1330 #endif /* MBEDTLS_GCM_C */