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