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 #if defined(MBEDTLS_BLOCK_CIPHER_C)
29 #include "block_cipher_internal.h"
30 #endif
31
32 #include <string.h>
33
34 #if defined(MBEDTLS_AESNI_C)
35 #include "aesni.h"
36 #endif
37
38 #if defined(MBEDTLS_AESCE_C)
39 #include "aesce.h"
40 #endif
41
42 #if !defined(MBEDTLS_GCM_ALT)
43
44 /* Used to select the acceleration mechanism */
45 #define MBEDTLS_GCM_ACC_SMALLTABLE 0
46 #define MBEDTLS_GCM_ACC_LARGETABLE 1
47 #define MBEDTLS_GCM_ACC_AESNI 2
48 #define MBEDTLS_GCM_ACC_AESCE 3
49
50 /*
51 * Initialize a context
52 */
mbedtls_gcm_init(mbedtls_gcm_context * ctx)53 void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
54 {
55 memset(ctx, 0, sizeof(mbedtls_gcm_context));
56 }
57
gcm_set_acceleration(mbedtls_gcm_context * ctx)58 static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
59 {
60 #if defined(MBEDTLS_GCM_LARGE_TABLE)
61 ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
62 #else
63 ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
64 #endif
65
66 #if defined(MBEDTLS_AESNI_HAVE_CODE)
67 /* With CLMUL support, we need only h, not the rest of the table */
68 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
69 ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
70 }
71 #endif
72
73 #if defined(MBEDTLS_AESCE_HAVE_CODE)
74 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
75 ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
76 }
77 #endif
78 }
79
gcm_gen_table_rightshift(uint64_t dst[2],const uint64_t src[2])80 static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
81 {
82 uint8_t *u8Dst = (uint8_t *) dst;
83 uint8_t *u8Src = (uint8_t *) src;
84
85 MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
86 u8Dst[8] |= (u8Src[7] & 0x01) << 7;
87 MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
88 u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
89 }
90
91 /*
92 * Precompute small multiples of H, that is set
93 * HH[i] || HL[i] = H times i,
94 * where i is seen as a field element as in [MGV], ie high-order bits
95 * correspond to low powers of P. The result is stored in the same way, that
96 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
97 * corresponds to P^127.
98 */
gcm_gen_table(mbedtls_gcm_context * ctx)99 static int gcm_gen_table(mbedtls_gcm_context *ctx)
100 {
101 int ret, i, j;
102 uint64_t u64h[2] = { 0 };
103 uint8_t *h = (uint8_t *) u64h;
104
105 #if defined(MBEDTLS_BLOCK_CIPHER_C)
106 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
107 #else
108 size_t olen = 0;
109 ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
110 #endif
111 if (ret != 0) {
112 return ret;
113 }
114
115 gcm_set_acceleration(ctx);
116
117 /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
118 ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
119 ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
120
121 switch (ctx->acceleration) {
122 #if defined(MBEDTLS_AESNI_HAVE_CODE)
123 case MBEDTLS_GCM_ACC_AESNI:
124 return 0;
125 #endif
126
127 #if defined(MBEDTLS_AESCE_HAVE_CODE)
128 case MBEDTLS_GCM_ACC_AESCE:
129 return 0;
130 #endif
131
132 default:
133 /* 0 corresponds to 0 in GF(2^128) */
134 ctx->H[0][0] = 0;
135 ctx->H[0][1] = 0;
136
137 for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
138 gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
139 }
140
141 #if !defined(MBEDTLS_GCM_LARGE_TABLE)
142 /* pack elements of H as 64-bits ints, big-endian */
143 for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
144 MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
145 MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
146 }
147 #endif
148
149 for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
150 for (j = 1; j < i; j++) {
151 mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
152 (unsigned char *) ctx->H[i],
153 (unsigned char *) ctx->H[j],
154 16);
155 }
156 }
157 }
158
159 return 0;
160 }
161
mbedtls_gcm_setkey(mbedtls_gcm_context * ctx,mbedtls_cipher_id_t cipher,const unsigned char * key,unsigned int keybits)162 int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
163 mbedtls_cipher_id_t cipher,
164 const unsigned char *key,
165 unsigned int keybits)
166 {
167 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
169 if (keybits != 128 && keybits != 192 && keybits != 256) {
170 return MBEDTLS_ERR_GCM_BAD_INPUT;
171 }
172
173 #if defined(MBEDTLS_BLOCK_CIPHER_C)
174 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
175
176 if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
177 return ret;
178 }
179
180 if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
181 return ret;
182 }
183 #else
184 const mbedtls_cipher_info_t *cipher_info;
185
186 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
187 MBEDTLS_MODE_ECB);
188 if (cipher_info == NULL) {
189 return MBEDTLS_ERR_GCM_BAD_INPUT;
190 }
191
192 if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
193 return MBEDTLS_ERR_GCM_BAD_INPUT;
194 }
195
196 mbedtls_cipher_free(&ctx->cipher_ctx);
197
198 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
199 return ret;
200 }
201
202 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
203 MBEDTLS_ENCRYPT)) != 0) {
204 return ret;
205 }
206 #endif
207
208 if ((ret = gcm_gen_table(ctx)) != 0) {
209 return ret;
210 }
211
212 return 0;
213 }
214
215 #if defined(MBEDTLS_GCM_LARGE_TABLE)
216 static const uint16_t last8[256] = {
217 0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05,
218 0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b,
219 0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19,
220 0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17,
221 0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d,
222 0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33,
223 0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21,
224 0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f,
225 0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75,
226 0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b,
227 0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69,
228 0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67,
229 0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d,
230 0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43,
231 0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51,
232 0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f,
233 0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4,
234 0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea,
235 0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8,
236 0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6,
237 0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc,
238 0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2,
239 0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0,
240 0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece,
241 0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94,
242 0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a,
243 0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88,
244 0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86,
245 0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac,
246 0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2,
247 0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0,
248 0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe
249 };
250
gcm_mult_largetable(uint8_t * output,const uint8_t * x,uint64_t H[256][2])251 static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2])
252 {
253 int i;
254 uint64_t u64z[2];
255 uint16_t *u16z = (uint16_t *) u64z;
256 uint8_t *u8z = (uint8_t *) u64z;
257 uint8_t rem;
258
259 u64z[0] = 0;
260 u64z[1] = 0;
261
262 if (MBEDTLS_IS_BIG_ENDIAN) {
263 for (i = 15; i > 0; i--) {
264 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
265 rem = u8z[15];
266
267 u64z[1] >>= 8;
268 u8z[8] = u8z[7];
269 u64z[0] >>= 8;
270
271 u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
272 }
273 } else {
274 for (i = 15; i > 0; i--) {
275 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
276 rem = u8z[15];
277
278 u64z[1] <<= 8;
279 u8z[8] = u8z[7];
280 u64z[0] <<= 8;
281
282 u16z[0] ^= last8[rem];
283 }
284 }
285
286 mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
287 }
288 #else
289 /*
290 * Shoup's method for multiplication use this table with
291 * last4[x] = x times P^128
292 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
293 */
294 static const uint16_t last4[16] =
295 {
296 0x0000, 0x1c20, 0x3840, 0x2460,
297 0x7080, 0x6ca0, 0x48c0, 0x54e0,
298 0xe100, 0xfd20, 0xd940, 0xc560,
299 0x9180, 0x8da0, 0xa9c0, 0xb5e0
300 };
301
gcm_mult_smalltable(uint8_t * output,const uint8_t * x,uint64_t H[16][2])302 static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2])
303 {
304 int i = 0;
305 unsigned char lo, hi, rem;
306 uint64_t u64z[2];
307 const uint64_t *pu64z = NULL;
308 uint8_t *u8z = (uint8_t *) u64z;
309
310 lo = x[15] & 0xf;
311 hi = (x[15] >> 4) & 0xf;
312
313 pu64z = H[lo];
314
315 rem = (unsigned char) pu64z[1] & 0xf;
316 u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
317 u64z[0] = (pu64z[0] >> 4);
318 u64z[0] ^= (uint64_t) last4[rem] << 48;
319 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
320
321 for (i = 14; i >= 0; i--) {
322 lo = x[i] & 0xf;
323 hi = (x[i] >> 4) & 0xf;
324
325 rem = (unsigned char) u64z[1] & 0xf;
326 u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
327 u64z[0] = (u64z[0] >> 4);
328 u64z[0] ^= (uint64_t) last4[rem] << 48;
329 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
330
331 rem = (unsigned char) u64z[1] & 0xf;
332 u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
333 u64z[0] = (u64z[0] >> 4);
334 u64z[0] ^= (uint64_t) last4[rem] << 48;
335 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
336 }
337
338 MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
339 MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
340 }
341 #endif
342
343 /*
344 * Sets output to x times H using the precomputed tables.
345 * x and output are seen as elements of GF(2^128) as in [MGV].
346 */
gcm_mult(mbedtls_gcm_context * ctx,const unsigned char x[16],unsigned char output[16])347 static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
348 unsigned char output[16])
349 {
350 switch (ctx->acceleration) {
351 #if defined(MBEDTLS_AESNI_HAVE_CODE)
352 case MBEDTLS_GCM_ACC_AESNI:
353 mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
354 break;
355 #endif
356
357 #if defined(MBEDTLS_AESCE_HAVE_CODE)
358 case MBEDTLS_GCM_ACC_AESCE:
359 mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
360 break;
361 #endif
362
363 #if defined(MBEDTLS_GCM_LARGE_TABLE)
364 case MBEDTLS_GCM_ACC_LARGETABLE:
365 gcm_mult_largetable(output, x, ctx->H);
366 break;
367 #else
368 case MBEDTLS_GCM_ACC_SMALLTABLE:
369 gcm_mult_smalltable(output, x, ctx->H);
370 break;
371 #endif
372 }
373
374 return;
375 }
376
mbedtls_gcm_starts(mbedtls_gcm_context * ctx,int mode,const unsigned char * iv,size_t iv_len)377 int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
378 int mode,
379 const unsigned char *iv, size_t iv_len)
380 {
381 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
382 unsigned char work_buf[16];
383 const unsigned char *p;
384 size_t use_len;
385 uint64_t iv_bits;
386 #if !defined(MBEDTLS_BLOCK_CIPHER_C)
387 size_t olen = 0;
388 #endif
389
390 /* IV is limited to 2^64 bits, so 2^61 bytes */
391 /* IV is not allowed to be zero length */
392 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
393 return MBEDTLS_ERR_GCM_BAD_INPUT;
394 }
395
396 memset(ctx->y, 0x00, sizeof(ctx->y));
397 memset(ctx->buf, 0x00, sizeof(ctx->buf));
398
399 ctx->mode = mode;
400 ctx->len = 0;
401 ctx->add_len = 0;
402
403 if (iv_len == 12) {
404 memcpy(ctx->y, iv, iv_len);
405 ctx->y[15] = 1;
406 } else {
407 memset(work_buf, 0x00, 16);
408 iv_bits = (uint64_t) iv_len * 8;
409 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
410
411 p = iv;
412 while (iv_len > 0) {
413 use_len = (iv_len < 16) ? iv_len : 16;
414
415 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
416 #pragma GCC diagnostic push
417 #pragma GCC diagnostic warning "-Wstringop-overflow=0"
418 #endif
419
420 mbedtls_xor(ctx->y, ctx->y, p, use_len);
421
422 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
423 #pragma GCC diagnostic pop
424 #endif
425
426 gcm_mult(ctx, ctx->y, ctx->y);
427
428 iv_len -= use_len;
429 p += use_len;
430 }
431
432 mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
433
434 gcm_mult(ctx, ctx->y, ctx->y);
435 }
436
437
438 #if defined(MBEDTLS_BLOCK_CIPHER_C)
439 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
440 #else
441 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
442 #endif
443 if (ret != 0) {
444 return ret;
445 }
446
447 return 0;
448 }
449
450 /**
451 * mbedtls_gcm_context::buf contains the partial state of the computation of
452 * the authentication tag.
453 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
454 * different stages of the computation:
455 * * len == 0 && add_len == 0: initial state
456 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
457 * a partial block of AD that has been
458 * xored in but not yet multiplied in.
459 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
460 * the data ends now.
461 * * len % 16 != 0: the first `len % 16` bytes have
462 * a partial block of ciphertext that has
463 * been xored in but not yet multiplied in.
464 * * len > 0 && len % 16 == 0: the authentication tag is correct if
465 * the data ends now.
466 */
mbedtls_gcm_update_ad(mbedtls_gcm_context * ctx,const unsigned char * add,size_t add_len)467 int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
468 const unsigned char *add, size_t add_len)
469 {
470 const unsigned char *p;
471 size_t use_len, offset;
472 uint64_t new_add_len;
473
474 /* AD is limited to 2^64 bits, ie 2^61 bytes
475 * Also check for possible overflow */
476 #if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
477 if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
478 return MBEDTLS_ERR_GCM_BAD_INPUT;
479 }
480 #endif
481 new_add_len = ctx->add_len + (uint64_t) add_len;
482 if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
483 return MBEDTLS_ERR_GCM_BAD_INPUT;
484 }
485
486 offset = ctx->add_len % 16;
487 p = add;
488
489 if (offset != 0) {
490 use_len = 16 - offset;
491 if (use_len > add_len) {
492 use_len = add_len;
493 }
494
495 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
496
497 if (offset + use_len == 16) {
498 gcm_mult(ctx, ctx->buf, ctx->buf);
499 }
500
501 ctx->add_len += use_len;
502 add_len -= use_len;
503 p += use_len;
504 }
505
506 ctx->add_len += add_len;
507
508 while (add_len >= 16) {
509 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
510
511 gcm_mult(ctx, ctx->buf, ctx->buf);
512
513 add_len -= 16;
514 p += 16;
515 }
516
517 if (add_len > 0) {
518 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
519 }
520
521 return 0;
522 }
523
524 /* Increment the counter. */
gcm_incr(unsigned char y[16])525 static void gcm_incr(unsigned char y[16])
526 {
527 uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
528 x++;
529 MBEDTLS_PUT_UINT32_BE(x, y, 12);
530 }
531
532 /* Calculate and apply the encryption mask. Process use_len bytes of data,
533 * 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)534 static int gcm_mask(mbedtls_gcm_context *ctx,
535 unsigned char ectr[16],
536 size_t offset, size_t use_len,
537 const unsigned char *input,
538 unsigned char *output)
539 {
540 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
541
542 #if defined(MBEDTLS_BLOCK_CIPHER_C)
543 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
544 #else
545 size_t olen = 0;
546 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
547 #endif
548 if (ret != 0) {
549 mbedtls_platform_zeroize(ectr, 16);
550 return ret;
551 }
552
553 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
554 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
555 }
556 mbedtls_xor(output, ectr + offset, input, use_len);
557 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
558 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
559 }
560
561 return 0;
562 }
563
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)564 int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
565 const unsigned char *input, size_t input_length,
566 unsigned char *output, size_t output_size,
567 size_t *output_length)
568 {
569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
570 const unsigned char *p = input;
571 unsigned char *out_p = output;
572 size_t offset;
573 unsigned char ectr[16] = { 0 };
574
575 if (output_size < input_length) {
576 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
577 }
578 *output_length = input_length;
579
580 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
581 * on a potentially null pointer.
582 * Returning early also means that the last partial block of AD remains
583 * untouched for mbedtls_gcm_finish */
584 if (input_length == 0) {
585 return 0;
586 }
587
588 if (output > input && (size_t) (output - input) < input_length) {
589 return MBEDTLS_ERR_GCM_BAD_INPUT;
590 }
591
592 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
593 * Also check for possible overflow */
594 if (ctx->len + input_length < ctx->len ||
595 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
596 return MBEDTLS_ERR_GCM_BAD_INPUT;
597 }
598
599 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
600 gcm_mult(ctx, ctx->buf, ctx->buf);
601 }
602
603 offset = ctx->len % 16;
604 if (offset != 0) {
605 size_t use_len = 16 - offset;
606 if (use_len > input_length) {
607 use_len = input_length;
608 }
609
610 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
611 return ret;
612 }
613
614 if (offset + use_len == 16) {
615 gcm_mult(ctx, ctx->buf, ctx->buf);
616 }
617
618 ctx->len += use_len;
619 input_length -= use_len;
620 p += use_len;
621 out_p += use_len;
622 }
623
624 ctx->len += input_length;
625
626 while (input_length >= 16) {
627 gcm_incr(ctx->y);
628 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
629 return ret;
630 }
631
632 gcm_mult(ctx, ctx->buf, ctx->buf);
633
634 input_length -= 16;
635 p += 16;
636 out_p += 16;
637 }
638
639 if (input_length > 0) {
640 gcm_incr(ctx->y);
641 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
642 return ret;
643 }
644 }
645
646 mbedtls_platform_zeroize(ectr, sizeof(ectr));
647 return 0;
648 }
649
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)650 int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
651 unsigned char *output, size_t output_size,
652 size_t *output_length,
653 unsigned char *tag, size_t tag_len)
654 {
655 unsigned char work_buf[16];
656 uint64_t orig_len;
657 uint64_t orig_add_len;
658
659 /* We never pass any output in finish(). The output parameter exists only
660 * for the sake of alternative implementations. */
661 (void) output;
662 (void) output_size;
663 *output_length = 0;
664
665 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
666 * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
667 * the two multiplications would overflow. */
668 orig_len = ctx->len * 8;
669 orig_add_len = ctx->add_len * 8;
670
671 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
672 gcm_mult(ctx, ctx->buf, ctx->buf);
673 }
674
675 if (tag_len > 16 || tag_len < 4) {
676 return MBEDTLS_ERR_GCM_BAD_INPUT;
677 }
678
679 if (ctx->len % 16 != 0) {
680 gcm_mult(ctx, ctx->buf, ctx->buf);
681 }
682
683 memcpy(tag, ctx->base_ectr, tag_len);
684
685 if (orig_len || orig_add_len) {
686 memset(work_buf, 0x00, 16);
687
688 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
689 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
690 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
691 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
692
693 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
694
695 gcm_mult(ctx, ctx->buf, ctx->buf);
696
697 mbedtls_xor(tag, tag, ctx->buf, tag_len);
698 }
699
700 return 0;
701 }
702
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)703 int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
704 int mode,
705 size_t length,
706 const unsigned char *iv,
707 size_t iv_len,
708 const unsigned char *add,
709 size_t add_len,
710 const unsigned char *input,
711 unsigned char *output,
712 size_t tag_len,
713 unsigned char *tag)
714 {
715 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
716 size_t olen;
717
718 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
719 return ret;
720 }
721
722 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
723 return ret;
724 }
725
726 if ((ret = mbedtls_gcm_update(ctx, input, length,
727 output, length, &olen)) != 0) {
728 return ret;
729 }
730
731 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
732 return ret;
733 }
734
735 return 0;
736 }
737
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)738 int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
739 size_t length,
740 const unsigned char *iv,
741 size_t iv_len,
742 const unsigned char *add,
743 size_t add_len,
744 const unsigned char *tag,
745 size_t tag_len,
746 const unsigned char *input,
747 unsigned char *output)
748 {
749 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
750 unsigned char check_tag[16];
751 int diff;
752
753 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
754 iv, iv_len, add, add_len,
755 input, output, tag_len, check_tag)) != 0) {
756 return ret;
757 }
758
759 /* Check tag in "constant-time" */
760 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
761
762 if (diff != 0) {
763 mbedtls_platform_zeroize(output, length);
764 return MBEDTLS_ERR_GCM_AUTH_FAILED;
765 }
766
767 return 0;
768 }
769
mbedtls_gcm_free(mbedtls_gcm_context * ctx)770 void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
771 {
772 if (ctx == NULL) {
773 return;
774 }
775 #if defined(MBEDTLS_BLOCK_CIPHER_C)
776 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
777 #else
778 mbedtls_cipher_free(&ctx->cipher_ctx);
779 #endif
780 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
781 }
782
783 #endif /* !MBEDTLS_GCM_ALT */
784
785 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
786 /*
787 * AES-GCM test vectors from:
788 *
789 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
790 */
791 #define MAX_TESTS 6
792
793 static const int key_index_test_data[MAX_TESTS] =
794 { 0, 0, 1, 1, 1, 1 };
795
796 static const unsigned char key_test_data[][32] =
797 {
798 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
802 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
803 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
804 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
805 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
806 };
807
808 static const size_t iv_len_test_data[MAX_TESTS] =
809 { 12, 12, 12, 12, 8, 60 };
810
811 static const int iv_index_test_data[MAX_TESTS] =
812 { 0, 0, 1, 1, 1, 2 };
813
814 static const unsigned char iv_test_data[][64] =
815 {
816 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817 0x00, 0x00, 0x00, 0x00 },
818 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
819 0xde, 0xca, 0xf8, 0x88 },
820 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
821 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
822 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
823 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
824 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
825 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
826 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
827 0xa6, 0x37, 0xb3, 0x9b },
828 };
829
830 static const size_t add_len_test_data[MAX_TESTS] =
831 { 0, 0, 0, 20, 20, 20 };
832
833 static const int add_index_test_data[MAX_TESTS] =
834 { 0, 0, 0, 1, 1, 1 };
835
836 static const unsigned char additional_test_data[][64] =
837 {
838 { 0x00 },
839 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
840 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
841 0xab, 0xad, 0xda, 0xd2 },
842 };
843
844 static const size_t pt_len_test_data[MAX_TESTS] =
845 { 0, 16, 64, 60, 60, 60 };
846
847 static const int pt_index_test_data[MAX_TESTS] =
848 { 0, 0, 1, 1, 1, 1 };
849
850 static const unsigned char pt_test_data[][64] =
851 {
852 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
854 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
855 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
856 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
857 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
858 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
859 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
860 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
861 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
862 };
863
864 static const unsigned char ct_test_data[][64] =
865 {
866 { 0x00 },
867 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
868 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
869 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
870 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
871 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
872 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
873 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
874 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
875 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
876 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
877 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
878 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
879 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
880 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
881 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
882 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
883 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
884 0x3d, 0x58, 0xe0, 0x91 },
885 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
886 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
887 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
888 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
889 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
890 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
891 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
892 0xc2, 0x3f, 0x45, 0x98 },
893 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
894 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
895 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
896 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
897 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
898 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
899 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
900 0x4c, 0x34, 0xae, 0xe5 },
901 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
902 { 0x00 },
903 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
904 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
905 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
906 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
907 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
908 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
909 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
910 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
911 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
912 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
913 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
914 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
915 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
916 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
917 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
918 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
919 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
920 0xcc, 0xda, 0x27, 0x10 },
921 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
922 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
923 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
924 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
925 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
926 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
927 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
928 0xa0, 0xf0, 0x62, 0xf7 },
929 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
930 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
931 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
932 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
933 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
934 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
935 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
936 0xe9, 0xb7, 0x37, 0x3b },
937 { 0x00 },
938 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
939 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
940 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
941 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
942 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
943 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
944 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
945 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
946 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
947 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
948 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
949 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
950 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
951 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
952 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
953 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
954 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
955 0xbc, 0xc9, 0xf6, 0x62 },
956 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
957 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
958 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
959 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
960 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
961 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
962 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
963 0xf4, 0x7c, 0x9b, 0x1f },
964 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
965 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
966 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
967 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
968 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
969 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
970 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
971 0x44, 0xae, 0x7e, 0x3f },
972 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
973 };
974
975 static const unsigned char tag_test_data[][16] =
976 {
977 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
978 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
979 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
980 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
981 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
982 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
983 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
984 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
985 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
986 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
987 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
988 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
989 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
990 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
991 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
992 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
993 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
994 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
995 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
996 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
997 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
998 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
999 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
1000 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
1001 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
1002 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
1003 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
1004 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
1005 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
1006 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
1007 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
1008 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
1009 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
1010 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
1011 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
1012 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
1013 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
1014 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1015 };
1016
mbedtls_gcm_self_test(int verbose)1017 int mbedtls_gcm_self_test(int verbose)
1018 {
1019 mbedtls_gcm_context ctx;
1020 unsigned char buf[64];
1021 unsigned char tag_buf[16];
1022 int i, j, ret;
1023 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
1024 size_t olen;
1025
1026 if (verbose != 0) {
1027 #if defined(MBEDTLS_GCM_ALT)
1028 mbedtls_printf(" GCM note: alternative implementation.\n");
1029 #else /* MBEDTLS_GCM_ALT */
1030 #if defined(MBEDTLS_AESNI_HAVE_CODE)
1031 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
1032 mbedtls_printf(" GCM note: using AESNI.\n");
1033 } else
1034 #endif
1035
1036 #if defined(MBEDTLS_AESCE_HAVE_CODE)
1037 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
1038 mbedtls_printf(" GCM note: using AESCE.\n");
1039 } else
1040 #endif
1041
1042 mbedtls_printf(" GCM note: built-in implementation.\n");
1043 #endif /* MBEDTLS_GCM_ALT */
1044 }
1045
1046 static const int loop_limit =
1047 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
1048
1049 for (j = 0; j < loop_limit; j++) {
1050 int key_len = 128 + 64 * j;
1051
1052 for (i = 0; i < MAX_TESTS; i++) {
1053 if (verbose != 0) {
1054 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
1055 key_len, i, "enc");
1056 }
1057
1058 mbedtls_gcm_init(&ctx);
1059
1060 ret = mbedtls_gcm_setkey(&ctx, cipher,
1061 key_test_data[key_index_test_data[i]],
1062 key_len);
1063 /*
1064 * AES-192 is an optional feature that may be unavailable when
1065 * there is an alternative underlying implementation i.e. when
1066 * MBEDTLS_AES_ALT is defined.
1067 */
1068 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
1069 mbedtls_printf("skipped\n");
1070 break;
1071 } else if (ret != 0) {
1072 goto exit;
1073 }
1074
1075 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
1076 pt_len_test_data[i],
1077 iv_test_data[iv_index_test_data[i]],
1078 iv_len_test_data[i],
1079 additional_test_data[add_index_test_data[i]],
1080 add_len_test_data[i],
1081 pt_test_data[pt_index_test_data[i]],
1082 buf, 16, tag_buf);
1083 #if defined(MBEDTLS_GCM_ALT)
1084 /* Allow alternative implementations to only support 12-byte nonces. */
1085 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
1086 iv_len_test_data[i] != 12) {
1087 mbedtls_printf("skipped\n");
1088 break;
1089 }
1090 #endif /* defined(MBEDTLS_GCM_ALT) */
1091 if (ret != 0) {
1092 goto exit;
1093 }
1094
1095 if (memcmp(buf, ct_test_data[j * 6 + i],
1096 pt_len_test_data[i]) != 0 ||
1097 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1098 ret = 1;
1099 goto exit;
1100 }
1101
1102 mbedtls_gcm_free(&ctx);
1103
1104 if (verbose != 0) {
1105 mbedtls_printf("passed\n");
1106 }
1107
1108 mbedtls_gcm_init(&ctx);
1109
1110 if (verbose != 0) {
1111 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
1112 key_len, i, "dec");
1113 }
1114
1115 ret = mbedtls_gcm_setkey(&ctx, cipher,
1116 key_test_data[key_index_test_data[i]],
1117 key_len);
1118 if (ret != 0) {
1119 goto exit;
1120 }
1121
1122 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1123 pt_len_test_data[i],
1124 iv_test_data[iv_index_test_data[i]],
1125 iv_len_test_data[i],
1126 additional_test_data[add_index_test_data[i]],
1127 add_len_test_data[i],
1128 ct_test_data[j * 6 + i], buf, 16, tag_buf);
1129
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 mbedtls_gcm_init(&ctx);
1148
1149 if (verbose != 0) {
1150 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1151 key_len, i, "enc");
1152 }
1153
1154 ret = mbedtls_gcm_setkey(&ctx, cipher,
1155 key_test_data[key_index_test_data[i]],
1156 key_len);
1157 if (ret != 0) {
1158 goto exit;
1159 }
1160
1161 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1162 iv_test_data[iv_index_test_data[i]],
1163 iv_len_test_data[i]);
1164 if (ret != 0) {
1165 goto exit;
1166 }
1167
1168 ret = mbedtls_gcm_update_ad(&ctx,
1169 additional_test_data[add_index_test_data[i]],
1170 add_len_test_data[i]);
1171 if (ret != 0) {
1172 goto exit;
1173 }
1174
1175 if (pt_len_test_data[i] > 32) {
1176 size_t rest_len = pt_len_test_data[i] - 32;
1177 ret = mbedtls_gcm_update(&ctx,
1178 pt_test_data[pt_index_test_data[i]],
1179 32,
1180 buf, sizeof(buf), &olen);
1181 if (ret != 0) {
1182 goto exit;
1183 }
1184 if (olen != 32) {
1185 goto exit;
1186 }
1187
1188 ret = mbedtls_gcm_update(&ctx,
1189 pt_test_data[pt_index_test_data[i]] + 32,
1190 rest_len,
1191 buf + 32, sizeof(buf) - 32, &olen);
1192 if (ret != 0) {
1193 goto exit;
1194 }
1195 if (olen != rest_len) {
1196 goto exit;
1197 }
1198 } else {
1199 ret = mbedtls_gcm_update(&ctx,
1200 pt_test_data[pt_index_test_data[i]],
1201 pt_len_test_data[i],
1202 buf, sizeof(buf), &olen);
1203 if (ret != 0) {
1204 goto exit;
1205 }
1206 if (olen != pt_len_test_data[i]) {
1207 goto exit;
1208 }
1209 }
1210
1211 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1212 if (ret != 0) {
1213 goto exit;
1214 }
1215
1216 if (memcmp(buf, ct_test_data[j * 6 + i],
1217 pt_len_test_data[i]) != 0 ||
1218 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1219 ret = 1;
1220 goto exit;
1221 }
1222
1223 mbedtls_gcm_free(&ctx);
1224
1225 if (verbose != 0) {
1226 mbedtls_printf("passed\n");
1227 }
1228
1229 mbedtls_gcm_init(&ctx);
1230
1231 if (verbose != 0) {
1232 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1233 key_len, i, "dec");
1234 }
1235
1236 ret = mbedtls_gcm_setkey(&ctx, cipher,
1237 key_test_data[key_index_test_data[i]],
1238 key_len);
1239 if (ret != 0) {
1240 goto exit;
1241 }
1242
1243 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1244 iv_test_data[iv_index_test_data[i]],
1245 iv_len_test_data[i]);
1246 if (ret != 0) {
1247 goto exit;
1248 }
1249 ret = mbedtls_gcm_update_ad(&ctx,
1250 additional_test_data[add_index_test_data[i]],
1251 add_len_test_data[i]);
1252 if (ret != 0) {
1253 goto exit;
1254 }
1255
1256 if (pt_len_test_data[i] > 32) {
1257 size_t rest_len = pt_len_test_data[i] - 32;
1258 ret = mbedtls_gcm_update(&ctx,
1259 ct_test_data[j * 6 + i], 32,
1260 buf, sizeof(buf), &olen);
1261 if (ret != 0) {
1262 goto exit;
1263 }
1264 if (olen != 32) {
1265 goto exit;
1266 }
1267
1268 ret = mbedtls_gcm_update(&ctx,
1269 ct_test_data[j * 6 + i] + 32,
1270 rest_len,
1271 buf + 32, sizeof(buf) - 32, &olen);
1272 if (ret != 0) {
1273 goto exit;
1274 }
1275 if (olen != rest_len) {
1276 goto exit;
1277 }
1278 } else {
1279 ret = mbedtls_gcm_update(&ctx,
1280 ct_test_data[j * 6 + i],
1281 pt_len_test_data[i],
1282 buf, sizeof(buf), &olen);
1283 if (ret != 0) {
1284 goto exit;
1285 }
1286 if (olen != pt_len_test_data[i]) {
1287 goto exit;
1288 }
1289 }
1290
1291 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1292 if (ret != 0) {
1293 goto exit;
1294 }
1295
1296 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1297 pt_len_test_data[i]) != 0 ||
1298 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
1299 ret = 1;
1300 goto exit;
1301 }
1302
1303 mbedtls_gcm_free(&ctx);
1304
1305 if (verbose != 0) {
1306 mbedtls_printf("passed\n");
1307 }
1308 }
1309 }
1310
1311 if (verbose != 0) {
1312 mbedtls_printf("\n");
1313 }
1314
1315 ret = 0;
1316
1317 exit:
1318 if (ret != 0) {
1319 if (verbose != 0) {
1320 mbedtls_printf("failed\n");
1321 }
1322 mbedtls_gcm_free(&ctx);
1323 }
1324
1325 return ret;
1326 }
1327
1328 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1329
1330 #endif /* MBEDTLS_GCM_C */
1331