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