NCBI C++ ToolKit
gcm.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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  */
54 {
55  memset(ctx, 0, sizeof(mbedtls_gcm_context));
56 }
57 
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 */
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 
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  */
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 
163  mbedtls_cipher_id_t cipher,
164  const unsigned char *key,
165  unsigned int keybits)
166 {
168 
169  if (keybits != 128 && keybits != 192 && keybits != 256) {
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,
188  if (cipher_info == NULL) {
190  }
191 
192  if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
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 
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 
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  */
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:
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 
378  int mode,
379  const unsigned char *iv, size_t iv_len)
380 {
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) {
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  */
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) {
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) {
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. */
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. */
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 {
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 
565  const unsigned char *input, size_t input_length,
566  unsigned char *output, size_t output_size,
567  size_t *output_length)
568 {
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) {
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) {
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) {
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 
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) {
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 
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 {
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 
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 {
750  unsigned char check_tag[16];
751  int diff;
752 
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) {
765  }
766 
767  return 0;
768 }
769 
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
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 
1017 int mbedtls_gcm_self_test(int verbose)
1018 {
1020  unsigned char buf[64];
1021  unsigned char tag_buf[16];
1022  int i, j, ret;
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)
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 
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 
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. */
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 
1103 
1104  if (verbose != 0) {
1105  mbedtls_printf("passed\n");
1106  }
1107 
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 
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 
1142 
1143  if (verbose != 0) {
1144  mbedtls_printf("passed\n");
1145  }
1146 
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 
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 
1224 
1225  if (verbose != 0) {
1226  mbedtls_printf("passed\n");
1227  }
1228 
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 
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 
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  }
1323  }
1324 
1325  return ret;
1326 }
1327 
1328 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1329 
1330 #endif /* MBEDTLS_GCM_C */
Support hardware AES acceleration on Armv8-A processors with the Armv8-A Cryptographic Extension.
AES-NI for hardware AES acceleration on some Intel processors.
#define MBEDTLS_AESNI_CLMUL
Definition: aesni.h:21
#define MBEDTLS_IS_BIG_ENDIAN
Definition: alignment.h:390
#define MBEDTLS_GET_UINT16_LE(data, offset)
Get the unsigned 16 bits integer corresponding to two bytes in little-endian order (LSB first).
Definition: alignment.h:485
#define MBEDTLS_PUT_UINT32_BE(n, data, offset)
Put in memory a 32 bits unsigned integer in big-endian order.
Definition: alignment.h:427
#define MBEDTLS_PUT_UINT64_BE(n, data, offset)
Put in memory a 64 bits unsigned integer in big-endian order.
Definition: alignment.h:636
#define MBEDTLS_GET_UINT32_BE(data, offset)
Get the unsigned 32 bits integer corresponding to four bytes in big-endian order (MSB first).
Definition: alignment.h:412
#define MBEDTLS_GET_UINT64_BE(data, offset)
Get the unsigned 64 bits integer corresponding to eight bytes in big-endian order (MSB first).
Definition: alignment.h:621
Lightweight abstraction layer for block ciphers with 128 bit blocks, for use by the GCM and CCM modul...
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, const unsigned char *key, unsigned key_bitlen)
Set the key into the context.
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, mbedtls_cipher_id_t cipher_id)
Set the block cipher to use with this context.
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
Clear the context.
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, const unsigned char input[16], unsigned char output[16])
Encrypt one block (16 bytes) with the configured key.
int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info)
This function prepares a cipher context for use with the given cipher primitive.
int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *key, int key_bitlen, const mbedtls_operation_t operation)
This function sets the key to use with the given context.
static size_t mbedtls_cipher_info_get_block_size(const mbedtls_cipher_info_t *info)
This function returns the block size of the given cipher info structure in bytes.
Definition: cipher.h:538
void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
This function frees and clears the cipher-specific context of ctx.
int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
The generic cipher update function.
const mbedtls_cipher_info_t * mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id, int key_bitlen, const mbedtls_cipher_mode_t mode)
This function retrieves the cipher-information structure associated with the given cipher ID,...
@ MBEDTLS_ENCRYPT
Definition: cipher.h:202
@ MBEDTLS_MODE_ECB
The ECB cipher mode.
Definition: cipher.h:174
mbedtls_cipher_id_t
Supported cipher types.
Definition: cipher.h:66
@ MBEDTLS_CIPHER_ID_AES
The AES cipher.
Definition: cipher.h:69
static void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
Perform a fast block XOR operation, such that r[i] = a[i] ^ b[i] where 0 <= i < n.
Definition: common.h:186
static void mbedtls_xor_no_simd(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
Perform a fast block XOR operation, such that r[i] = a[i] ^ b[i] where 0 <= i < n.
Definition: common.h:268
CS_CONTEXT * ctx
Definition: t0006.c:12
#define MAX_TESTS
Definition: blob1.c:59
static SQLCHAR output[256]
Definition: print.c:5
int offset
Definition: replacements.h:160
#define H(x, y, z)
Definition: md4.c:180
Uint8 uint64_t
unsigned char uint8_t
Uint2 uint16_t
Uint4 uint32_t
This file contains GCM definitions and functions.
#define MBEDTLS_GCM_ENCRYPT
Definition: gcm.h:33
#define MBEDTLS_GCM_HTABLE_SIZE
Definition: gcm.h:52
int 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)
This function feeds an input buffer into an ongoing GCM encryption or decryption operation.
#define MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL
An output buffer is too small.
Definition: gcm.h:41
int 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)
This function finishes the GCM operation and generates the authentication tag.
int 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)
This function performs GCM encryption or decryption of a buffer.
#define MBEDTLS_ERR_GCM_AUTH_FAILED
Authenticated decryption failed.
Definition: gcm.h:37
#define MBEDTLS_ERR_GCM_BAD_INPUT
Bad input parameters to function.
Definition: gcm.h:39
#define MBEDTLS_GCM_DECRYPT
Definition: gcm.h:34
int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, const unsigned char *add, size_t add_len)
This function feeds an input buffer as associated data (authenticated but not encrypted data) in a GC...
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, int mode, const unsigned char *iv, size_t iv_len)
This function starts a GCM encryption or decryption operation.
void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
This function initializes the specified GCM context, to make references valid, and prepares the conte...
int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits)
This function associates a GCM context with a cipher algorithm and a key.
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
This function clears a GCM context and the underlying cipher sub-context.
int 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)
This function performs a GCM authenticated decryption of a buffer.
#define NULL
Definition: ncbistd.hpp:225
exit(2)
char * buf
static int input()
int i
int len
mdb_mode_t mode
Definition: lmdb++.h:38
const struct ncbi::grid::netcache::search::fields::KEY key
const char * tag
#define mbedtls_platform_zeroize
#define mbedtls_aesni_gcm_mult
#define mbedtls_aesni_has_support
#define mbedtls_ct_memcmp
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_printf
Definition: platform.h:219
Common and shared functions used by multiple modules in the Mbed TLS library.
true_type verbose
Definition: processing.cpp:890
Error to string translation.
#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED
The requested feature is not supported by the platform.
Definition: error.h:105
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
This is a bug in the library.
Definition: error.h:100
#define uint64_t
Definition: config.h:48
Cipher information.
Definition: cipher.h:266
The GCM context structure.
Definition: gcm.h:58
Modified on Thu Apr 25 08:17:30 2024 by modify_doxy.py rev. 669887