Coverage Report

Created: 2026-04-15 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/fipsmodule/aes/gcm.cc.inc
Line
Count
Source
1
// Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/base.h>
16
17
#include <string.h>
18
19
#include <openssl/mem.h>
20
21
#include "../../internal.h"
22
#include "../aes/internal.h"
23
#include "internal.h"
24
25
26
using namespace bssl;
27
28
// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four
29
// bits of a |size_t|.
30
static const size_t kSizeTWithoutLower4Bits = (size_t) -16;
31
32
33
#define GCM_MUL(key, ctx, Xi) bssl::gcm_gmult_nohw((ctx)->Xi, (key)->Htable)
34
#define GHASH(key, ctx, in, len) \
35
  gcm_ghash_nohw((ctx)->Xi, (key)->Htable, in, len)
36
// GHASH_CHUNK is "stride parameter" missioned to mitigate cache
37
// trashing effect. In other words idea is to hash data while it's
38
// still in L1 cache after encryption pass...
39
2.99k
#define GHASH_CHUNK (3 * 1024)
40
41
#if defined(GHASH_ASM_X86_64) || defined(GHASH_ASM_X86)
42
0
static void gcm_reduce_1bit(u128 *V) {
43
0
  if (sizeof(crypto_word_t) == 8) {
44
0
    uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V->hi & 1));
45
0
    V->hi = (V->lo << 63) | (V->hi >> 1);
46
0
    V->lo = (V->lo >> 1) ^ T;
47
0
  } else {
48
0
    uint32_t T = 0xe1000000U & (0 - (uint32_t)(V->hi & 1));
49
0
    V->hi = (V->lo << 63) | (V->hi >> 1);
50
0
    V->lo = (V->lo >> 1) ^ ((uint64_t)T << 32);
51
0
  }
52
0
}
53
54
0
void bssl::gcm_init_ssse3(u128 Htable[16], const uint64_t H[2]) {
55
0
  Htable[0].hi = 0;
56
0
  Htable[0].lo = 0;
57
0
  u128 V;
58
0
  V.hi = H[1];
59
0
  V.lo = H[0];
60
61
0
  Htable[8] = V;
62
0
  gcm_reduce_1bit(&V);
63
0
  Htable[4] = V;
64
0
  gcm_reduce_1bit(&V);
65
0
  Htable[2] = V;
66
0
  gcm_reduce_1bit(&V);
67
0
  Htable[1] = V;
68
0
  Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo;
69
0
  V = Htable[4];
70
0
  Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo;
71
0
  Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo;
72
0
  Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo;
73
0
  V = Htable[8];
74
0
  Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo;
75
0
  Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo;
76
0
  Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo;
77
0
  Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo;
78
0
  Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo;
79
0
  Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo;
80
0
  Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo;
81
82
  // Treat |Htable| as a 16x16 byte table and transpose it. Thus, Htable[i]
83
  // contains the i'th byte of j*H for all j.
84
0
  uint8_t *Hbytes = (uint8_t *)Htable;
85
0
  for (int i = 0; i < 16; i++) {
86
0
    for (int j = 0; j < i; j++) {
87
0
      uint8_t tmp = Hbytes[16*i + j];
88
0
      Hbytes[16*i + j] = Hbytes[16*j + i];
89
0
      Hbytes[16*j + i] = tmp;
90
0
    }
91
0
  }
92
0
}
93
#endif  // GHASH_ASM_X86_64 || GHASH_ASM_X86
94
95
#ifdef GCM_FUNCREF
96
#undef GCM_MUL
97
6.89k
#define GCM_MUL(key, ctx, Xi) (*gcm_gmult_p)((ctx)->Xi, (key)->Htable)
98
#undef GHASH
99
#define GHASH(key, ctx, in, len) \
100
623
  (*gcm_ghash_p)((ctx)->Xi, (key)->Htable, in, len)
101
#endif  // GCM_FUNCREF
102
103
#if defined(HW_GCM) && defined(OPENSSL_X86_64)
104
static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
105
                             const AES_KEY *key, uint8_t ivec[16],
106
                             uint8_t Xi[16], const u128 Htable[16],
107
547
                             enum gcm_impl_t impl) {
108
547
  switch (impl) {
109
0
    case gcm_x86_vaes_avx2:
110
0
      len &= kSizeTWithoutLower4Bits;
111
0
      aes_gcm_enc_update_vaes_avx2(in, out, len, key, ivec, Htable, Xi);
112
0
      CRYPTO_store_u32_be(&ivec[12], CRYPTO_load_u32_be(&ivec[12]) + len / 16);
113
0
      return len;
114
0
    case gcm_x86_vaes_avx512:
115
0
      len &= kSizeTWithoutLower4Bits;
116
0
      aes_gcm_enc_update_vaes_avx512(in, out, len, key, ivec, Htable, Xi);
117
0
      CRYPTO_store_u32_be(&ivec[12], CRYPTO_load_u32_be(&ivec[12]) + len / 16);
118
0
      return len;
119
547
    default:
120
547
      return aesni_gcm_encrypt(in, out, len, key, ivec, Htable, Xi);
121
547
  }
122
547
}
123
124
static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
125
                             const AES_KEY *key, uint8_t ivec[16],
126
                             uint8_t Xi[16], const u128 Htable[16],
127
489
                             enum gcm_impl_t impl) {
128
489
  switch (impl) {
129
0
    case gcm_x86_vaes_avx2:
130
0
      len &= kSizeTWithoutLower4Bits;
131
0
      aes_gcm_dec_update_vaes_avx2(in, out, len, key, ivec, Htable, Xi);
132
0
      CRYPTO_store_u32_be(&ivec[12], CRYPTO_load_u32_be(&ivec[12]) + len / 16);
133
0
      return len;
134
0
    case gcm_x86_vaes_avx512:
135
0
      len &= kSizeTWithoutLower4Bits;
136
0
      aes_gcm_dec_update_vaes_avx512(in, out, len, key, ivec, Htable, Xi);
137
0
      CRYPTO_store_u32_be(&ivec[12], CRYPTO_load_u32_be(&ivec[12]) + len / 16);
138
0
      return len;
139
489
    default:
140
489
      return aesni_gcm_decrypt(in, out, len, key, ivec, Htable, Xi);
141
489
  }
142
489
}
143
#endif  // HW_GCM && X86_64
144
145
#if defined(HW_GCM) && defined(OPENSSL_AARCH64)
146
147
static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
148
                             const AES_KEY *key, uint8_t ivec[16],
149
                             uint8_t Xi[16], const u128 Htable[16],
150
                             enum gcm_impl_t impl) {
151
  const size_t len_blocks = len & kSizeTWithoutLower4Bits;
152
  if (!len_blocks) {
153
    return 0;
154
  }
155
  if (impl == gcm_arm64_aes_eor3) {
156
    aes_gcm_enc_kernel_eor3(in, len_blocks * 8, out, Xi, ivec, key, Htable);
157
    return len_blocks;
158
  }
159
  aes_gcm_enc_kernel(in, len_blocks * 8, out, Xi, ivec, key, Htable);
160
  return len_blocks;
161
}
162
163
static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len,
164
                             const AES_KEY *key, uint8_t ivec[16],
165
                             uint8_t Xi[16], const u128 Htable[16],
166
                             enum gcm_impl_t impl) {
167
  const size_t len_blocks = len & kSizeTWithoutLower4Bits;
168
  if (!len_blocks) {
169
    return 0;
170
  }
171
  if (impl == gcm_arm64_aes_eor3) {
172
    aes_gcm_dec_kernel_eor3(in, len_blocks * 8, out, Xi, ivec, key, Htable);
173
    return len_blocks;
174
  }
175
  aes_gcm_dec_kernel(in, len_blocks * 8, out, Xi, ivec, key, Htable);
176
  return len_blocks;
177
}
178
179
#endif  // HW_GCM && AARCH64
180
181
void bssl::CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash,
182
81.1k
                             u128 out_table[16], const uint8_t gcm_key[16]) {
183
  // H is passed to |gcm_init_*| as a pair of byte-swapped, 64-bit values.
184
81.1k
  uint64_t H[2] = {CRYPTO_load_u64_be(gcm_key),
185
81.1k
                   CRYPTO_load_u64_be(gcm_key + 8)};
186
187
81.1k
#if defined(GHASH_ASM_X86_64)
188
81.1k
  if (crypto_gcm_clmul_enabled()) {
189
81.1k
    if (CRYPTO_is_VPCLMULQDQ_capable() && CRYPTO_is_AVX2_capable()) {
190
0
      if (CRYPTO_is_AVX512BW_capable() && CRYPTO_is_AVX512VL_capable() &&
191
0
          CRYPTO_is_BMI2_capable() && !CRYPTO_cpu_avoid_zmm_registers()) {
192
0
        gcm_init_vpclmulqdq_avx512(out_table, H);
193
0
        *out_mult = gcm_gmult_vpclmulqdq_avx512;
194
0
        *out_hash = gcm_ghash_vpclmulqdq_avx512;
195
0
        return;
196
0
      }
197
0
      gcm_init_vpclmulqdq_avx2(out_table, H);
198
0
      *out_mult = gcm_gmult_vpclmulqdq_avx2;
199
0
      *out_hash = gcm_ghash_vpclmulqdq_avx2;
200
0
      return;
201
0
    }
202
81.1k
    if (CRYPTO_is_AVX_capable() && CRYPTO_is_MOVBE_capable()) {
203
81.1k
      gcm_init_avx(out_table, H);
204
81.1k
      *out_mult = gcm_gmult_avx;
205
81.1k
      *out_hash = gcm_ghash_avx;
206
81.1k
      return;
207
81.1k
    }
208
0
    gcm_init_clmul(out_table, H);
209
0
    *out_mult = gcm_gmult_clmul;
210
0
    *out_hash = gcm_ghash_clmul;
211
0
    return;
212
81.1k
  }
213
0
  if (CRYPTO_is_SSSE3_capable()) {
214
0
    gcm_init_ssse3(out_table, H);
215
0
    *out_mult = gcm_gmult_ssse3;
216
0
    *out_hash = gcm_ghash_ssse3;
217
0
    return;
218
0
  }
219
#elif defined(GHASH_ASM_X86)
220
  if (crypto_gcm_clmul_enabled()) {
221
    gcm_init_clmul(out_table, H);
222
    *out_mult = gcm_gmult_clmul;
223
    *out_hash = gcm_ghash_clmul;
224
    return;
225
  }
226
  if (CRYPTO_is_SSSE3_capable()) {
227
    gcm_init_ssse3(out_table, H);
228
    *out_mult = gcm_gmult_ssse3;
229
    *out_hash = gcm_ghash_ssse3;
230
    return;
231
  }
232
#elif defined(GHASH_ASM_ARM)
233
  if (gcm_pmull_capable()) {
234
    gcm_init_v8(out_table, H);
235
    *out_mult = gcm_gmult_v8;
236
    *out_hash = gcm_ghash_v8;
237
    return;
238
  }
239
240
  if (gcm_neon_capable()) {
241
    gcm_init_neon(out_table, H);
242
    *out_mult = gcm_gmult_neon;
243
    *out_hash = gcm_ghash_neon;
244
    return;
245
  }
246
#endif
247
248
0
  gcm_init_nohw(out_table, H);
249
0
  *out_mult = gcm_gmult_nohw;
250
0
  *out_hash = gcm_ghash_nohw;
251
0
}
252
253
void bssl::CRYPTO_gcm128_init_aes_key(GCM128_KEY *gcm_key, const uint8_t *key,
254
81.1k
                                      size_t key_bytes) {
255
81.1k
  switch (key_bytes) {
256
49.2k
    case 16:
257
49.2k
      boringssl_fips_inc_counter(fips_counter_evp_aes_128_gcm);
258
49.2k
      break;
259
260
31.8k
    case 32:
261
31.8k
      boringssl_fips_inc_counter(fips_counter_evp_aes_256_gcm);
262
31.8k
      break;
263
81.1k
  }
264
265
81.1k
  OPENSSL_memset(gcm_key, 0, sizeof(*gcm_key));
266
81.1k
  int is_hwaes;
267
81.1k
  gcm_key->ctr = aes_ctr_set_key(&gcm_key->aes, &is_hwaes, &gcm_key->block, key,
268
81.1k
                                 key_bytes);
269
270
81.1k
  uint8_t ghash_key[16];
271
81.1k
  OPENSSL_memset(ghash_key, 0, sizeof(ghash_key));
272
81.1k
  gcm_key->block(ghash_key, ghash_key, &gcm_key->aes);
273
274
81.1k
  CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, gcm_key->Htable,
275
81.1k
                    ghash_key);
276
277
81.1k
#if !defined(OPENSSL_NO_ASM)
278
81.1k
#if defined(OPENSSL_X86_64)
279
81.1k
  if (gcm_key->ghash == gcm_ghash_vpclmulqdq_avx512 &&
280
0
      CRYPTO_is_VAES_capable()) {
281
0
    gcm_key->impl = gcm_x86_vaes_avx512;
282
81.1k
  } else if (gcm_key->ghash == gcm_ghash_vpclmulqdq_avx2 &&
283
0
             CRYPTO_is_VAES_capable()) {
284
0
    gcm_key->impl = gcm_x86_vaes_avx2;
285
81.1k
  } else if (gcm_key->ghash == gcm_ghash_avx && is_hwaes) {
286
81.1k
    gcm_key->impl = gcm_x86_aesni;
287
81.1k
  }
288
#elif defined(OPENSSL_AARCH64)
289
  // SHA3 and EOR3 belong to the same ISA extension.
290
  if (gcm_sha3_capable() && is_hwaes) {
291
    gcm_key->impl = gcm_arm64_aes_eor3;
292
  } else if (gcm_pmull_capable() && is_hwaes) {
293
    gcm_key->impl = gcm_arm64_aes;
294
  }
295
#endif
296
81.1k
#endif
297
81.1k
}
298
299
void bssl::CRYPTO_gcm128_init_ctx(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
300
2.99k
                                  const uint8_t *iv, size_t iv_len) {
301
2.99k
#ifdef GCM_FUNCREF
302
2.99k
  void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult;
303
2.99k
#endif
304
305
2.99k
  OPENSSL_memset(&ctx->Yi, 0, sizeof(ctx->Yi));
306
2.99k
  OPENSSL_memset(&ctx->Xi, 0, sizeof(ctx->Xi));
307
2.99k
  ctx->len.aad = 0;
308
2.99k
  ctx->len.msg = 0;
309
2.99k
  ctx->ares = 0;
310
2.99k
  ctx->mres = 0;
311
312
2.99k
  uint32_t ctr;
313
2.99k
  if (iv_len == 12) {
314
2.99k
    OPENSSL_memcpy(ctx->Yi, iv, 12);
315
2.99k
    ctx->Yi[15] = 1;
316
2.99k
    ctr = 1;
317
2.99k
  } else {
318
0
    uint64_t len0 = iv_len;
319
320
0
    while (iv_len >= 16) {
321
0
      CRYPTO_xor16(ctx->Yi, ctx->Yi, iv);
322
0
      GCM_MUL(key, ctx, Yi);
323
0
      iv += 16;
324
0
      iv_len -= 16;
325
0
    }
326
0
    if (iv_len) {
327
0
      for (size_t i = 0; i < iv_len; ++i) {
328
0
        ctx->Yi[i] ^= iv[i];
329
0
      }
330
0
      GCM_MUL(key, ctx, Yi);
331
0
    }
332
333
0
    uint8_t len_block[16];
334
0
    OPENSSL_memset(len_block, 0, 8);
335
0
    CRYPTO_store_u64_be(len_block + 8, len0 << 3);
336
0
    CRYPTO_xor16(ctx->Yi, ctx->Yi, len_block);
337
338
0
    GCM_MUL(key, ctx, Yi);
339
0
    ctr = CRYPTO_load_u32_be(ctx->Yi + 12);
340
0
  }
341
342
2.99k
  key->block(ctx->Yi, ctx->EK0, &key->aes);
343
2.99k
  ++ctr;
344
2.99k
  CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
345
2.99k
}
346
347
int bssl::CRYPTO_gcm128_aad(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
348
2.99k
                            const uint8_t *aad, size_t aad_len) {
349
2.99k
#ifdef GCM_FUNCREF
350
2.99k
  void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult;
351
2.99k
  void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp,
352
2.99k
                      size_t len) = key->ghash;
353
2.99k
#endif
354
355
2.99k
  if (ctx->len.msg != 0) {
356
    // The caller must have finished the AAD before providing other input.
357
0
    return 0;
358
0
  }
359
360
2.99k
  uint64_t alen = ctx->len.aad + aad_len;
361
2.99k
  if (alen > (UINT64_C(1) << 61) || (sizeof(aad_len) == 8 && alen < aad_len)) {
362
0
    return 0;
363
0
  }
364
2.99k
  ctx->len.aad = alen;
365
366
2.99k
  unsigned n = ctx->ares;
367
2.99k
  if (n) {
368
0
    while (n && aad_len) {
369
0
      ctx->Xi[n] ^= *(aad++);
370
0
      --aad_len;
371
0
      n = (n + 1) % 16;
372
0
    }
373
0
    if (n == 0) {
374
0
      GCM_MUL(key, ctx, Xi);
375
0
    } else {
376
0
      ctx->ares = n;
377
0
      return 1;
378
0
    }
379
0
  }
380
381
  // Process a whole number of blocks.
382
2.99k
  size_t len_blocks = aad_len & kSizeTWithoutLower4Bits;
383
2.99k
  if (len_blocks != 0) {
384
28
    GHASH(key, ctx, aad, len_blocks);
385
28
    aad += len_blocks;
386
28
    aad_len -= len_blocks;
387
28
  }
388
389
  // Process the remainder.
390
2.99k
  if (aad_len != 0) {
391
2.99k
    n = (unsigned int)aad_len;
392
20.0k
    for (size_t i = 0; i < aad_len; ++i) {
393
17.0k
      ctx->Xi[i] ^= aad[i];
394
17.0k
    }
395
2.99k
  }
396
397
2.99k
  ctx->ares = n;
398
2.99k
  return 1;
399
2.99k
}
400
401
int bssl::CRYPTO_gcm128_encrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
402
909
                                const uint8_t *in, uint8_t *out, size_t len) {
403
909
#ifdef GCM_FUNCREF
404
909
  void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult;
405
909
  void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp,
406
909
                      size_t len) = key->ghash;
407
909
#endif
408
409
909
  uint64_t mlen = ctx->len.msg + len;
410
909
  if (mlen > ((UINT64_C(1) << 36) - 32) ||
411
909
      (sizeof(len) == 8 && mlen < len)) {
412
0
    return 0;
413
0
  }
414
909
  ctx->len.msg = mlen;
415
416
909
  if (ctx->ares) {
417
    // First call to encrypt finalizes GHASH(AAD)
418
547
    GCM_MUL(key, ctx, Xi);
419
547
    ctx->ares = 0;
420
547
  }
421
422
909
  unsigned n = ctx->mres;
423
909
  if (n) {
424
724
    while (n && len) {
425
362
      ctx->Xi[n] ^= *(out++) = *(in++) ^ ctx->EKi[n];
426
362
      --len;
427
362
      n = (n + 1) % 16;
428
362
    }
429
362
    if (n == 0) {
430
0
      GCM_MUL(key, ctx, Xi);
431
362
    } else {
432
362
      ctx->mres = n;
433
362
      return 1;
434
362
    }
435
362
  }
436
437
547
#if defined(HW_GCM)
438
547
  if (key->impl != gcm_separate && len > 0) {
439
    // |hw_gcm_encrypt| may not process all the input given to it. It may
440
    // not process *any* of its input if it is deemed too small.
441
547
    size_t bulk = hw_gcm_encrypt(in, out, len, &key->aes, ctx->Yi, ctx->Xi,
442
547
                                 key->Htable, key->impl);
443
547
    in += bulk;
444
547
    out += bulk;
445
547
    len -= bulk;
446
547
  }
447
547
#endif
448
449
547
  uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12);
450
547
  ctr128_f stream = key->ctr;
451
547
  while (len >= GHASH_CHUNK) {
452
0
    (*stream)(in, out, GHASH_CHUNK / 16, &key->aes, ctx->Yi);
453
0
    ctr += GHASH_CHUNK / 16;
454
0
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
455
0
    GHASH(key, ctx, out, GHASH_CHUNK);
456
0
    out += GHASH_CHUNK;
457
0
    in += GHASH_CHUNK;
458
0
    len -= GHASH_CHUNK;
459
0
  }
460
461
547
  size_t len_blocks = len & kSizeTWithoutLower4Bits;
462
547
  if (len_blocks != 0) {
463
356
    size_t j = len_blocks / 16;
464
356
    (*stream)(in, out, j, &key->aes, ctx->Yi);
465
356
    ctr += (uint32_t)j;
466
356
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
467
356
    in += len_blocks;
468
356
    len -= len_blocks;
469
356
    GHASH(key, ctx, out, len_blocks);
470
356
    out += len_blocks;
471
356
  }
472
473
547
  if (len) {
474
447
    key->block(ctx->Yi, ctx->EKi, &key->aes);
475
447
    ++ctr;
476
447
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
477
2.42k
    while (len--) {
478
1.98k
      ctx->Xi[n] ^= out[n] = in[n] ^ ctx->EKi[n];
479
1.98k
      ++n;
480
1.98k
    }
481
447
  }
482
483
547
  ctx->mres = n;
484
547
  return 1;
485
909
}
486
487
int bssl::CRYPTO_gcm128_decrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
488
2.45k
                                const uint8_t *in, uint8_t *out, size_t len) {
489
2.45k
#ifdef GCM_FUNCREF
490
2.45k
  void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult;
491
2.45k
  void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp,
492
2.45k
                      size_t len) = key->ghash;
493
2.45k
#endif
494
495
2.45k
  uint64_t mlen = ctx->len.msg + len;
496
2.45k
  if (mlen > ((UINT64_C(1) << 36) - 32) ||
497
2.45k
      (sizeof(len) == 8 && mlen < len)) {
498
0
    return 0;
499
0
  }
500
2.45k
  ctx->len.msg = mlen;
501
502
2.45k
  if (ctx->ares) {
503
    // First call to decrypt finalizes GHASH(AAD)
504
2.44k
    GCM_MUL(key, ctx, Xi);
505
2.44k
    ctx->ares = 0;
506
2.44k
  }
507
508
2.45k
  unsigned n = ctx->mres;
509
2.45k
  if (n) {
510
0
    while (n && len) {
511
0
      uint8_t c = *(in++);
512
0
      *(out++) = c ^ ctx->EKi[n];
513
0
      ctx->Xi[n] ^= c;
514
0
      --len;
515
0
      n = (n + 1) % 16;
516
0
    }
517
0
    if (n == 0) {
518
0
      GCM_MUL(key, ctx, Xi);
519
0
    } else {
520
0
      ctx->mres = n;
521
0
      return 1;
522
0
    }
523
0
  }
524
525
2.45k
#if defined(HW_GCM)
526
2.45k
  if (key->impl != gcm_separate && len > 0) {
527
    // |hw_gcm_decrypt| may not process all the input given to it. It may
528
    // not process *any* of its input if it is deemed too small.
529
489
    size_t bulk = hw_gcm_decrypt(in, out, len, &key->aes, ctx->Yi, ctx->Xi,
530
489
                                 key->Htable, key->impl);
531
489
    in += bulk;
532
489
    out += bulk;
533
489
    len -= bulk;
534
489
  }
535
2.45k
#endif
536
537
2.45k
  uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12);
538
2.45k
  ctr128_f stream = key->ctr;
539
2.45k
  while (len >= GHASH_CHUNK) {
540
0
    GHASH(key, ctx, in, GHASH_CHUNK);
541
0
    (*stream)(in, out, GHASH_CHUNK / 16, &key->aes, ctx->Yi);
542
0
    ctr += GHASH_CHUNK / 16;
543
0
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
544
0
    out += GHASH_CHUNK;
545
0
    in += GHASH_CHUNK;
546
0
    len -= GHASH_CHUNK;
547
0
  }
548
549
2.45k
  size_t len_blocks = len & kSizeTWithoutLower4Bits;
550
2.45k
  if (len_blocks != 0) {
551
239
    size_t j = len_blocks / 16;
552
239
    GHASH(key, ctx, in, len_blocks);
553
239
    (*stream)(in, out, j, &key->aes, ctx->Yi);
554
239
    ctr += (uint32_t)j;
555
239
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
556
239
    out += len_blocks;
557
239
    in += len_blocks;
558
239
    len -= len_blocks;
559
239
  }
560
561
2.45k
  if (len) {
562
457
    key->block(ctx->Yi, ctx->EKi, &key->aes);
563
457
    ++ctr;
564
457
    CRYPTO_store_u32_be(ctx->Yi + 12, ctr);
565
2.83k
    while (len--) {
566
2.38k
      uint8_t c = in[n];
567
2.38k
      ctx->Xi[n] ^= c;
568
2.38k
      out[n] = c ^ ctx->EKi[n];
569
2.38k
      ++n;
570
2.38k
    }
571
457
  }
572
573
2.45k
  ctx->mres = n;
574
2.45k
  return 1;
575
2.45k
}
576
577
int bssl::CRYPTO_gcm128_finish(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
578
2.99k
                               const uint8_t *tag, size_t len) {
579
2.99k
#ifdef GCM_FUNCREF
580
2.99k
  void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult;
581
2.99k
#endif
582
583
2.99k
  if (ctx->mres || ctx->ares) {
584
904
    GCM_MUL(key, ctx, Xi);
585
904
  }
586
587
2.99k
  uint8_t len_block[16];
588
2.99k
  CRYPTO_store_u64_be(len_block, ctx->len.aad << 3);
589
2.99k
  CRYPTO_store_u64_be(len_block + 8, ctx->len.msg << 3);
590
2.99k
  CRYPTO_xor16(ctx->Xi, ctx->Xi, len_block);
591
2.99k
  GCM_MUL(key, ctx, Xi);
592
2.99k
  CRYPTO_xor16(ctx->Xi, ctx->Xi, ctx->EK0);
593
594
2.99k
  if (tag && len <= sizeof(ctx->Xi)) {
595
0
    return CRYPTO_memcmp(ctx->Xi, tag, len) == 0;
596
2.99k
  } else {
597
2.99k
    return 0;
598
2.99k
  }
599
2.99k
}
600
601
void bssl::CRYPTO_gcm128_tag(const GCM128_KEY *key, GCM128_CONTEXT *ctx,
602
2.99k
                             uint8_t *tag, size_t len) {
603
2.99k
  CRYPTO_gcm128_finish(key, ctx, nullptr, 0);
604
2.99k
  OPENSSL_memcpy(tag, ctx->Xi, len <= sizeof(ctx->Xi) ? len : sizeof(ctx->Xi));
605
2.99k
}
606
607
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
608
166k
int bssl::crypto_gcm_clmul_enabled() {
609
166k
#if defined(GHASH_ASM_X86) || defined(GHASH_ASM_X86_64)
610
166k
  return CRYPTO_is_PCLMUL_capable() && CRYPTO_is_SSSE3_capable();
611
#else
612
  return 0;
613
#endif
614
166k
}
615
#endif