Coverage Report

Created: 2024-08-06 15:09

/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
82
{
52
82
    memset(ctx, 0, sizeof(mbedtls_gcm_context));
53
82
}
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
82
{
65
82
    int ret, i, j;
66
82
    uint64_t hi, lo;
67
82
    uint64_t vl, vh;
68
82
    unsigned char h[16];
69
82
    size_t olen = 0;
70
71
82
    memset(h, 0, 16);
72
82
    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
82
    hi = MBEDTLS_GET_UINT32_BE(h,  0);
78
82
    lo = MBEDTLS_GET_UINT32_BE(h,  4);
79
82
    vh = (uint64_t) hi << 32 | lo;
80
81
82
    hi = MBEDTLS_GET_UINT32_BE(h,  8);
82
82
    lo = MBEDTLS_GET_UINT32_BE(h,  12);
83
82
    vl = (uint64_t) hi << 32 | lo;
84
85
    /* 8 = 1000 corresponds to 1 in GF(2^128) */
86
82
    ctx->HL[8] = vl;
87
82
    ctx->HH[8] = vh;
88
89
82
#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
82
    if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
92
82
        return 0;
93
82
    }
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
82
}
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
82
{
127
82
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
128
82
    const mbedtls_cipher_info_t *cipher_info;
129
130
82
    if (keybits != 128 && keybits != 192 && keybits != 256) {
131
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
132
0
    }
133
134
82
    cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
135
82
                                                  MBEDTLS_MODE_ECB);
136
82
    if (cipher_info == NULL) {
137
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
138
0
    }
139
140
82
    if (cipher_info->block_size != 16) {
141
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
142
0
    }
143
144
82
    mbedtls_cipher_free(&ctx->cipher_ctx);
145
146
82
    if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
147
0
        return ret;
148
0
    }
149
150
82
    if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
151
82
                                     MBEDTLS_ENCRYPT)) != 0) {
152
0
        return ret;
153
0
    }
154
155
82
    if ((ret = gcm_gen_table(ctx)) != 0) {
156
0
        return ret;
157
0
    }
158
159
82
    return 0;
160
82
}
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
9.77k
{
182
9.77k
    int i = 0;
183
9.77k
    unsigned char lo, hi, rem;
184
9.77k
    uint64_t zh, zl;
185
186
9.77k
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
187
9.77k
    if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
188
9.77k
        unsigned char h[16];
189
190
9.77k
        MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h,  0);
191
9.77k
        MBEDTLS_PUT_UINT32_BE(ctx->HH[8],       h,  4);
192
9.77k
        MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h,  8);
193
9.77k
        MBEDTLS_PUT_UINT32_BE(ctx->HL[8],       h, 12);
194
195
9.77k
        mbedtls_aesni_gcm_mult(output, x, h);
196
9.77k
        return;
197
9.77k
    }
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
105
{
237
105
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
238
105
    unsigned char work_buf[16];
239
105
    const unsigned char *p;
240
105
    size_t use_len, olen = 0;
241
105
    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
105
    if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
246
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
247
0
    }
248
249
105
    memset(ctx->y, 0x00, sizeof(ctx->y));
250
105
    memset(ctx->buf, 0x00, sizeof(ctx->buf));
251
252
105
    ctx->mode = mode;
253
105
    ctx->len = 0;
254
105
    ctx->add_len = 0;
255
256
105
    if (iv_len == 12) {
257
105
        memcpy(ctx->y, iv, iv_len);
258
105
        ctx->y[15] = 1;
259
105
    } 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
105
    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
282
105
                                     ctx->base_ectr, &olen)) != 0) {
283
0
        return ret;
284
0
    }
285
286
105
    return 0;
287
105
}
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
105
{
309
105
    const unsigned char *p;
310
105
    size_t use_len, offset;
311
312
    /* IV is limited to 2^64 bits, so 2^61 bytes */
313
105
    if ((uint64_t) add_len >> 61 != 0) {
314
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
315
0
    }
316
317
105
    offset = ctx->add_len % 16;
318
105
    p = add;
319
320
105
    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
105
    ctx->add_len += add_len;
338
339
105
    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
105
    if (add_len > 0) {
349
105
        mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
350
105
    }
351
352
105
    return 0;
353
105
}
354
355
/* Increment the counter. */
356
static void gcm_incr(unsigned char y[16])
357
9.56k
{
358
9.56k
    size_t i;
359
9.59k
    for (i = 16; i > 12; i--) {
360
9.59k
        if (++y[i - 1] != 0) {
361
9.56k
            break;
362
9.56k
        }
363
9.59k
    }
364
9.56k
}
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
9.56k
{
374
9.56k
    size_t olen = 0;
375
9.56k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
376
377
9.56k
    if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr,
378
9.56k
                                     &olen)) != 0) {
379
0
        mbedtls_platform_zeroize(ectr, 16);
380
0
        return ret;
381
0
    }
382
383
9.56k
    if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
384
9.44k
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
385
9.44k
    }
386
9.56k
    mbedtls_xor(output, ectr + offset, input, use_len);
387
9.56k
    if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
388
120
        mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
389
120
    }
390
391
9.56k
    return 0;
392
9.56k
}
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
105
{
399
105
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
400
105
    const unsigned char *p = input;
401
105
    unsigned char *out_p = output;
402
105
    size_t offset;
403
105
    unsigned char ectr[16] = { 0 };
404
405
105
    if (output_size < input_length) {
406
0
        return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
407
0
    }
408
105
    *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
105
    if (input_length == 0) {
415
1
        return 0;
416
1
    }
417
418
104
    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
104
    if (ctx->len + input_length < ctx->len ||
425
104
        (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
426
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
427
0
    }
428
429
104
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
430
104
        gcm_mult(ctx, ctx->buf, ctx->buf);
431
104
    }
432
433
104
    offset = ctx->len % 16;
434
104
    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
104
    ctx->len += input_length;
455
456
9.57k
    while (input_length >= 16) {
457
9.46k
        gcm_incr(ctx->y);
458
9.46k
        if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
459
0
            return ret;
460
0
        }
461
462
9.46k
        gcm_mult(ctx, ctx->buf, ctx->buf);
463
464
9.46k
        input_length -= 16;
465
9.46k
        p += 16;
466
9.46k
        out_p += 16;
467
9.46k
    }
468
469
104
    if (input_length > 0) {
470
101
        gcm_incr(ctx->y);
471
101
        if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
472
0
            return ret;
473
0
        }
474
101
    }
475
476
104
    mbedtls_platform_zeroize(ectr, sizeof(ectr));
477
104
    return 0;
478
104
}
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
105
{
485
105
    unsigned char work_buf[16];
486
105
    uint64_t orig_len;
487
105
    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
105
    (void) output;
492
105
    (void) output_size;
493
105
    *output_length = 0;
494
495
105
    orig_len = ctx->len * 8;
496
105
    orig_add_len = ctx->add_len * 8;
497
498
105
    if (ctx->len == 0 && ctx->add_len % 16 != 0) {
499
1
        gcm_mult(ctx, ctx->buf, ctx->buf);
500
1
    }
501
502
105
    if (tag_len > 16 || tag_len < 4) {
503
0
        return MBEDTLS_ERR_GCM_BAD_INPUT;
504
0
    }
505
506
105
    if (ctx->len % 16 != 0) {
507
101
        gcm_mult(ctx, ctx->buf, ctx->buf);
508
101
    }
509
510
105
    memcpy(tag, ctx->base_ectr, tag_len);
511
512
105
    if (orig_len || orig_add_len) {
513
105
        memset(work_buf, 0x00, 16);
514
515
105
        MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
516
105
        MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
517
105
        MBEDTLS_PUT_UINT32_BE((orig_len     >> 32), work_buf, 8);
518
105
        MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
519
520
105
        mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
521
522
105
        gcm_mult(ctx, ctx->buf, ctx->buf);
523
524
105
        mbedtls_xor(tag, tag, ctx->buf, tag_len);
525
105
    }
526
527
105
    return 0;
528
105
}
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
105
{
542
105
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
543
105
    size_t olen;
544
545
105
    if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
546
0
        return ret;
547
0
    }
548
549
105
    if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
550
0
        return ret;
551
0
    }
552
553
105
    if ((ret = mbedtls_gcm_update(ctx, input, length,
554
105
                                  output, length, &olen)) != 0) {
555
0
        return ret;
556
0
    }
557
558
105
    if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
559
0
        return ret;
560
0
    }
561
562
105
    return 0;
563
105
}
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
29
{
576
29
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
577
29
    unsigned char check_tag[16];
578
29
    size_t i;
579
29
    int diff;
580
581
29
    if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
582
29
                                         iv, iv_len, add, add_len,
583
29
                                         input, output, tag_len, check_tag)) != 0) {
584
0
        return ret;
585
0
    }
586
587
    /* Check tag in "constant-time" */
588
493
    for (diff = 0, i = 0; i < tag_len; i++) {
589
464
        diff |= tag[i] ^ check_tag[i];
590
464
    }
591
592
29
    if (diff != 0) {
593
29
        mbedtls_platform_zeroize(output, length);
594
29
        return MBEDTLS_ERR_GCM_AUTH_FAILED;
595
29
    }
596
597
0
    return 0;
598
29
}
599
600
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
601
82
{
602
82
    if (ctx == NULL) {
603
0
        return;
604
0
    }
605
82
    mbedtls_cipher_free(&ctx->cipher_ctx);
606
82
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
607
82
}
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 */