Coverage Report

Created: 2024-11-21 07:03

/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
190
#define MBEDTLS_GCM_ACC_SMALLTABLE  0
46
#define MBEDTLS_GCM_ACC_LARGETABLE  1
47
9.27k
#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
277
{
55
277
    memset(ctx, 0, sizeof(mbedtls_gcm_context));
56
277
}
57
58
static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
59
190
{
60
#if defined(MBEDTLS_GCM_LARGE_TABLE)
61
    ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
62
#else
63
190
    ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
64
190
#endif
65
66
190
#if defined(MBEDTLS_AESNI_HAVE_CODE)
67
    /* With CLMUL support, we need only h, not the rest of the table */
68
190
    if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
69
190
        ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
70
190
    }
71
190
#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
190
}
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
190
{
101
190
    int ret, i, j;
102
190
    uint64_t u64h[2] = { 0 };
103
190
    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
190
    size_t olen = 0;
109
190
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
110
190
#endif
111
190
    if (ret != 0) {
112
0
        return ret;
113
0
    }
114
115
190
    gcm_set_acceleration(ctx);
116
117
    /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
118
190
    ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
119
190
    ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
120
121
190
    switch (ctx->acceleration) {
122
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
123
190
        case MBEDTLS_GCM_ACC_AESNI:
124
190
            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
0
#if !defined(MBEDTLS_GCM_LARGE_TABLE)
142
            /* pack elements of H as 64-bits ints, big-endian */
143
0
            for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
144
0
                MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
145
0
                MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
146
0
            }
147
0
#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
190
    }
158
159
0
    return 0;
160
190
}
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
190
{
167
190
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
169
190
    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
190
    const mbedtls_cipher_info_t *cipher_info;
185
186
190
    cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
187
190
                                                  MBEDTLS_MODE_ECB);
188
190
    if (cipher_info == NULL) {
189
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
190
0
    }
191
192
190
    if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
193
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
194
0
    }
195
196
190
    mbedtls_cipher_free(&ctx->cipher_ctx);
197
198
190
    if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
199
0
        return ret;
200
0
    }
201
202
190
    if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
203
190
                                     MBEDTLS_ENCRYPT)) != 0) {
204
0
        return ret;
205
0
    }
206
190
#endif
207
208
190
    if ((ret = gcm_gen_table(ctx)) != 0) {
209
0
        return ret;
210
0
    }
211
212
190
    return 0;
213
190
}
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
0
{
304
0
    int i = 0;
305
0
    unsigned char lo, hi, rem;
306
0
    uint64_t u64z[2];
307
0
    const uint64_t *pu64z = NULL;
308
0
    uint8_t *u8z = (uint8_t *) u64z;
309
310
0
    lo = x[15] & 0xf;
311
0
    hi = (x[15] >> 4) & 0xf;
312
313
0
    pu64z = H[lo];
314
315
0
    rem = (unsigned char) pu64z[1] & 0xf;
316
0
    u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
317
0
    u64z[0] = (pu64z[0] >> 4);
318
0
    u64z[0] ^= (uint64_t) last4[rem] << 48;
319
0
    mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
320
321
0
    for (i = 14; i >= 0; i--) {
322
0
        lo = x[i] & 0xf;
323
0
        hi = (x[i] >> 4) & 0xf;
324
325
0
        rem = (unsigned char) u64z[1] & 0xf;
326
0
        u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
327
0
        u64z[0] = (u64z[0] >> 4);
328
0
        u64z[0] ^= (uint64_t) last4[rem] << 48;
329
0
        mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
330
331
0
        rem = (unsigned char) u64z[1] & 0xf;
332
0
        u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
333
0
        u64z[0] = (u64z[0] >> 4);
334
0
        u64z[0] ^= (uint64_t) last4[rem] << 48;
335
0
        mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
336
0
    }
337
338
0
    MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
339
0
    MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
340
0
}
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
8.89k
{
350
8.89k
    switch (ctx->acceleration) {
351
0
#if defined(MBEDTLS_AESNI_HAVE_CODE)
352
8.89k
        case MBEDTLS_GCM_ACC_AESNI:
353
8.89k
            mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
354
8.89k
            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
#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
0
        case MBEDTLS_GCM_ACC_SMALLTABLE:
369
0
            gcm_mult_smalltable(output, x, ctx->H);
370
0
            break;
371
8.89k
#endif
372
8.89k
    }
373
374
8.89k
    return;
375
8.89k
}
376
377
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
378
                       int mode,
379
                       const unsigned char *iv, size_t iv_len)
380
147
{
381
147
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
382
147
    unsigned char work_buf[16];
383
147
    const unsigned char *p;
384
147
    size_t use_len;
385
147
    uint64_t iv_bits;
386
147
#if !defined(MBEDTLS_BLOCK_CIPHER_C)
387
147
    size_t olen = 0;
388
147
#endif
389
390
    /* IV is limited to 2^64 bits, so 2^61 bytes */
391
    /* IV is not allowed to be zero length */
392
147
    if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
393
2
        return MBEDTLS_ERR_GCM_BAD_INPUT;
394
2
    }
395
396
145
    memset(ctx->y, 0x00, sizeof(ctx->y));
397
145
    memset(ctx->buf, 0x00, sizeof(ctx->buf));
398
399
145
    ctx->mode = mode;
400
145
    ctx->len = 0;
401
145
    ctx->add_len = 0;
402
403
145
    if (iv_len == 12) {
404
7
        memcpy(ctx->y, iv, iv_len);
405
7
        ctx->y[15] = 1;
406
138
    } else {
407
138
        memset(work_buf, 0x00, 16);
408
138
        iv_bits = (uint64_t) iv_len * 8;
409
138
        MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
410
411
138
        p = iv;
412
3.06k
        while (iv_len > 0) {
413
2.92k
            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
2.92k
            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
2.92k
            gcm_mult(ctx, ctx->y, ctx->y);
427
428
2.92k
            iv_len -= use_len;
429
2.92k
            p += use_len;
430
2.92k
        }
431
432
138
        mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
433
434
138
        gcm_mult(ctx, ctx->y, ctx->y);
435
138
    }
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
145
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
442
145
#endif
443
145
    if (ret != 0) {
444
0
        return ret;
445
0
    }
446
447
145
    return 0;
448
145
}
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
144
{
470
144
    const unsigned char *p;
471
144
    size_t use_len, offset;
472
144
    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
144
    new_add_len = ctx->add_len + (uint64_t) add_len;
482
144
    if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
483
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
484
0
    }
485
486
144
    offset = ctx->add_len % 16;
487
144
    p = add;
488
489
144
    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
144
    ctx->add_len += add_len;
507
508
1.43k
    while (add_len >= 16) {
509
1.29k
        mbedtls_xor(ctx->buf, ctx->buf, p, 16);
510
511
1.29k
        gcm_mult(ctx, ctx->buf, ctx->buf);
512
513
1.29k
        add_len -= 16;
514
1.29k
        p += 16;
515
1.29k
    }
516
517
144
    if (add_len > 0) {
518
22
        mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
519
22
    }
520
521
144
    return 0;
522
144
}
523
524
/* Increment the counter. */
525
static void gcm_incr(unsigned char y[16])
526
4.60k
{
527
4.60k
    uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
528
4.60k
    x++;
529
4.60k
    MBEDTLS_PUT_UINT32_BE(x, y, 12);
530
4.60k
}
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
4.61k
{
540
4.61k
    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
4.61k
    size_t olen = 0;
546
4.61k
    ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
547
4.61k
#endif
548
4.61k
    if (ret != 0) {
549
0
        mbedtls_platform_zeroize(ectr, 16);
550
0
        return ret;
551
0
    }
552
553
4.61k
    if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
554
1.77k
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
555
1.77k
    }
556
4.61k
    mbedtls_xor(output, ectr + offset, input, use_len);
557
4.61k
    if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
558
2.83k
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
559
2.83k
    }
560
561
4.61k
    return 0;
562
4.61k
}
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
677
{
569
677
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
570
677
    const unsigned char *p = input;
571
677
    unsigned char *out_p = output;
572
677
    size_t offset;
573
677
    unsigned char ectr[16] = { 0 };
574
575
677
    if (output_size < input_length) {
576
0
        return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
577
0
    }
578
677
    *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
677
    if (input_length == 0) {
585
324
        return 0;
586
324
    }
587
588
353
    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
353
    if (ctx->len + input_length < ctx->len ||
595
353
        (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
596
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
597
0
    }
598
599
353
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
600
18
        gcm_mult(ctx, ctx->buf, ctx->buf);
601
18
    }
602
603
353
    offset = ctx->len % 16;
604
353
    if (offset != 0) {
605
9
        size_t use_len = 16 - offset;
606
9
        if (use_len > input_length) {
607
4
            use_len = input_length;
608
4
        }
609
610
9
        if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
611
0
            return ret;
612
0
        }
613
614
9
        if (offset + use_len == 16) {
615
5
            gcm_mult(ctx, ctx->buf, ctx->buf);
616
5
        }
617
618
9
        ctx->len += use_len;
619
9
        input_length -= use_len;
620
9
        p += use_len;
621
9
        out_p += use_len;
622
9
    }
623
624
353
    ctx->len += input_length;
625
626
4.83k
    while (input_length >= 16) {
627
4.48k
        gcm_incr(ctx->y);
628
4.48k
        if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
629
0
            return ret;
630
0
        }
631
632
4.48k
        gcm_mult(ctx, ctx->buf, ctx->buf);
633
634
4.48k
        input_length -= 16;
635
4.48k
        p += 16;
636
4.48k
        out_p += 16;
637
4.48k
    }
638
639
353
    if (input_length > 0) {
640
122
        gcm_incr(ctx->y);
641
122
        if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
642
0
            return ret;
643
0
        }
644
122
    }
645
646
353
    mbedtls_platform_zeroize(ectr, sizeof(ectr));
647
353
    return 0;
648
353
}
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
100
{
655
100
    unsigned char work_buf[16];
656
100
    uint64_t orig_len;
657
100
    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
100
    (void) output;
662
100
    (void) output_size;
663
100
    *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
100
    orig_len = ctx->len * 8;
669
100
    orig_add_len = ctx->add_len * 8;
670
671
100
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
672
4
        gcm_mult(ctx, ctx->buf, ctx->buf);
673
4
    }
674
675
100
    if (tag_len > 16 || tag_len < 4) {
676
77
        return MBEDTLS_ERR_GCM_BAD_INPUT;
677
77
    }
678
679
23
    if (ctx->len % 16 != 0) {
680
13
        gcm_mult(ctx, ctx->buf, ctx->buf);
681
13
    }
682
683
23
    memcpy(tag, ctx->base_ectr, tag_len);
684
685
23
    if (orig_len || orig_add_len) {
686
17
        memset(work_buf, 0x00, 16);
687
688
17
        MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
689
17
        MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
690
17
        MBEDTLS_PUT_UINT32_BE((orig_len     >> 32), work_buf, 8);
691
17
        MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
692
693
17
        mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
694
695
17
        gcm_mult(ctx, ctx->buf, ctx->buf);
696
697
17
        mbedtls_xor(tag, tag, ctx->buf, tag_len);
698
17
    }
699
700
23
    return 0;
701
100
}
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
101
{
715
101
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
716
101
    size_t olen;
717
718
101
    if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
719
2
        return ret;
720
2
    }
721
722
99
    if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
723
0
        return ret;
724
0
    }
725
726
99
    if ((ret = mbedtls_gcm_update(ctx, input, length,
727
99
                                  output, length, &olen)) != 0) {
728
0
        return ret;
729
0
    }
730
731
99
    if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
732
77
        return ret;
733
77
    }
734
735
22
    return 0;
736
99
}
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
55
{
749
55
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
750
55
    unsigned char check_tag[16];
751
55
    int diff;
752
753
55
    if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
754
55
                                         iv, iv_len, add, add_len,
755
55
                                         input, output, tag_len, check_tag)) != 0) {
756
43
        return ret;
757
43
    }
758
759
    /* Check tag in "constant-time" */
760
12
    diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
761
762
12
    if (diff != 0) {
763
6
        mbedtls_platform_zeroize(output, length);
764
6
        return MBEDTLS_ERR_GCM_AUTH_FAILED;
765
6
    }
766
767
6
    return 0;
768
12
}
769
770
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
771
277
{
772
277
    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
277
    mbedtls_cipher_free(&ctx->cipher_ctx);
779
277
#endif
780
277
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
781
277
}
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 */