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