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