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