Coverage Report

Created: 2025-06-24 07:00

/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
4.77k
bcm_infallible BCM_sha224_init(SHA256_CTX *sha) {
28
4.77k
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
29
4.77k
  sha->h[0] = 0xc1059ed8UL;
30
4.77k
  sha->h[1] = 0x367cd507UL;
31
4.77k
  sha->h[2] = 0x3070dd17UL;
32
4.77k
  sha->h[3] = 0xf70e5939UL;
33
4.77k
  sha->h[4] = 0xffc00b31UL;
34
4.77k
  sha->h[5] = 0x68581511UL;
35
4.77k
  sha->h[6] = 0x64f98fa7UL;
36
4.77k
  sha->h[7] = 0xbefa4fa4UL;
37
4.77k
  sha->md_len = BCM_SHA224_DIGEST_LENGTH;
38
4.77k
  return bcm_infallible::approved;
39
4.77k
}
40
41
1.01M
bcm_infallible BCM_sha256_init(SHA256_CTX *sha) {
42
1.01M
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
43
1.01M
  sha->h[0] = 0x6a09e667UL;
44
1.01M
  sha->h[1] = 0xbb67ae85UL;
45
1.01M
  sha->h[2] = 0x3c6ef372UL;
46
1.01M
  sha->h[3] = 0xa54ff53aUL;
47
1.01M
  sha->h[4] = 0x510e527fUL;
48
1.01M
  sha->h[5] = 0x9b05688cUL;
49
1.01M
  sha->h[6] = 0x1f83d9abUL;
50
1.01M
  sha->h[7] = 0x5be0cd19UL;
51
1.01M
  sha->md_len = BCM_SHA256_DIGEST_LENGTH;
52
1.01M
  return bcm_infallible::approved;
53
1.01M
}
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
3.91M
                         size_t num_blocks) {
73
3.91M
    sha256_block_data_order(state, data, num_blocks);
74
3.91M
  }
75
};
76
}  // namespace
77
78
4.56M
bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) {
79
4.56M
  bssl::crypto_md32_update<SHA256Traits>(
80
4.56M
      c, bssl::Span(static_cast<const uint8_t *>(data), len));
81
4.56M
  return bcm_infallible::approved;
82
4.56M
}
83
84
bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data,
85
4.87k
                                 size_t len) {
86
4.87k
  return BCM_sha256_update(ctx, data, len);
87
4.87k
}
88
89
2.01M
static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
90
2.01M
  bssl::crypto_md32_final<SHA256Traits>(c);
91
92
2.01M
  BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
93
94
2.01M
  assert(md_len % 4 == 0);
95
2.01M
  const size_t out_words = md_len / 4;
96
18.1M
  for (size_t i = 0; i < out_words; i++) {
97
16.1M
    CRYPTO_store_u32_be(out, c->h[i]);
98
16.1M
    out += 4;
99
16.1M
  }
100
101
2.01M
  FIPS_service_indicator_update_state();
102
2.01M
}
103
104
bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
105
2.01M
                                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.01M
  sha256_final_impl(out, c->md_len, c);
112
2.01M
  return bcm_infallible::approved;
113
2.01M
}
114
115
bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
116
4.77k
                                SHA256_CTX *ctx) {
117
  // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
118
  // to |BCM_SHA224_DIGEST_LENGTH|.
119
4.77k
  assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH);
120
4.77k
  sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx);
121
4.77k
  return bcm_infallible::approved;
122
4.77k
}
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
3.91M
                                    size_t num) {
266
3.91M
#if defined(SHA256_ASM_HW)
267
3.91M
  if (sha256_hw_capable()) {
268
0
    sha256_block_data_order_hw(state, data, num);
269
0
    return;
270
0
  }
271
3.91M
#endif
272
3.91M
#if defined(SHA256_ASM_AVX)
273
3.91M
  if (sha256_avx_capable()) {
274
3.91M
    sha256_block_data_order_avx(state, data, num);
275
3.91M
    return;
276
3.91M
  }
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