Coverage Report

Created: 2026-11-11 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/duckdb/third_party/mbedtls/library/gcm.cpp
Line
Count
Source
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
0
#define MBEDTLS_GCM_ACC_SMALLTABLE  0
46
#define MBEDTLS_GCM_ACC_LARGETABLE  1
47
#define MBEDTLS_GCM_ACC_AESNI       2
48
#define MBEDTLS_GCM_ACC_AESCE       3
49
50
/*
51
 * Initialize a context
52
 */
53
void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
54
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
#if defined(MBEDTLS_GCM_LARGE_TABLE)
61
    ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
62
#else
63
0
    ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
64
0
#endif
65
66
#if defined(MBEDTLS_AESNI_HAVE_CODE)
67
    /* With CLMUL support, we need only h, not the rest of the table */
68
    if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
69
        ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
70
    }
71
#endif
72
73
#if defined(MBEDTLS_AESCE_HAVE_CODE)
74
    if (MBEDTLS_AESCE_HAS_SUPPORT()) {
75
        ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
76
    }
77
#endif
78
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
#if defined(MBEDTLS_AESNI_HAVE_CODE)
123
        case MBEDTLS_GCM_ACC_AESNI:
124
            return 0;
125
#endif
126
127
#if defined(MBEDTLS_AESCE_HAVE_CODE)
128
        case MBEDTLS_GCM_ACC_AESCE:
129
            return 0;
130
#endif
131
132
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
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
{
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
0
{
350
0
    switch (ctx->acceleration) {
351
#if defined(MBEDTLS_AESNI_HAVE_CODE)
352
        case MBEDTLS_GCM_ACC_AESNI:
353
            mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
354
            break;
355
#endif
356
357
#if defined(MBEDTLS_AESCE_HAVE_CODE)
358
        case MBEDTLS_GCM_ACC_AESCE:
359
            mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
360
            break;
361
#endif
362
363
#if defined(MBEDTLS_GCM_LARGE_TABLE)
364
        case MBEDTLS_GCM_ACC_LARGETABLE:
365
            gcm_mult_largetable(output, x, ctx->H);
366
            break;
367
#else
368
0
        case MBEDTLS_GCM_ACC_SMALLTABLE:
369
0
            gcm_mult_smalltable(output, x, ctx->H);
370
0
            break;
371
0
#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
#define MAX_TESTS   6
792
793
static const int key_index_test_data[MAX_TESTS] =
794
{ 0, 0, 1, 1, 1, 1 };
795
796
static const unsigned char key_test_data[][32] =
797
{
798
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
802
    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
803
      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
804
      0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
805
      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
806
};
807
808
static const size_t iv_len_test_data[MAX_TESTS] =
809
{ 12, 12, 12, 12, 8, 60 };
810
811
static const int iv_index_test_data[MAX_TESTS] =
812
{ 0, 0, 1, 1, 1, 2 };
813
814
static const unsigned char iv_test_data[][64] =
815
{
816
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817
      0x00, 0x00, 0x00, 0x00 },
818
    { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
819
      0xde, 0xca, 0xf8, 0x88 },
820
    { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
821
      0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
822
      0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
823
      0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
824
      0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
825
      0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
826
      0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
827
      0xa6, 0x37, 0xb3, 0x9b },
828
};
829
830
static const size_t add_len_test_data[MAX_TESTS] =
831
{ 0, 0, 0, 20, 20, 20 };
832
833
static const int add_index_test_data[MAX_TESTS] =
834
{ 0, 0, 0, 1, 1, 1 };
835
836
static const unsigned char additional_test_data[][64] =
837
{
838
    { 0x00 },
839
    { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
840
      0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
841
      0xab, 0xad, 0xda, 0xd2 },
842
};
843
844
static const size_t pt_len_test_data[MAX_TESTS] =
845
{ 0, 16, 64, 60, 60, 60 };
846
847
static const int pt_index_test_data[MAX_TESTS] =
848
{ 0, 0, 1, 1, 1, 1 };
849
850
static const unsigned char pt_test_data[][64] =
851
{
852
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
854
    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
855
      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
856
      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
857
      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
858
      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
859
      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
860
      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
861
      0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
862
};
863
864
static const unsigned char ct_test_data[][64] =
865
{
866
    { 0x00 },
867
    { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
868
      0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
869
    { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
870
      0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
871
      0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
872
      0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
873
      0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
874
      0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
875
      0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
876
      0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
877
    { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
878
      0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
879
      0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
880
      0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
881
      0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
882
      0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
883
      0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
884
      0x3d, 0x58, 0xe0, 0x91 },
885
    { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
886
      0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
887
      0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
888
      0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
889
      0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
890
      0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
891
      0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
892
      0xc2, 0x3f, 0x45, 0x98 },
893
    { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
894
      0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
895
      0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
896
      0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
897
      0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
898
      0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
899
      0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
900
      0x4c, 0x34, 0xae, 0xe5 },
901
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
902
    { 0x00 },
903
    { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
904
      0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
905
    { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
906
      0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
907
      0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
908
      0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
909
      0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
910
      0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
911
      0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
912
      0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
913
    { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
914
      0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
915
      0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
916
      0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
917
      0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
918
      0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
919
      0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
920
      0xcc, 0xda, 0x27, 0x10 },
921
    { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
922
      0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
923
      0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
924
      0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
925
      0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
926
      0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
927
      0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
928
      0xa0, 0xf0, 0x62, 0xf7 },
929
    { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
930
      0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
931
      0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
932
      0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
933
      0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
934
      0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
935
      0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
936
      0xe9, 0xb7, 0x37, 0x3b },
937
    { 0x00 },
938
    { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
939
      0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
940
    { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
941
      0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
942
      0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
943
      0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
944
      0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
945
      0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
946
      0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
947
      0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
948
    { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
949
      0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
950
      0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
951
      0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
952
      0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
953
      0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
954
      0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
955
      0xbc, 0xc9, 0xf6, 0x62 },
956
    { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
957
      0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
958
      0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
959
      0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
960
      0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
961
      0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
962
      0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
963
      0xf4, 0x7c, 0x9b, 0x1f },
964
    { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
965
      0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
966
      0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
967
      0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
968
      0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
969
      0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
970
      0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
971
      0x44, 0xae, 0x7e, 0x3f },
972
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
973
};
974
975
static const unsigned char tag_test_data[][16] =
976
{
977
    { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
978
      0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
979
    { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
980
      0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
981
    { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
982
      0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
983
    { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
984
      0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
985
    { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
986
      0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
987
    { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
988
      0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
989
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
990
    { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
991
      0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
992
    { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
993
      0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
994
    { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
995
      0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
996
    { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
997
      0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
998
    { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
999
      0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
1000
    { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
1001
      0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
1002
    { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
1003
      0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
1004
    { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
1005
      0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
1006
    { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
1007
      0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
1008
    { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
1009
      0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
1010
    { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
1011
      0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
1012
    { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
1013
      0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
1014
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1015
};
1016
1017
int mbedtls_gcm_self_test(int verbose)
1018
{
1019
    mbedtls_gcm_context ctx;
1020
    unsigned char buf[64];
1021
    unsigned char tag_buf[16];
1022
    int i, j, ret;
1023
    mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
1024
    size_t olen;
1025
1026
    if (verbose != 0) {
1027
#if defined(MBEDTLS_GCM_ALT)
1028
        mbedtls_printf("  GCM note: alternative implementation.\n");
1029
#else /* MBEDTLS_GCM_ALT */
1030
#if defined(MBEDTLS_AESNI_HAVE_CODE)
1031
        if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
1032
            mbedtls_printf("  GCM note: using AESNI.\n");
1033
        } else
1034
#endif
1035
1036
#if defined(MBEDTLS_AESCE_HAVE_CODE)
1037
        if (MBEDTLS_AESCE_HAS_SUPPORT()) {
1038
            mbedtls_printf("  GCM note: using AESCE.\n");
1039
        } else
1040
#endif
1041
1042
        mbedtls_printf("  GCM note: built-in implementation.\n");
1043
#endif /* MBEDTLS_GCM_ALT */
1044
    }
1045
1046
    static const int loop_limit =
1047
        (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
1048
1049
    for (j = 0; j < loop_limit; j++) {
1050
        int key_len = 128 + 64 * j;
1051
1052
        for (i = 0; i < MAX_TESTS; i++) {
1053
            if (verbose != 0) {
1054
                mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
1055
                               key_len, i, "enc");
1056
            }
1057
1058
            mbedtls_gcm_init(&ctx);
1059
1060
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1061
                                     key_test_data[key_index_test_data[i]],
1062
                                     key_len);
1063
            /*
1064
             * AES-192 is an optional feature that may be unavailable when
1065
             * there is an alternative underlying implementation i.e. when
1066
             * MBEDTLS_AES_ALT is defined.
1067
             */
1068
            if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
1069
                mbedtls_printf("skipped\n");
1070
                break;
1071
            } else if (ret != 0) {
1072
                goto exit;
1073
            }
1074
1075
            ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
1076
                                            pt_len_test_data[i],
1077
                                            iv_test_data[iv_index_test_data[i]],
1078
                                            iv_len_test_data[i],
1079
                                            additional_test_data[add_index_test_data[i]],
1080
                                            add_len_test_data[i],
1081
                                            pt_test_data[pt_index_test_data[i]],
1082
                                            buf, 16, tag_buf);
1083
#if defined(MBEDTLS_GCM_ALT)
1084
            /* Allow alternative implementations to only support 12-byte nonces. */
1085
            if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
1086
                iv_len_test_data[i] != 12) {
1087
                mbedtls_printf("skipped\n");
1088
                break;
1089
            }
1090
#endif /* defined(MBEDTLS_GCM_ALT) */
1091
            if (ret != 0) {
1092
                goto exit;
1093
            }
1094
1095
            if (memcmp(buf, ct_test_data[j * 6 + i],
1096
                       pt_len_test_data[i]) != 0 ||
1097
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1098
                ret = 1;
1099
                goto exit;
1100
            }
1101
1102
            mbedtls_gcm_free(&ctx);
1103
1104
            if (verbose != 0) {
1105
                mbedtls_printf("passed\n");
1106
            }
1107
1108
            mbedtls_gcm_init(&ctx);
1109
1110
            if (verbose != 0) {
1111
                mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
1112
                               key_len, i, "dec");
1113
            }
1114
1115
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1116
                                     key_test_data[key_index_test_data[i]],
1117
                                     key_len);
1118
            if (ret != 0) {
1119
                goto exit;
1120
            }
1121
1122
            ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1123
                                            pt_len_test_data[i],
1124
                                            iv_test_data[iv_index_test_data[i]],
1125
                                            iv_len_test_data[i],
1126
                                            additional_test_data[add_index_test_data[i]],
1127
                                            add_len_test_data[i],
1128
                                            ct_test_data[j * 6 + i], buf, 16, tag_buf);
1129
1130
            if (ret != 0) {
1131
                goto exit;
1132
            }
1133
1134
            if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1135
                       pt_len_test_data[i]) != 0 ||
1136
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1137
                ret = 1;
1138
                goto exit;
1139
            }
1140
1141
            mbedtls_gcm_free(&ctx);
1142
1143
            if (verbose != 0) {
1144
                mbedtls_printf("passed\n");
1145
            }
1146
1147
            mbedtls_gcm_init(&ctx);
1148
1149
            if (verbose != 0) {
1150
                mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
1151
                               key_len, i, "enc");
1152
            }
1153
1154
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1155
                                     key_test_data[key_index_test_data[i]],
1156
                                     key_len);
1157
            if (ret != 0) {
1158
                goto exit;
1159
            }
1160
1161
            ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1162
                                     iv_test_data[iv_index_test_data[i]],
1163
                                     iv_len_test_data[i]);
1164
            if (ret != 0) {
1165
                goto exit;
1166
            }
1167
1168
            ret = mbedtls_gcm_update_ad(&ctx,
1169
                                        additional_test_data[add_index_test_data[i]],
1170
                                        add_len_test_data[i]);
1171
            if (ret != 0) {
1172
                goto exit;
1173
            }
1174
1175
            if (pt_len_test_data[i] > 32) {
1176
                size_t rest_len = pt_len_test_data[i] - 32;
1177
                ret = mbedtls_gcm_update(&ctx,
1178
                                         pt_test_data[pt_index_test_data[i]],
1179
                                         32,
1180
                                         buf, sizeof(buf), &olen);
1181
                if (ret != 0) {
1182
                    goto exit;
1183
                }
1184
                if (olen != 32) {
1185
                    goto exit;
1186
                }
1187
1188
                ret = mbedtls_gcm_update(&ctx,
1189
                                         pt_test_data[pt_index_test_data[i]] + 32,
1190
                                         rest_len,
1191
                                         buf + 32, sizeof(buf) - 32, &olen);
1192
                if (ret != 0) {
1193
                    goto exit;
1194
                }
1195
                if (olen != rest_len) {
1196
                    goto exit;
1197
                }
1198
            } else {
1199
                ret = mbedtls_gcm_update(&ctx,
1200
                                         pt_test_data[pt_index_test_data[i]],
1201
                                         pt_len_test_data[i],
1202
                                         buf, sizeof(buf), &olen);
1203
                if (ret != 0) {
1204
                    goto exit;
1205
                }
1206
                if (olen != pt_len_test_data[i]) {
1207
                    goto exit;
1208
                }
1209
            }
1210
1211
            ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1212
            if (ret != 0) {
1213
                goto exit;
1214
            }
1215
1216
            if (memcmp(buf, ct_test_data[j * 6 + i],
1217
                       pt_len_test_data[i]) != 0 ||
1218
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1219
                ret = 1;
1220
                goto exit;
1221
            }
1222
1223
            mbedtls_gcm_free(&ctx);
1224
1225
            if (verbose != 0) {
1226
                mbedtls_printf("passed\n");
1227
            }
1228
1229
            mbedtls_gcm_init(&ctx);
1230
1231
            if (verbose != 0) {
1232
                mbedtls_printf("  AES-GCM-%3d #%d split (%s): ",
1233
                               key_len, i, "dec");
1234
            }
1235
1236
            ret = mbedtls_gcm_setkey(&ctx, cipher,
1237
                                     key_test_data[key_index_test_data[i]],
1238
                                     key_len);
1239
            if (ret != 0) {
1240
                goto exit;
1241
            }
1242
1243
            ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1244
                                     iv_test_data[iv_index_test_data[i]],
1245
                                     iv_len_test_data[i]);
1246
            if (ret != 0) {
1247
                goto exit;
1248
            }
1249
            ret = mbedtls_gcm_update_ad(&ctx,
1250
                                        additional_test_data[add_index_test_data[i]],
1251
                                        add_len_test_data[i]);
1252
            if (ret != 0) {
1253
                goto exit;
1254
            }
1255
1256
            if (pt_len_test_data[i] > 32) {
1257
                size_t rest_len = pt_len_test_data[i] - 32;
1258
                ret = mbedtls_gcm_update(&ctx,
1259
                                         ct_test_data[j * 6 + i], 32,
1260
                                         buf, sizeof(buf), &olen);
1261
                if (ret != 0) {
1262
                    goto exit;
1263
                }
1264
                if (olen != 32) {
1265
                    goto exit;
1266
                }
1267
1268
                ret = mbedtls_gcm_update(&ctx,
1269
                                         ct_test_data[j * 6 + i] + 32,
1270
                                         rest_len,
1271
                                         buf + 32, sizeof(buf) - 32, &olen);
1272
                if (ret != 0) {
1273
                    goto exit;
1274
                }
1275
                if (olen != rest_len) {
1276
                    goto exit;
1277
                }
1278
            } else {
1279
                ret = mbedtls_gcm_update(&ctx,
1280
                                         ct_test_data[j * 6 + i],
1281
                                         pt_len_test_data[i],
1282
                                         buf, sizeof(buf), &olen);
1283
                if (ret != 0) {
1284
                    goto exit;
1285
                }
1286
                if (olen != pt_len_test_data[i]) {
1287
                    goto exit;
1288
                }
1289
            }
1290
1291
            ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1292
            if (ret != 0) {
1293
                goto exit;
1294
            }
1295
1296
            if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1297
                       pt_len_test_data[i]) != 0 ||
1298
                memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1299
                ret = 1;
1300
                goto exit;
1301
            }
1302
1303
            mbedtls_gcm_free(&ctx);
1304
1305
            if (verbose != 0) {
1306
                mbedtls_printf("passed\n");
1307
            }
1308
        }
1309
    }
1310
1311
    if (verbose != 0) {
1312
        mbedtls_printf("\n");
1313
    }
1314
1315
    ret = 0;
1316
1317
exit:
1318
    if (ret != 0) {
1319
        if (verbose != 0) {
1320
            mbedtls_printf("failed\n");
1321
        }
1322
        mbedtls_gcm_free(&ctx);
1323
    }
1324
1325
    return ret;
1326
}
1327
1328
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1329
1330
#endif /* MBEDTLS_GCM_C */