• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_AESCE_C)
46 #include "aesce.h"
47 #endif
48 
49 #if !defined(MBEDTLS_GCM_ALT)
50 
51 /*
52  * Initialize a context
53  */
mbedtls_gcm_init(mbedtls_gcm_context * ctx)54 void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
55 {
56     memset(ctx, 0, sizeof(mbedtls_gcm_context));
57 }
58 
59 /*
60  * Precompute small multiples of H, that is set
61  *      HH[i] || HL[i] = H times i,
62  * where i is seen as a field element as in [MGV], ie high-order bits
63  * correspond to low powers of P. The result is stored in the same way, that
64  * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
65  * corresponds to P^127.
66  */
gcm_gen_table(mbedtls_gcm_context * ctx)67 static int gcm_gen_table(mbedtls_gcm_context *ctx)
68 {
69     int ret, i, j;
70     uint64_t hi, lo;
71     uint64_t vl, vh;
72     unsigned char h[16];
73     size_t olen = 0;
74 
75     memset(h, 0, 16);
76     if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) {
77         return ret;
78     }
79 
80     /* pack h as two 64-bits ints, big-endian */
81     hi = MBEDTLS_GET_UINT32_BE(h,  0);
82     lo = MBEDTLS_GET_UINT32_BE(h,  4);
83     vh = (uint64_t) hi << 32 | lo;
84 
85     hi = MBEDTLS_GET_UINT32_BE(h,  8);
86     lo = MBEDTLS_GET_UINT32_BE(h,  12);
87     vl = (uint64_t) hi << 32 | lo;
88 
89     /* 8 = 1000 corresponds to 1 in GF(2^128) */
90     ctx->HL[8] = vl;
91     ctx->HH[8] = vh;
92 
93 #if defined(MBEDTLS_AESNI_HAVE_CODE)
94     /* With CLMUL support, we need only h, not the rest of the table */
95     if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
96         return 0;
97     }
98 #endif
99 
100 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
101     if (mbedtls_aesce_has_support()) {
102         return 0;
103     }
104 #endif
105 
106     /* 0 corresponds to 0 in GF(2^128) */
107     ctx->HH[0] = 0;
108     ctx->HL[0] = 0;
109 
110     for (i = 4; i > 0; i >>= 1) {
111         uint32_t T = (vl & 1) * 0xe1000000U;
112         vl  = (vh << 63) | (vl >> 1);
113         vh  = (vh >> 1) ^ ((uint64_t) T << 32);
114 
115         ctx->HL[i] = vl;
116         ctx->HH[i] = vh;
117     }
118 
119     for (i = 2; i <= 8; i *= 2) {
120         uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
121         vh = *HiH;
122         vl = *HiL;
123         for (j = 1; j < i; j++) {
124             HiH[j] = vh ^ ctx->HH[j];
125             HiL[j] = vl ^ ctx->HL[j];
126         }
127     }
128 
129     return 0;
130 }
131 
mbedtls_gcm_setkey(mbedtls_gcm_context * ctx,mbedtls_cipher_id_t cipher,const unsigned char * key,unsigned int keybits)132 int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
133                        mbedtls_cipher_id_t cipher,
134                        const unsigned char *key,
135                        unsigned int keybits)
136 {
137     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
138     const mbedtls_cipher_info_t *cipher_info;
139 
140     if (keybits != 128 && keybits != 192 && keybits != 256) {
141         return MBEDTLS_ERR_GCM_BAD_INPUT;
142     }
143 
144     cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
145                                                   MBEDTLS_MODE_ECB);
146     if (cipher_info == NULL) {
147         return MBEDTLS_ERR_GCM_BAD_INPUT;
148     }
149 
150     if (cipher_info->block_size != 16) {
151         return MBEDTLS_ERR_GCM_BAD_INPUT;
152     }
153 
154     mbedtls_cipher_free(&ctx->cipher_ctx);
155 
156     if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
157         return ret;
158     }
159 
160     if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
161                                      MBEDTLS_ENCRYPT)) != 0) {
162         return ret;
163     }
164 
165     if ((ret = gcm_gen_table(ctx)) != 0) {
166         return ret;
167     }
168 
169     return 0;
170 }
171 
172 /*
173  * Shoup's method for multiplication use this table with
174  *      last4[x] = x times P^128
175  * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
176  */
177 static const uint64_t last4[16] =
178 {
179     0x0000, 0x1c20, 0x3840, 0x2460,
180     0x7080, 0x6ca0, 0x48c0, 0x54e0,
181     0xe100, 0xfd20, 0xd940, 0xc560,
182     0x9180, 0x8da0, 0xa9c0, 0xb5e0
183 };
184 
185 /*
186  * Sets output to x times H using the precomputed tables.
187  * x and output are seen as elements of GF(2^128) as in [MGV].
188  */
gcm_mult(mbedtls_gcm_context * ctx,const unsigned char x[16],unsigned char output[16])189 static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
190                      unsigned char output[16])
191 {
192     int i = 0;
193     unsigned char lo, hi, rem;
194     uint64_t zh, zl;
195 
196 #if defined(MBEDTLS_AESNI_HAVE_CODE)
197     if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
198         unsigned char h[16];
199 
200         /* mbedtls_aesni_gcm_mult needs big-endian input */
201         MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h,  0);
202         MBEDTLS_PUT_UINT32_BE(ctx->HH[8],       h,  4);
203         MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h,  8);
204         MBEDTLS_PUT_UINT32_BE(ctx->HL[8],       h, 12);
205 
206         mbedtls_aesni_gcm_mult(output, x, h);
207         return;
208     }
209 #endif /* MBEDTLS_AESNI_HAVE_CODE */
210 
211 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
212     if (mbedtls_aesce_has_support()) {
213         unsigned char h[16];
214 
215         /* mbedtls_aesce_gcm_mult needs big-endian input */
216         MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h,  0);
217         MBEDTLS_PUT_UINT32_BE(ctx->HH[8],       h,  4);
218         MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h,  8);
219         MBEDTLS_PUT_UINT32_BE(ctx->HL[8],       h, 12);
220 
221         mbedtls_aesce_gcm_mult(output, x, h);
222         return;
223     }
224 #endif
225 
226     lo = x[15] & 0xf;
227 
228     zh = ctx->HH[lo];
229     zl = ctx->HL[lo];
230 
231     for (i = 15; i >= 0; i--) {
232         lo = x[i] & 0xf;
233         hi = (x[i] >> 4) & 0xf;
234 
235         if (i != 15) {
236             rem = (unsigned char) zl & 0xf;
237             zl = (zh << 60) | (zl >> 4);
238             zh = (zh >> 4);
239             zh ^= (uint64_t) last4[rem] << 48;
240             zh ^= ctx->HH[lo];
241             zl ^= ctx->HL[lo];
242 
243         }
244 
245         rem = (unsigned char) zl & 0xf;
246         zl = (zh << 60) | (zl >> 4);
247         zh = (zh >> 4);
248         zh ^= (uint64_t) last4[rem] << 48;
249         zh ^= ctx->HH[hi];
250         zl ^= ctx->HL[hi];
251     }
252 
253     MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
254     MBEDTLS_PUT_UINT32_BE(zh, output, 4);
255     MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
256     MBEDTLS_PUT_UINT32_BE(zl, output, 12);
257 }
258 
mbedtls_gcm_starts(mbedtls_gcm_context * ctx,int mode,const unsigned char * iv,size_t iv_len)259 int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
260                        int mode,
261                        const unsigned char *iv, size_t iv_len)
262 {
263     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
264     unsigned char work_buf[16];
265     const unsigned char *p;
266     size_t use_len, olen = 0;
267     uint64_t iv_bits;
268 
269     /* IV is limited to 2^64 bits, so 2^61 bytes */
270     /* IV is not allowed to be zero length */
271     if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
272         return MBEDTLS_ERR_GCM_BAD_INPUT;
273     }
274 
275     memset(ctx->y, 0x00, sizeof(ctx->y));
276     memset(ctx->buf, 0x00, sizeof(ctx->buf));
277 
278     ctx->mode = mode;
279     ctx->len = 0;
280     ctx->add_len = 0;
281 
282     if (iv_len == 12) {
283         memcpy(ctx->y, iv, iv_len);
284         ctx->y[15] = 1;
285     } else {
286         memset(work_buf, 0x00, 16);
287         iv_bits = (uint64_t) iv_len * 8;
288         MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
289 
290         p = iv;
291         while (iv_len > 0) {
292             use_len = (iv_len < 16) ? iv_len : 16;
293 
294             mbedtls_xor(ctx->y, ctx->y, p, use_len);
295 
296             gcm_mult(ctx, ctx->y, ctx->y);
297 
298             iv_len -= use_len;
299             p += use_len;
300         }
301 
302         mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
303 
304         gcm_mult(ctx, ctx->y, ctx->y);
305     }
306 
307     if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
308                                      ctx->base_ectr, &olen)) != 0) {
309         return ret;
310     }
311 
312     return 0;
313 }
314 
315 /**
316  * mbedtls_gcm_context::buf contains the partial state of the computation of
317  * the authentication tag.
318  * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
319  * different stages of the computation:
320  *     * len == 0 && add_len == 0:      initial state
321  *     * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
322  *                                      a partial block of AD that has been
323  *                                      xored in but not yet multiplied in.
324  *     * len == 0 && add_len % 16 == 0: the authentication tag is correct if
325  *                                      the data ends now.
326  *     * len % 16 != 0:                 the first `len % 16` bytes have
327  *                                      a partial block of ciphertext that has
328  *                                      been xored in but not yet multiplied in.
329  *     * len > 0 && len % 16 == 0:      the authentication tag is correct if
330  *                                      the data ends now.
331  */
mbedtls_gcm_update_ad(mbedtls_gcm_context * ctx,const unsigned char * add,size_t add_len)332 int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
333                           const unsigned char *add, size_t add_len)
334 {
335     const unsigned char *p;
336     size_t use_len, offset;
337 
338     /* IV is limited to 2^64 bits, so 2^61 bytes */
339     if ((uint64_t) add_len >> 61 != 0) {
340         return MBEDTLS_ERR_GCM_BAD_INPUT;
341     }
342 
343     offset = ctx->add_len % 16;
344     p = add;
345 
346     if (offset != 0) {
347         use_len = 16 - offset;
348         if (use_len > add_len) {
349             use_len = add_len;
350         }
351 
352         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
353 
354         if (offset + use_len == 16) {
355             gcm_mult(ctx, ctx->buf, ctx->buf);
356         }
357 
358         ctx->add_len += use_len;
359         add_len -= use_len;
360         p += use_len;
361     }
362 
363     ctx->add_len += add_len;
364 
365     while (add_len >= 16) {
366         mbedtls_xor(ctx->buf, ctx->buf, p, 16);
367 
368         gcm_mult(ctx, ctx->buf, ctx->buf);
369 
370         add_len -= 16;
371         p += 16;
372     }
373 
374     if (add_len > 0) {
375         mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
376     }
377 
378     return 0;
379 }
380 
381 /* Increment the counter. */
gcm_incr(unsigned char y[16])382 static void gcm_incr(unsigned char y[16])
383 {
384     size_t i;
385     for (i = 16; i > 12; i--) {
386         if (++y[i - 1] != 0) {
387             break;
388         }
389     }
390 }
391 
392 /* Calculate and apply the encryption mask. Process use_len bytes of data,
393  * 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)394 static int gcm_mask(mbedtls_gcm_context *ctx,
395                     unsigned char ectr[16],
396                     size_t offset, size_t use_len,
397                     const unsigned char *input,
398                     unsigned char *output)
399 {
400     size_t olen = 0;
401     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
402 
403     if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr,
404                                      &olen)) != 0) {
405         mbedtls_platform_zeroize(ectr, 16);
406         return ret;
407     }
408 
409     if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
410         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
411     }
412     mbedtls_xor(output, ectr + offset, input, use_len);
413     if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
414         mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
415     }
416 
417     return 0;
418 }
419 
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)420 int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
421                        const unsigned char *input, size_t input_length,
422                        unsigned char *output, size_t output_size,
423                        size_t *output_length)
424 {
425     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426     const unsigned char *p = input;
427     unsigned char *out_p = output;
428     size_t offset;
429     unsigned char ectr[16] = { 0 };
430 
431     if (output_size < input_length) {
432         return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
433     }
434     *output_length = input_length;
435 
436     /* Exit early if input_length==0 so that we don't do any pointer arithmetic
437      * on a potentially null pointer.
438      * Returning early also means that the last partial block of AD remains
439      * untouched for mbedtls_gcm_finish */
440     if (input_length == 0) {
441         return 0;
442     }
443 
444     if (output > input && (size_t) (output - input) < input_length) {
445         return MBEDTLS_ERR_GCM_BAD_INPUT;
446     }
447 
448     /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
449      * Also check for possible overflow */
450     if (ctx->len + input_length < ctx->len ||
451         (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
452         return MBEDTLS_ERR_GCM_BAD_INPUT;
453     }
454 
455     if (ctx->len == 0 && ctx->add_len % 16 != 0) {
456         gcm_mult(ctx, ctx->buf, ctx->buf);
457     }
458 
459     offset = ctx->len % 16;
460     if (offset != 0) {
461         size_t use_len = 16 - offset;
462         if (use_len > input_length) {
463             use_len = input_length;
464         }
465 
466         if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
467             return ret;
468         }
469 
470         if (offset + use_len == 16) {
471             gcm_mult(ctx, ctx->buf, ctx->buf);
472         }
473 
474         ctx->len += use_len;
475         input_length -= use_len;
476         p += use_len;
477         out_p += use_len;
478     }
479 
480     ctx->len += input_length;
481 
482     while (input_length >= 16) {
483         gcm_incr(ctx->y);
484         if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
485             return ret;
486         }
487 
488         gcm_mult(ctx, ctx->buf, ctx->buf);
489 
490         input_length -= 16;
491         p += 16;
492         out_p += 16;
493     }
494 
495     if (input_length > 0) {
496         gcm_incr(ctx->y);
497         if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
498             return ret;
499         }
500     }
501 
502     mbedtls_platform_zeroize(ectr, sizeof(ectr));
503     return 0;
504 }
505 
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)506 int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
507                        unsigned char *output, size_t output_size,
508                        size_t *output_length,
509                        unsigned char *tag, size_t tag_len)
510 {
511     unsigned char work_buf[16];
512     uint64_t orig_len;
513     uint64_t orig_add_len;
514 
515     /* We never pass any output in finish(). The output parameter exists only
516      * for the sake of alternative implementations. */
517     (void) output;
518     (void) output_size;
519     *output_length = 0;
520 
521     orig_len = ctx->len * 8;
522     orig_add_len = ctx->add_len * 8;
523 
524     if (ctx->len == 0 && ctx->add_len % 16 != 0) {
525         gcm_mult(ctx, ctx->buf, ctx->buf);
526     }
527 
528     if (tag_len > 16 || tag_len < 4) {
529         return MBEDTLS_ERR_GCM_BAD_INPUT;
530     }
531 
532     if (ctx->len % 16 != 0) {
533         gcm_mult(ctx, ctx->buf, ctx->buf);
534     }
535 
536     memcpy(tag, ctx->base_ectr, tag_len);
537 
538     if (orig_len || orig_add_len) {
539         memset(work_buf, 0x00, 16);
540 
541         MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
542         MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
543         MBEDTLS_PUT_UINT32_BE((orig_len     >> 32), work_buf, 8);
544         MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
545 
546         mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
547 
548         gcm_mult(ctx, ctx->buf, ctx->buf);
549 
550         mbedtls_xor(tag, tag, ctx->buf, tag_len);
551     }
552 
553     return 0;
554 }
555 
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)556 int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
557                               int mode,
558                               size_t length,
559                               const unsigned char *iv,
560                               size_t iv_len,
561                               const unsigned char *add,
562                               size_t add_len,
563                               const unsigned char *input,
564                               unsigned char *output,
565                               size_t tag_len,
566                               unsigned char *tag)
567 {
568     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
569     size_t olen;
570 
571     if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
572         return ret;
573     }
574 
575     if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
576         return ret;
577     }
578 
579     if ((ret = mbedtls_gcm_update(ctx, input, length,
580                                   output, length, &olen)) != 0) {
581         return ret;
582     }
583 
584     if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
585         return ret;
586     }
587 
588     return 0;
589 }
590 
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)591 int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
592                              size_t length,
593                              const unsigned char *iv,
594                              size_t iv_len,
595                              const unsigned char *add,
596                              size_t add_len,
597                              const unsigned char *tag,
598                              size_t tag_len,
599                              const unsigned char *input,
600                              unsigned char *output)
601 {
602     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
603     unsigned char check_tag[16];
604     size_t i;
605     int diff;
606 
607     if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
608                                          iv, iv_len, add, add_len,
609                                          input, output, tag_len, check_tag)) != 0) {
610         return ret;
611     }
612 
613     /* Check tag in "constant-time" */
614     for (diff = 0, i = 0; i < tag_len; i++) {
615         diff |= tag[i] ^ check_tag[i];
616     }
617 
618     if (diff != 0) {
619         mbedtls_platform_zeroize(output, length);
620         return MBEDTLS_ERR_GCM_AUTH_FAILED;
621     }
622 
623     return 0;
624 }
625 
mbedtls_gcm_free(mbedtls_gcm_context * ctx)626 void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
627 {
628     if (ctx == NULL) {
629         return;
630     }
631     mbedtls_cipher_free(&ctx->cipher_ctx);
632     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
633 }
634 
635 #endif /* !MBEDTLS_GCM_ALT */
636 
637 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
638 /*
639  * AES-GCM test vectors from:
640  *
641  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
642  */
643 #define MAX_TESTS   6
644 
645 static const int key_index_test_data[MAX_TESTS] =
646 { 0, 0, 1, 1, 1, 1 };
647 
648 static const unsigned char key_test_data[MAX_TESTS][32] =
649 {
650     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
654     { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
655       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
656       0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
657       0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
658 };
659 
660 static const size_t iv_len_test_data[MAX_TESTS] =
661 { 12, 12, 12, 12, 8, 60 };
662 
663 static const int iv_index_test_data[MAX_TESTS] =
664 { 0, 0, 1, 1, 1, 2 };
665 
666 static const unsigned char iv_test_data[MAX_TESTS][64] =
667 {
668     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669       0x00, 0x00, 0x00, 0x00 },
670     { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
671       0xde, 0xca, 0xf8, 0x88 },
672     { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
673       0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
674       0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
675       0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
676       0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
677       0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
678       0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
679       0xa6, 0x37, 0xb3, 0x9b },
680 };
681 
682 static const size_t add_len_test_data[MAX_TESTS] =
683 { 0, 0, 0, 20, 20, 20 };
684 
685 static const int add_index_test_data[MAX_TESTS] =
686 { 0, 0, 0, 1, 1, 1 };
687 
688 static const unsigned char additional_test_data[MAX_TESTS][64] =
689 {
690     { 0x00 },
691     { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
692       0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
693       0xab, 0xad, 0xda, 0xd2 },
694 };
695 
696 static const size_t pt_len_test_data[MAX_TESTS] =
697 { 0, 16, 64, 60, 60, 60 };
698 
699 static const int pt_index_test_data[MAX_TESTS] =
700 { 0, 0, 1, 1, 1, 1 };
701 
702 static const unsigned char pt_test_data[MAX_TESTS][64] =
703 {
704     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
706     { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
707       0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
708       0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
709       0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
710       0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
711       0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
712       0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
713       0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
714 };
715 
716 static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
717 {
718     { 0x00 },
719     { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
720       0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
721     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
722       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
723       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
724       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
725       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
726       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
727       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
728       0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
729     { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
730       0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
731       0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
732       0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
733       0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
734       0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
735       0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
736       0x3d, 0x58, 0xe0, 0x91 },
737     { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
738       0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
739       0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
740       0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
741       0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
742       0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
743       0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
744       0xc2, 0x3f, 0x45, 0x98 },
745     { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
746       0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
747       0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
748       0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
749       0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
750       0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
751       0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
752       0x4c, 0x34, 0xae, 0xe5 },
753     { 0x00 },
754     { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
755       0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
756     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
757       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
758       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
759       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
760       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
761       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
762       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
763       0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
764     { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
765       0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
766       0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
767       0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
768       0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
769       0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
770       0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
771       0xcc, 0xda, 0x27, 0x10 },
772     { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
773       0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
774       0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
775       0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
776       0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
777       0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
778       0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
779       0xa0, 0xf0, 0x62, 0xf7 },
780     { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
781       0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
782       0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
783       0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
784       0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
785       0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
786       0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
787       0xe9, 0xb7, 0x37, 0x3b },
788     { 0x00 },
789     { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
790       0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
791     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
792       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
793       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
794       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
795       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
796       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
797       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
798       0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
799     { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
800       0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
801       0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
802       0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
803       0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
804       0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
805       0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
806       0xbc, 0xc9, 0xf6, 0x62 },
807     { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
808       0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
809       0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
810       0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
811       0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
812       0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
813       0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
814       0xf4, 0x7c, 0x9b, 0x1f },
815     { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
816       0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
817       0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
818       0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
819       0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
820       0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
821       0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
822       0x44, 0xae, 0x7e, 0x3f },
823 };
824 
825 static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
826 {
827     { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
828       0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
829     { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
830       0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
831     { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
832       0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
833     { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
834       0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
835     { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
836       0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
837     { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
838       0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
839     { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
840       0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
841     { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
842       0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
843     { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
844       0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
845     { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
846       0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
847     { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
848       0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
849     { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
850       0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
851     { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
852       0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
853     { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
854       0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
855     { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
856       0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
857     { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
858       0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
859     { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
860       0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
861     { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
862       0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
863 };
864 
mbedtls_gcm_self_test(int verbose)865 int mbedtls_gcm_self_test(int verbose)
866 {
867     mbedtls_gcm_context ctx;
868     unsigned char buf[64];
869     unsigned char tag_buf[16];
870     int i, j, ret;
871     mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
872     size_t olen;
873 
874     if (verbose != 0) {
875 #if defined(MBEDTLS_GCM_ALT)
876         mbedtls_printf("  GCM note: alternative implementation.\n");
877 #else /* MBEDTLS_GCM_ALT */
878 #if defined(MBEDTLS_AESNI_HAVE_CODE)
879         if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
880             mbedtls_printf("  GCM note: using AESNI.\n");
881         } else
882 #endif
883         mbedtls_printf("  GCM note: built-in implementation.\n");
884 #endif /* MBEDTLS_GCM_ALT */
885     }
886 
887     for (j = 0; j < 3; j++) {
888         int key_len = 128 + 64 * j;
889 
890         for (i = 0; i < MAX_TESTS; i++) {
891             mbedtls_gcm_init(&ctx);
892 
893             if (verbose != 0) {
894                 mbedtls_printf("  AES-GCM-%3d #%d (%s): ",
895                                key_len, i, "enc");
896             }
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