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