Coverage Report

Created: 2025-08-28 06:59

/src/boringssl/crypto/fipsmodule/sha/sha256.cc.inc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2004-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 <string.h>
16
17
#include <openssl/mem.h>
18
#include <openssl/span.h>
19
20
#include "../../internal.h"
21
#include "../bcm_interface.h"
22
#include "../digest/md32_common.h"
23
#include "../service_indicator/internal.h"
24
#include "internal.h"
25
26
27
6.70k
bcm_infallible BCM_sha224_init(SHA256_CTX *sha) {
28
6.70k
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
29
6.70k
  sha->h[0] = 0xc1059ed8UL;
30
6.70k
  sha->h[1] = 0x367cd507UL;
31
6.70k
  sha->h[2] = 0x3070dd17UL;
32
6.70k
  sha->h[3] = 0xf70e5939UL;
33
6.70k
  sha->h[4] = 0xffc00b31UL;
34
6.70k
  sha->h[5] = 0x68581511UL;
35
6.70k
  sha->h[6] = 0x64f98fa7UL;
36
6.70k
  sha->h[7] = 0xbefa4fa4UL;
37
6.70k
  sha->md_len = BCM_SHA224_DIGEST_LENGTH;
38
6.70k
  return bcm_infallible::approved;
39
6.70k
}
40
41
1.02M
bcm_infallible BCM_sha256_init(SHA256_CTX *sha) {
42
1.02M
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
43
1.02M
  sha->h[0] = 0x6a09e667UL;
44
1.02M
  sha->h[1] = 0xbb67ae85UL;
45
1.02M
  sha->h[2] = 0x3c6ef372UL;
46
1.02M
  sha->h[3] = 0xa54ff53aUL;
47
1.02M
  sha->h[4] = 0x510e527fUL;
48
1.02M
  sha->h[5] = 0x9b05688cUL;
49
1.02M
  sha->h[6] = 0x1f83d9abUL;
50
1.02M
  sha->h[7] = 0x5be0cd19UL;
51
1.02M
  sha->md_len = BCM_SHA256_DIGEST_LENGTH;
52
1.02M
  return bcm_infallible::approved;
53
1.02M
}
54
55
#if !defined(SHA256_ASM)
56
static void sha256_block_data_order(uint32_t state[8], const uint8_t *in,
57
                                    size_t num);
58
#endif
59
60
bcm_infallible BCM_sha256_transform(SHA256_CTX *c,
61
0
                                    const uint8_t data[BCM_SHA256_CBLOCK]) {
62
0
  sha256_block_data_order(c->h, data, 1);
63
0
  return bcm_infallible::approved;
64
0
}
65
66
namespace {
67
struct SHA256Traits {
68
  using HashContext = SHA256_CTX;
69
  static constexpr size_t kBlockSize = BCM_SHA256_CBLOCK;
70
  static constexpr bool kLengthIsBigEndian = true;
71
  static void HashBlocks(uint32_t *state, const uint8_t *data,
72
4.19M
                         size_t num_blocks) {
73
4.19M
    sha256_block_data_order(state, data, num_blocks);
74
4.19M
  }
75
};
76
}  // namespace
77
78
4.87M
bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) {
79
4.87M
  bssl::crypto_md32_update<SHA256Traits>(
80
4.87M
      c, bssl::Span(static_cast<const uint8_t *>(data), len));
81
4.87M
  return bcm_infallible::approved;
82
4.87M
}
83
84
bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data,
85
6.76k
                                 size_t len) {
86
6.76k
  return BCM_sha256_update(ctx, data, len);
87
6.76k
}
88
89
2.17M
static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
90
2.17M
  bssl::crypto_md32_final<SHA256Traits>(c);
91
92
2.17M
  BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
93
94
2.17M
  assert(md_len % 4 == 0);
95
2.17M
  const size_t out_words = md_len / 4;
96
19.5M
  for (size_t i = 0; i < out_words; i++) {
97
17.4M
    CRYPTO_store_u32_be(out, c->h[i]);
98
17.4M
    out += 4;
99
17.4M
  }
100
101
2.17M
  FIPS_service_indicator_update_state();
102
2.17M
}
103
104
bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
105
2.17M
                                SHA256_CTX *c) {
106
  // Ideally we would assert |sha->md_len| is |BCM_SHA256_DIGEST_LENGTH| to
107
  // match the size hint, but calling code often pairs |SHA224_Init| with
108
  // |SHA256_Final| and expects |sha->md_len| to carry the size over.
109
  //
110
  // TODO(davidben): Add an assert and fix code to match them up.
111
2.17M
  sha256_final_impl(out, c->md_len, c);
112
2.17M
  return bcm_infallible::approved;
113
2.17M
}
114
115
bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
116
6.70k
                                SHA256_CTX *ctx) {
117
  // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
118
  // to |BCM_SHA224_DIGEST_LENGTH|.
119
6.70k
  assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH);
120
6.70k
  sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx);
121
6.70k
  return bcm_infallible::approved;
122
6.70k
}
123
124
#if !defined(SHA256_ASM)
125
126
#if !defined(SHA256_ASM_NOHW)
127
static const uint32_t K256[64] = {
128
    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
129
    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
130
    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
131
    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
132
    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
133
    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
134
    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
135
    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
136
    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
137
    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
138
    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
139
    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
140
    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
141
142
// See FIPS 180-4, section 4.1.2.
143
#define Sigma0(x)                                       \
144
  (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \
145
   CRYPTO_rotr_u32((x), 22))
146
#define Sigma1(x)                                       \
147
  (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \
148
   CRYPTO_rotr_u32((x), 25))
149
#define sigma0(x) \
150
  (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3))
151
#define sigma1(x) \
152
  (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10))
153
154
#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
155
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
156
157
#define ROUND_00_15(i, a, b, c, d, e, f, g, h)   \
158
  do {                                           \
159
    T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
160
    h = Sigma0(a) + Maj(a, b, c);                \
161
    d += T1;                                     \
162
    h += T1;                                     \
163
  } while (0)
164
165
#define ROUND_16_63(i, a, b, c, d, e, f, g, h, X)      \
166
  do {                                                 \
167
    s0 = X[(i + 1) & 0x0f];                            \
168
    s0 = sigma0(s0);                                   \
169
    s1 = X[(i + 14) & 0x0f];                           \
170
    s1 = sigma1(s1);                                   \
171
    T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \
172
    ROUND_00_15(i, a, b, c, d, e, f, g, h);            \
173
  } while (0)
174
175
static void sha256_block_data_order_nohw(uint32_t state[8], const uint8_t *data,
176
                                         size_t num) {
177
  uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
178
  uint32_t X[16];
179
  int i;
180
181
  while (num--) {
182
    a = state[0];
183
    b = state[1];
184
    c = state[2];
185
    d = state[3];
186
    e = state[4];
187
    f = state[5];
188
    g = state[6];
189
    h = state[7];
190
191
    T1 = X[0] = CRYPTO_load_u32_be(data);
192
    data += 4;
193
    ROUND_00_15(0, a, b, c, d, e, f, g, h);
194
    T1 = X[1] = CRYPTO_load_u32_be(data);
195
    data += 4;
196
    ROUND_00_15(1, h, a, b, c, d, e, f, g);
197
    T1 = X[2] = CRYPTO_load_u32_be(data);
198
    data += 4;
199
    ROUND_00_15(2, g, h, a, b, c, d, e, f);
200
    T1 = X[3] = CRYPTO_load_u32_be(data);
201
    data += 4;
202
    ROUND_00_15(3, f, g, h, a, b, c, d, e);
203
    T1 = X[4] = CRYPTO_load_u32_be(data);
204
    data += 4;
205
    ROUND_00_15(4, e, f, g, h, a, b, c, d);
206
    T1 = X[5] = CRYPTO_load_u32_be(data);
207
    data += 4;
208
    ROUND_00_15(5, d, e, f, g, h, a, b, c);
209
    T1 = X[6] = CRYPTO_load_u32_be(data);
210
    data += 4;
211
    ROUND_00_15(6, c, d, e, f, g, h, a, b);
212
    T1 = X[7] = CRYPTO_load_u32_be(data);
213
    data += 4;
214
    ROUND_00_15(7, b, c, d, e, f, g, h, a);
215
    T1 = X[8] = CRYPTO_load_u32_be(data);
216
    data += 4;
217
    ROUND_00_15(8, a, b, c, d, e, f, g, h);
218
    T1 = X[9] = CRYPTO_load_u32_be(data);
219
    data += 4;
220
    ROUND_00_15(9, h, a, b, c, d, e, f, g);
221
    T1 = X[10] = CRYPTO_load_u32_be(data);
222
    data += 4;
223
    ROUND_00_15(10, g, h, a, b, c, d, e, f);
224
    T1 = X[11] = CRYPTO_load_u32_be(data);
225
    data += 4;
226
    ROUND_00_15(11, f, g, h, a, b, c, d, e);
227
    T1 = X[12] = CRYPTO_load_u32_be(data);
228
    data += 4;
229
    ROUND_00_15(12, e, f, g, h, a, b, c, d);
230
    T1 = X[13] = CRYPTO_load_u32_be(data);
231
    data += 4;
232
    ROUND_00_15(13, d, e, f, g, h, a, b, c);
233
    T1 = X[14] = CRYPTO_load_u32_be(data);
234
    data += 4;
235
    ROUND_00_15(14, c, d, e, f, g, h, a, b);
236
    T1 = X[15] = CRYPTO_load_u32_be(data);
237
    data += 4;
238
    ROUND_00_15(15, b, c, d, e, f, g, h, a);
239
240
    for (i = 16; i < 64; i += 8) {
241
      ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
242
      ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
243
      ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
244
      ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
245
      ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
246
      ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
247
      ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
248
      ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
249
    }
250
251
    state[0] += a;
252
    state[1] += b;
253
    state[2] += c;
254
    state[3] += d;
255
    state[4] += e;
256
    state[5] += f;
257
    state[6] += g;
258
    state[7] += h;
259
  }
260
}
261
262
#endif  // !defined(SHA256_ASM_NOHW)
263
264
static void sha256_block_data_order(uint32_t state[8], const uint8_t *data,
265
4.19M
                                    size_t num) {
266
4.19M
#if defined(SHA256_ASM_HW)
267
4.19M
  if (sha256_hw_capable()) {
268
4.19M
    sha256_block_data_order_hw(state, data, num);
269
4.19M
    return;
270
4.19M
  }
271
0
#endif
272
0
#if defined(SHA256_ASM_AVX)
273
0
  if (sha256_avx_capable()) {
274
0
    sha256_block_data_order_avx(state, data, num);
275
0
    return;
276
0
  }
277
0
#endif
278
0
#if defined(SHA256_ASM_SSSE3)
279
0
  if (sha256_ssse3_capable()) {
280
0
    sha256_block_data_order_ssse3(state, data, num);
281
0
    return;
282
0
  }
283
0
#endif
284
#if defined(SHA256_ASM_NEON)
285
  if (CRYPTO_is_NEON_capable()) {
286
    sha256_block_data_order_neon(state, data, num);
287
    return;
288
  }
289
#endif
290
0
  sha256_block_data_order_nohw(state, data, num);
291
0
}
292
293
#endif  // !defined(SHA256_ASM)
294
295
296
bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8],
297
                                           const uint8_t *data,
298
0
                                           size_t num_blocks) {
299
0
  sha256_block_data_order(state, data, num_blocks);
300
0
  return bcm_infallible::approved;
301
0
}
302
303
#undef Sigma0
304
#undef Sigma1
305
#undef sigma0
306
#undef sigma1
307
#undef Ch
308
#undef Maj
309
#undef ROUND_00_15
310
#undef ROUND_16_63