Coverage Report

Created: 2025-03-01 06:26

/src/mbedtls/library/gcm.c
Line
Count
Source (jump to first uncovered line)
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
0
#define MBEDTLS_GCM_ACC_LARGETABLE  1
47
0
#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
0
{
55
0
    memset(ctx, 0, sizeof(mbedtls_gcm_context));
56
0
}
57
58
static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
59
0
{
60
0
#if defined(MBEDTLS_GCM_LARGE_TABLE)
61
0
    ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
62
#else
63
    ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
64
#endif
65
66
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
67
    /* With CLMUL support, we need only h, not the rest of the table */
68
0
    if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
69
0
        ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
70
0
    }
71
0
#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
0
}
79
80
static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
81
0
{
82
0
    uint8_t *u8Dst = (uint8_t *) dst;
83
0
    uint8_t *u8Src = (uint8_t *) src;
84
85
0
    MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
86
0
    u8Dst[8] |= (u8Src[7] & 0x01) << 7;
87
0
    MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
88
0
    u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
89
0
}
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
0
{
101
0
    int ret, i, j;
102
0
    uint64_t u64h[2] = { 0 };
103
0
    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
0
    size_t olen = 0;
109
0
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
110
0
#endif
111
0
    if (ret != 0) {
112
0
        return ret;
113
0
    }
114
115
0
    gcm_set_acceleration(ctx);
116
117
    /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
118
0
    ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
119
0
    ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
120
121
0
    switch (ctx->acceleration) {
122
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
123
0
        case MBEDTLS_GCM_ACC_AESNI:
124
0
            return 0;
125
0
#endif
126
127
#if defined(MBEDTLS_AESCE_HAVE_CODE)
128
        case MBEDTLS_GCM_ACC_AESCE:
129
            return 0;
130
#endif
131
132
0
        default:
133
            /* 0 corresponds to 0 in GF(2^128) */
134
0
            ctx->H[0][0] = 0;
135
0
            ctx->H[0][1] = 0;
136
137
0
            for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
138
0
                gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
139
0
            }
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
0
            for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
150
0
                for (j = 1; j < i; j++) {
151
0
                    mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
152
0
                                        (unsigned char *) ctx->H[i],
153
0
                                        (unsigned char *) ctx->H[j],
154
0
                                        16);
155
0
                }
156
0
            }
157
0
    }
158
159
0
    return 0;
160
0
}
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
0
{
167
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
169
0
    if (keybits != 128 && keybits != 192 && keybits != 256) {
170
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
171
0
    }
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
0
    const mbedtls_cipher_info_t *cipher_info;
185
186
0
    cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
187
0
                                                  MBEDTLS_MODE_ECB);
188
0
    if (cipher_info == NULL) {
189
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
190
0
    }
191
192
0
    if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
193
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
194
0
    }
195
196
0
    mbedtls_cipher_free(&ctx->cipher_ctx);
197
198
0
    if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
199
0
        return ret;
200
0
    }
201
202
0
    if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
203
0
                                     MBEDTLS_ENCRYPT)) != 0) {
204
0
        return ret;
205
0
    }
206
0
#endif
207
208
0
    if ((ret = gcm_gen_table(ctx)) != 0) {
209
0
        return ret;
210
0
    }
211
212
0
    return 0;
213
0
}
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
0
{
253
0
    int i;
254
0
    uint64_t u64z[2];
255
0
    uint16_t *u16z = (uint16_t *) u64z;
256
0
    uint8_t *u8z = (uint8_t *) u64z;
257
0
    uint8_t rem;
258
259
0
    u64z[0] = 0;
260
0
    u64z[1] = 0;
261
262
0
    if (MBEDTLS_IS_BIG_ENDIAN) {
263
0
        for (i = 15; i > 0; i--) {
264
0
            mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
265
0
            rem = u8z[15];
266
267
0
            u64z[1] >>= 8;
268
0
            u8z[8] = u8z[7];
269
0
            u64z[0] >>= 8;
270
271
0
            u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
272
0
        }
273
0
    } else {
274
0
        for (i = 15; i > 0; i--) {
275
0
            mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
276
0
            rem = u8z[15];
277
278
0
            u64z[1] <<= 8;
279
0
            u8z[8] = u8z[7];
280
0
            u64z[0] <<= 8;
281
282
0
            u16z[0] ^= last8[rem];
283
0
        }
284
0
    }
285
286
0
    mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
287
0
}
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
0
{
350
0
    switch (ctx->acceleration) {
351
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
352
0
        case MBEDTLS_GCM_ACC_AESNI:
353
0
            mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
354
0
            break;
355
0
#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
0
#if defined(MBEDTLS_GCM_LARGE_TABLE)
364
0
        case MBEDTLS_GCM_ACC_LARGETABLE:
365
0
            gcm_mult_largetable(output, x, ctx->H);
366
0
            break;
367
#else
368
        case MBEDTLS_GCM_ACC_SMALLTABLE:
369
            gcm_mult_smalltable(output, x, ctx->H);
370
            break;
371
#endif
372
0
    }
373
374
0
    return;
375
0
}
376
377
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
378
                       int mode,
379
                       const unsigned char *iv, size_t iv_len)
380
0
{
381
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
382
0
    unsigned char work_buf[16];
383
0
    const unsigned char *p;
384
0
    size_t use_len;
385
0
    uint64_t iv_bits;
386
0
#if !defined(MBEDTLS_BLOCK_CIPHER_C)
387
0
    size_t olen = 0;
388
0
#endif
389
390
    /* IV is limited to 2^64 bits, so 2^61 bytes */
391
    /* IV is not allowed to be zero length */
392
0
    if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
393
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
394
0
    }
395
396
0
    memset(ctx->y, 0x00, sizeof(ctx->y));
397
0
    memset(ctx->buf, 0x00, sizeof(ctx->buf));
398
399
0
    ctx->mode = mode;
400
0
    ctx->len = 0;
401
0
    ctx->add_len = 0;
402
403
0
    if (iv_len == 12) {
404
0
        memcpy(ctx->y, iv, iv_len);
405
0
        ctx->y[15] = 1;
406
0
    } else {
407
0
        memset(work_buf, 0x00, 16);
408
0
        iv_bits = (uint64_t) iv_len * 8;
409
0
        MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
410
411
0
        p = iv;
412
0
        while (iv_len > 0) {
413
0
            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
0
            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
0
            gcm_mult(ctx, ctx->y, ctx->y);
427
428
0
            iv_len -= use_len;
429
0
            p += use_len;
430
0
        }
431
432
0
        mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
433
434
0
        gcm_mult(ctx, ctx->y, ctx->y);
435
0
    }
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
0
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
442
0
#endif
443
0
    if (ret != 0) {
444
0
        return ret;
445
0
    }
446
447
0
    return 0;
448
0
}
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
0
{
470
0
    const unsigned char *p;
471
0
    size_t use_len, offset;
472
0
    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
0
    new_add_len = ctx->add_len + (uint64_t) add_len;
482
0
    if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
483
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
484
0
    }
485
486
0
    offset = ctx->add_len % 16;
487
0
    p = add;
488
489
0
    if (offset != 0) {
490
0
        use_len = 16 - offset;
491
0
        if (use_len > add_len) {
492
0
            use_len = add_len;
493
0
        }
494
495
0
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
496
497
0
        if (offset + use_len == 16) {
498
0
            gcm_mult(ctx, ctx->buf, ctx->buf);
499
0
        }
500
501
0
        ctx->add_len += use_len;
502
0
        add_len -= use_len;
503
0
        p += use_len;
504
0
    }
505
506
0
    ctx->add_len += add_len;
507
508
0
    while (add_len >= 16) {
509
0
        mbedtls_xor(ctx->buf, ctx->buf, p, 16);
510
511
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
512
513
0
        add_len -= 16;
514
0
        p += 16;
515
0
    }
516
517
0
    if (add_len > 0) {
518
0
        mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
519
0
    }
520
521
0
    return 0;
522
0
}
523
524
/* Increment the counter. */
525
static void gcm_incr(unsigned char y[16])
526
0
{
527
0
    uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
528
0
    x++;
529
0
    MBEDTLS_PUT_UINT32_BE(x, y, 12);
530
0
}
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
0
{
540
0
    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
0
    size_t olen = 0;
546
0
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
547
0
#endif
548
0
    if (ret != 0) {
549
0
        mbedtls_platform_zeroize(ectr, 16);
550
0
        return ret;
551
0
    }
552
553
0
    if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
554
0
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
555
0
    }
556
0
    mbedtls_xor(output, ectr + offset, input, use_len);
557
0
    if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
558
0
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
559
0
    }
560
561
0
    return 0;
562
0
}
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
0
{
569
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
570
0
    const unsigned char *p = input;
571
0
    unsigned char *out_p = output;
572
0
    size_t offset;
573
0
    unsigned char ectr[16] = { 0 };
574
575
0
    if (output_size < input_length) {
576
0
        return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
577
0
    }
578
0
    *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
0
    if (input_length == 0) {
585
0
        return 0;
586
0
    }
587
588
0
    if (output > input && (size_t) (output - input) < input_length) {
589
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
590
0
    }
591
592
    /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
593
     * Also check for possible overflow */
594
0
    if (ctx->len + input_length < ctx->len ||
595
0
        (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
596
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
597
0
    }
598
599
0
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
600
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
601
0
    }
602
603
0
    offset = ctx->len % 16;
604
0
    if (offset != 0) {
605
0
        size_t use_len = 16 - offset;
606
0
        if (use_len > input_length) {
607
0
            use_len = input_length;
608
0
        }
609
610
0
        if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
611
0
            return ret;
612
0
        }
613
614
0
        if (offset + use_len == 16) {
615
0
            gcm_mult(ctx, ctx->buf, ctx->buf);
616
0
        }
617
618
0
        ctx->len += use_len;
619
0
        input_length -= use_len;
620
0
        p += use_len;
621
0
        out_p += use_len;
622
0
    }
623
624
0
    ctx->len += input_length;
625
626
0
    while (input_length >= 16) {
627
0
        gcm_incr(ctx->y);
628
0
        if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
629
0
            return ret;
630
0
        }
631
632
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
633
634
0
        input_length -= 16;
635
0
        p += 16;
636
0
        out_p += 16;
637
0
    }
638
639
0
    if (input_length > 0) {
640
0
        gcm_incr(ctx->y);
641
0
        if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
642
0
            return ret;
643
0
        }
644
0
    }
645
646
0
    mbedtls_platform_zeroize(ectr, sizeof(ectr));
647
0
    return 0;
648
0
}
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
0
{
655
0
    unsigned char work_buf[16];
656
0
    uint64_t orig_len;
657
0
    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
0
    (void) output;
662
0
    (void) output_size;
663
0
    *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
0
    orig_len = ctx->len * 8;
669
0
    orig_add_len = ctx->add_len * 8;
670
671
0
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
672
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
673
0
    }
674
675
0
    if (tag_len > 16 || tag_len < 4) {
676
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
677
0
    }
678
679
0
    if (ctx->len % 16 != 0) {
680
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
681
0
    }
682
683
0
    memcpy(tag, ctx->base_ectr, tag_len);
684
685
0
    if (orig_len || orig_add_len) {
686
0
        memset(work_buf, 0x00, 16);
687
688
0
        MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
689
0
        MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
690
0
        MBEDTLS_PUT_UINT32_BE((orig_len     >> 32), work_buf, 8);
691
0
        MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
692
693
0
        mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
694
695
0
        gcm_mult(ctx, ctx->buf, ctx->buf);
696
697
0
        mbedtls_xor(tag, tag, ctx->buf, tag_len);
698
0
    }
699
700
0
    return 0;
701
0
}
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
0
{
715
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
716
0
    size_t olen;
717
718
0
    if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
719
0
        return ret;
720
0
    }
721
722
0
    if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
723
0
        return ret;
724
0
    }
725
726
0
    if ((ret = mbedtls_gcm_update(ctx, input, length,
727
0
                                  output, length, &olen)) != 0) {
728
0
        return ret;
729
0
    }
730
731
0
    if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
732
0
        return ret;
733
0
    }
734
735
0
    return 0;
736
0
}
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
0
{
749
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
750
0
    unsigned char check_tag[16];
751
0
    int diff;
752
753
0
    if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
754
0
                                         iv, iv_len, add, add_len,
755
0
                                         input, output, tag_len, check_tag)) != 0) {
756
0
        return ret;
757
0
    }
758
759
    /* Check tag in "constant-time" */
760
0
    diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
761
762
0
    if (diff != 0) {
763
0
        mbedtls_platform_zeroize(output, length);
764
0
        return MBEDTLS_ERR_GCM_AUTH_FAILED;
765
0
    }
766
767
0
    return 0;
768
0
}
769
770
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
771
0
{
772
0
    if (ctx == NULL) {
773
0
        return;
774
0
    }
775
#if defined(MBEDTLS_BLOCK_CIPHER_C)
776
    mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
777
#else
778
0
    mbedtls_cipher_free(&ctx->cipher_ctx);
779
0
#endif
780
0
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
781
0
}
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
0
#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
0
{
1019
0
    mbedtls_gcm_context ctx;
1020
0
    unsigned char buf[64];
1021
0
    unsigned char tag_buf[16];
1022
0
    int i, j, ret;
1023
0
    mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
1024
0
    size_t olen;
1025
1026
0
    if (verbose != 0) {
1027
#if defined(MBEDTLS_GCM_ALT)
1028
        mbedtls_printf("  GCM note: alternative implementation.\n");
1029
#else /* MBEDTLS_GCM_ALT */
1030
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
1031
0
        if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
1032
0
            mbedtls_printf("  GCM note: using AESNI.\n");
1033
0
        } else
1034
0
#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
0
        mbedtls_printf("  GCM note: built-in implementation.\n");
1043
0
#endif /* MBEDTLS_GCM_ALT */
1044
0
    }
1045
1046
0
    static const int loop_limit =
1047
0
        (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
1048
1049
0
    for (j = 0; j < loop_limit; j++) {
1050
0
        int key_len = 128 + 64 * j;
1051
1052
0
        for (i = 0; i < MAX_TESTS; i++) {
1053
0
            if (verbose != 0) {
1054
0
                mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
1055
0
                               key_len, i, "enc");
1056
0
            }
1057
1058
0
            mbedtls_gcm_init(&ctx);
1059
1060
0
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1061
0
                                     key_test_data[key_index_test_data[i]],
1062
0
                                     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
0
            if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
1069
0
                mbedtls_printf("skipped\n");
1070
0
                break;
1071
0
            } else if (ret != 0) {
1072
0
                goto exit;
1073
0
            }
1074
1075
0
            ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
1076
0
                                            pt_len_test_data[i],
1077
0
                                            iv_test_data[iv_index_test_data[i]],
1078
0
                                            iv_len_test_data[i],
1079
0
                                            additional_test_data[add_index_test_data[i]],
1080
0
                                            add_len_test_data[i],
1081
0
                                            pt_test_data[pt_index_test_data[i]],
1082
0
                                            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
0
            if (ret != 0) {
1092
0
                goto exit;
1093
0
            }
1094
1095
0
            if (memcmp(buf, ct_test_data[j * 6 + i],
1096
0
                       pt_len_test_data[i]) != 0 ||
1097
0
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1098
0
                ret = 1;
1099
0
                goto exit;
1100
0
            }
1101
1102
0
            mbedtls_gcm_free(&ctx);
1103
1104
0
            if (verbose != 0) {
1105
0
                mbedtls_printf("passed\n");
1106
0
            }
1107
1108
0
            mbedtls_gcm_init(&ctx);
1109
1110
0
            if (verbose != 0) {
1111
0
                mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
1112
0
                               key_len, i, "dec");
1113
0
            }
1114
1115
0
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1116
0
                                     key_test_data[key_index_test_data[i]],
1117
0
                                     key_len);
1118
0
            if (ret != 0) {
1119
0
                goto exit;
1120
0
            }
1121
1122
0
            ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1123
0
                                            pt_len_test_data[i],
1124
0
                                            iv_test_data[iv_index_test_data[i]],
1125
0
                                            iv_len_test_data[i],
1126
0
                                            additional_test_data[add_index_test_data[i]],
1127
0
                                            add_len_test_data[i],
1128
0
                                            ct_test_data[j * 6 + i], buf, 16, tag_buf);
1129
1130
0
            if (ret != 0) {
1131
0
                goto exit;
1132
0
            }
1133
1134
0
            if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1135
0
                       pt_len_test_data[i]) != 0 ||
1136
0
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1137
0
                ret = 1;
1138
0
                goto exit;
1139
0
            }
1140
1141
0
            mbedtls_gcm_free(&ctx);
1142
1143
0
            if (verbose != 0) {
1144
0
                mbedtls_printf("passed\n");
1145
0
            }
1146
1147
0
            mbedtls_gcm_init(&ctx);
1148
1149
0
            if (verbose != 0) {
1150
0
                mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
1151
0
                               key_len, i, "enc");
1152
0
            }
1153
1154
0
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1155
0
                                     key_test_data[key_index_test_data[i]],
1156
0
                                     key_len);
1157
0
            if (ret != 0) {
1158
0
                goto exit;
1159
0
            }
1160
1161
0
            ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1162
0
                                     iv_test_data[iv_index_test_data[i]],
1163
0
                                     iv_len_test_data[i]);
1164
0
            if (ret != 0) {
1165
0
                goto exit;
1166
0
            }
1167
1168
0
            ret = mbedtls_gcm_update_ad(&ctx,
1169
0
                                        additional_test_data[add_index_test_data[i]],
1170
0
                                        add_len_test_data[i]);
1171
0
            if (ret != 0) {
1172
0
                goto exit;
1173
0
            }
1174
1175
0
            if (pt_len_test_data[i] > 32) {
1176
0
                size_t rest_len = pt_len_test_data[i] - 32;
1177
0
                ret = mbedtls_gcm_update(&ctx,
1178
0
                                         pt_test_data[pt_index_test_data[i]],
1179
0
                                         32,
1180
0
                                         buf, sizeof(buf), &olen);
1181
0
                if (ret != 0) {
1182
0
                    goto exit;
1183
0
                }
1184
0
                if (olen != 32) {
1185
0
                    goto exit;
1186
0
                }
1187
1188
0
                ret = mbedtls_gcm_update(&ctx,
1189
0
                                         pt_test_data[pt_index_test_data[i]] + 32,
1190
0
                                         rest_len,
1191
0
                                         buf + 32, sizeof(buf) - 32, &olen);
1192
0
                if (ret != 0) {
1193
0
                    goto exit;
1194
0
                }
1195
0
                if (olen != rest_len) {
1196
0
                    goto exit;
1197
0
                }
1198
0
            } else {
1199
0
                ret = mbedtls_gcm_update(&ctx,
1200
0
                                         pt_test_data[pt_index_test_data[i]],
1201
0
                                         pt_len_test_data[i],
1202
0
                                         buf, sizeof(buf), &olen);
1203
0
                if (ret != 0) {
1204
0
                    goto exit;
1205
0
                }
1206
0
                if (olen != pt_len_test_data[i]) {
1207
0
                    goto exit;
1208
0
                }
1209
0
            }
1210
1211
0
            ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1212
0
            if (ret != 0) {
1213
0
                goto exit;
1214
0
            }
1215
1216
0
            if (memcmp(buf, ct_test_data[j * 6 + i],
1217
0
                       pt_len_test_data[i]) != 0 ||
1218
0
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1219
0
                ret = 1;
1220
0
                goto exit;
1221
0
            }
1222
1223
0
            mbedtls_gcm_free(&ctx);
1224
1225
0
            if (verbose != 0) {
1226
0
                mbedtls_printf("passed\n");
1227
0
            }
1228
1229
0
            mbedtls_gcm_init(&ctx);
1230
1231
0
            if (verbose != 0) {
1232
0
                mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
1233
0
                               key_len, i, "dec");
1234
0
            }
1235
1236
0
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1237
0
                                     key_test_data[key_index_test_data[i]],
1238
0
                                     key_len);
1239
0
            if (ret != 0) {
1240
0
                goto exit;
1241
0
            }
1242
1243
0
            ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1244
0
                                     iv_test_data[iv_index_test_data[i]],
1245
0
                                     iv_len_test_data[i]);
1246
0
            if (ret != 0) {
1247
0
                goto exit;
1248
0
            }
1249
0
            ret = mbedtls_gcm_update_ad(&ctx,
1250
0
                                        additional_test_data[add_index_test_data[i]],
1251
0
                                        add_len_test_data[i]);
1252
0
            if (ret != 0) {
1253
0
                goto exit;
1254
0
            }
1255
1256
0
            if (pt_len_test_data[i] > 32) {
1257
0
                size_t rest_len = pt_len_test_data[i] - 32;
1258
0
                ret = mbedtls_gcm_update(&ctx,
1259
0
                                         ct_test_data[j * 6 + i], 32,
1260
0
                                         buf, sizeof(buf), &olen);
1261
0
                if (ret != 0) {
1262
0
                    goto exit;
1263
0
                }
1264
0
                if (olen != 32) {
1265
0
                    goto exit;
1266
0
                }
1267
1268
0
                ret = mbedtls_gcm_update(&ctx,
1269
0
                                         ct_test_data[j * 6 + i] + 32,
1270
0
                                         rest_len,
1271
0
                                         buf + 32, sizeof(buf) - 32, &olen);
1272
0
                if (ret != 0) {
1273
0
                    goto exit;
1274
0
                }
1275
0
                if (olen != rest_len) {
1276
0
                    goto exit;
1277
0
                }
1278
0
            } else {
1279
0
                ret = mbedtls_gcm_update(&ctx,
1280
0
                                         ct_test_data[j * 6 + i],
1281
0
                                         pt_len_test_data[i],
1282
0
                                         buf, sizeof(buf), &olen);
1283
0
                if (ret != 0) {
1284
0
                    goto exit;
1285
0
                }
1286
0
                if (olen != pt_len_test_data[i]) {
1287
0
                    goto exit;
1288
0
                }
1289
0
            }
1290
1291
0
            ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1292
0
            if (ret != 0) {
1293
0
                goto exit;
1294
0
            }
1295
1296
0
            if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1297
0
                       pt_len_test_data[i]) != 0 ||
1298
0
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1299
0
                ret = 1;
1300
0
                goto exit;
1301
0
            }
1302
1303
0
            mbedtls_gcm_free(&ctx);
1304
1305
0
            if (verbose != 0) {
1306
0
                mbedtls_printf("passed\n");
1307
0
            }
1308
0
        }
1309
0
    }
1310
1311
0
    if (verbose != 0) {
1312
0
        mbedtls_printf("\n");
1313
0
    }
1314
1315
0
    ret = 0;
1316
1317
0
exit:
1318
0
    if (ret != 0) {
1319
0
        if (verbose != 0) {
1320
0
            mbedtls_printf("failed\n");
1321
0
        }
1322
0
        mbedtls_gcm_free(&ctx);
1323
0
    }
1324
1325
0
    return ret;
1326
0
}
1327
1328
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1329
1330
#endif /* MBEDTLS_GCM_C */