Coverage Report

Created: 2024-01-20 12:33

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