Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/fipsmodule/sha/sha256.c.inc
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <string.h>
58
59
#include <openssl/mem.h>
60
61
#include "../../internal.h"
62
#include "../bcm_interface.h"
63
#include "../digest/md32_common.h"
64
#include "../service_indicator/internal.h"
65
#include "internal.h"
66
67
68
234
bcm_infallible BCM_sha224_init(SHA256_CTX *sha) {
69
234
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
70
234
  sha->h[0] = 0xc1059ed8UL;
71
234
  sha->h[1] = 0x367cd507UL;
72
234
  sha->h[2] = 0x3070dd17UL;
73
234
  sha->h[3] = 0xf70e5939UL;
74
234
  sha->h[4] = 0xffc00b31UL;
75
234
  sha->h[5] = 0x68581511UL;
76
234
  sha->h[6] = 0x64f98fa7UL;
77
234
  sha->h[7] = 0xbefa4fa4UL;
78
234
  sha->md_len = BCM_SHA224_DIGEST_LENGTH;
79
234
  return bcm_infallible_approved;
80
234
}
81
82
790
bcm_infallible BCM_sha256_init(SHA256_CTX *sha) {
83
790
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
84
790
  sha->h[0] = 0x6a09e667UL;
85
790
  sha->h[1] = 0xbb67ae85UL;
86
790
  sha->h[2] = 0x3c6ef372UL;
87
790
  sha->h[3] = 0xa54ff53aUL;
88
790
  sha->h[4] = 0x510e527fUL;
89
790
  sha->h[5] = 0x9b05688cUL;
90
790
  sha->h[6] = 0x1f83d9abUL;
91
790
  sha->h[7] = 0x5be0cd19UL;
92
790
  sha->md_len = BCM_SHA256_DIGEST_LENGTH;
93
790
  return bcm_infallible_approved;
94
790
}
95
96
#if !defined(SHA256_ASM)
97
static void sha256_block_data_order(uint32_t state[8], const uint8_t *in,
98
                                    size_t num);
99
#endif
100
101
bcm_infallible BCM_sha256_transform(SHA256_CTX *c,
102
0
                                    const uint8_t data[BCM_SHA256_CBLOCK]) {
103
0
  sha256_block_data_order(c->h, data, 1);
104
0
  return bcm_infallible_approved;
105
0
}
106
107
42.4k
bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) {
108
42.4k
  crypto_md32_update(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
109
42.4k
                     &c->num, &c->Nh, &c->Nl, data, len);
110
42.4k
  return bcm_infallible_approved;
111
42.4k
}
112
113
bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data,
114
11.8k
                                 size_t len) {
115
11.8k
  return BCM_sha256_update(ctx, data, len);
116
11.8k
}
117
118
14.7k
static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
119
14.7k
  crypto_md32_final(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
120
14.7k
                    &c->num, c->Nh, c->Nl, /*is_big_endian=*/1);
121
122
14.7k
  BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
123
124
14.7k
  assert(md_len % 4 == 0);
125
14.7k
  const size_t out_words = md_len / 4;
126
130k
  for (size_t i = 0; i < out_words; i++) {
127
115k
    CRYPTO_store_u32_be(out, c->h[i]);
128
115k
    out += 4;
129
115k
  }
130
131
14.7k
  FIPS_service_indicator_update_state();
132
14.7k
}
133
134
bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
135
12.4k
                                SHA256_CTX *c) {
136
  // Ideally we would assert |sha->md_len| is |BCM_SHA256_DIGEST_LENGTH| to
137
  // match the size hint, but calling code often pairs |SHA224_Init| with
138
  // |SHA256_Final| and expects |sha->md_len| to carry the size over.
139
  //
140
  // TODO(davidben): Add an assert and fix code to match them up.
141
12.4k
  sha256_final_impl(out, c->md_len, c);
142
12.4k
  return bcm_infallible_approved;
143
12.4k
}
144
145
bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
146
2.27k
                                SHA256_CTX *ctx) {
147
  // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
148
  // to |BCM_SHA224_DIGEST_LENGTH|.
149
2.27k
  assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH);
150
2.27k
  sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx);
151
2.27k
  return bcm_infallible_approved;
152
2.27k
}
153
154
#if !defined(SHA256_ASM)
155
156
#if !defined(SHA256_ASM_NOHW)
157
static const uint32_t K256[64] = {
158
    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
159
    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
160
    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
161
    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
162
    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
163
    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
164
    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
165
    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
166
    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
167
    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
168
    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
169
    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
170
    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
171
172
// See FIPS 180-4, section 4.1.2.
173
#define Sigma0(x)                                       \
174
27.2M
  (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \
175
27.2M
   CRYPTO_rotr_u32((x), 22))
176
#define Sigma1(x)                                       \
177
27.2M
  (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \
178
27.2M
   CRYPTO_rotr_u32((x), 25))
179
#define sigma0(x) \
180
20.4M
  (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3))
181
#define sigma1(x) \
182
20.4M
  (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10))
183
184
27.2M
#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
185
27.2M
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
186
187
#define ROUND_00_15(i, a, b, c, d, e, f, g, h)   \
188
27.2M
  do {                                           \
189
27.2M
    T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
190
27.2M
    h = Sigma0(a) + Maj(a, b, c);                \
191
27.2M
    d += T1;                                     \
192
27.2M
    h += T1;                                     \
193
27.2M
  } while (0)
194
195
#define ROUND_16_63(i, a, b, c, d, e, f, g, h, X)      \
196
20.4M
  do {                                                 \
197
20.4M
    s0 = X[(i + 1) & 0x0f];                            \
198
20.4M
    s0 = sigma0(s0);                                   \
199
20.4M
    s1 = X[(i + 14) & 0x0f];                           \
200
20.4M
    s1 = sigma1(s1);                                   \
201
20.4M
    T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \
202
20.4M
    ROUND_00_15(i, a, b, c, d, e, f, g, h);            \
203
20.4M
  } while (0)
204
205
static void sha256_block_data_order_nohw(uint32_t state[8], const uint8_t *data,
206
17.4k
                                         size_t num) {
207
17.4k
  uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
208
17.4k
  uint32_t X[16];
209
17.4k
  int i;
210
211
443k
  while (num--) {
212
425k
    a = state[0];
213
425k
    b = state[1];
214
425k
    c = state[2];
215
425k
    d = state[3];
216
425k
    e = state[4];
217
425k
    f = state[5];
218
425k
    g = state[6];
219
425k
    h = state[7];
220
221
425k
    T1 = X[0] = CRYPTO_load_u32_be(data);
222
425k
    data += 4;
223
425k
    ROUND_00_15(0, a, b, c, d, e, f, g, h);
224
425k
    T1 = X[1] = CRYPTO_load_u32_be(data);
225
425k
    data += 4;
226
425k
    ROUND_00_15(1, h, a, b, c, d, e, f, g);
227
425k
    T1 = X[2] = CRYPTO_load_u32_be(data);
228
425k
    data += 4;
229
425k
    ROUND_00_15(2, g, h, a, b, c, d, e, f);
230
425k
    T1 = X[3] = CRYPTO_load_u32_be(data);
231
425k
    data += 4;
232
425k
    ROUND_00_15(3, f, g, h, a, b, c, d, e);
233
425k
    T1 = X[4] = CRYPTO_load_u32_be(data);
234
425k
    data += 4;
235
425k
    ROUND_00_15(4, e, f, g, h, a, b, c, d);
236
425k
    T1 = X[5] = CRYPTO_load_u32_be(data);
237
425k
    data += 4;
238
425k
    ROUND_00_15(5, d, e, f, g, h, a, b, c);
239
425k
    T1 = X[6] = CRYPTO_load_u32_be(data);
240
425k
    data += 4;
241
425k
    ROUND_00_15(6, c, d, e, f, g, h, a, b);
242
425k
    T1 = X[7] = CRYPTO_load_u32_be(data);
243
425k
    data += 4;
244
425k
    ROUND_00_15(7, b, c, d, e, f, g, h, a);
245
425k
    T1 = X[8] = CRYPTO_load_u32_be(data);
246
425k
    data += 4;
247
425k
    ROUND_00_15(8, a, b, c, d, e, f, g, h);
248
425k
    T1 = X[9] = CRYPTO_load_u32_be(data);
249
425k
    data += 4;
250
425k
    ROUND_00_15(9, h, a, b, c, d, e, f, g);
251
425k
    T1 = X[10] = CRYPTO_load_u32_be(data);
252
425k
    data += 4;
253
425k
    ROUND_00_15(10, g, h, a, b, c, d, e, f);
254
425k
    T1 = X[11] = CRYPTO_load_u32_be(data);
255
425k
    data += 4;
256
425k
    ROUND_00_15(11, f, g, h, a, b, c, d, e);
257
425k
    T1 = X[12] = CRYPTO_load_u32_be(data);
258
425k
    data += 4;
259
425k
    ROUND_00_15(12, e, f, g, h, a, b, c, d);
260
425k
    T1 = X[13] = CRYPTO_load_u32_be(data);
261
425k
    data += 4;
262
425k
    ROUND_00_15(13, d, e, f, g, h, a, b, c);
263
425k
    T1 = X[14] = CRYPTO_load_u32_be(data);
264
425k
    data += 4;
265
425k
    ROUND_00_15(14, c, d, e, f, g, h, a, b);
266
425k
    T1 = X[15] = CRYPTO_load_u32_be(data);
267
425k
    data += 4;
268
425k
    ROUND_00_15(15, b, c, d, e, f, g, h, a);
269
270
2.98M
    for (i = 16; i < 64; i += 8) {
271
2.55M
      ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
272
2.55M
      ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
273
2.55M
      ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
274
2.55M
      ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
275
2.55M
      ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
276
2.55M
      ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
277
2.55M
      ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
278
2.55M
      ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
279
2.55M
    }
280
281
425k
    state[0] += a;
282
425k
    state[1] += b;
283
425k
    state[2] += c;
284
425k
    state[3] += d;
285
425k
    state[4] += e;
286
425k
    state[5] += f;
287
425k
    state[6] += g;
288
425k
    state[7] += h;
289
425k
  }
290
17.4k
}
291
292
#endif  // !defined(SHA256_ASM_NOHW)
293
294
static void sha256_block_data_order(uint32_t state[8], const uint8_t *data,
295
17.4k
                                    size_t num) {
296
#if defined(SHA256_ASM_HW)
297
  if (sha256_hw_capable()) {
298
    sha256_block_data_order_hw(state, data, num);
299
    return;
300
  }
301
#endif
302
#if defined(SHA256_ASM_AVX)
303
  if (sha256_avx_capable()) {
304
    sha256_block_data_order_avx(state, data, num);
305
    return;
306
  }
307
#endif
308
#if defined(SHA256_ASM_SSSE3)
309
  if (sha256_ssse3_capable()) {
310
    sha256_block_data_order_ssse3(state, data, num);
311
    return;
312
  }
313
#endif
314
#if defined(SHA256_ASM_NEON)
315
  if (CRYPTO_is_NEON_capable()) {
316
    sha256_block_data_order_neon(state, data, num);
317
    return;
318
  }
319
#endif
320
17.4k
  sha256_block_data_order_nohw(state, data, num);
321
17.4k
}
322
323
#endif  // !defined(SHA256_ASM)
324
325
326
bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8],
327
                                           const uint8_t *data,
328
0
                                           size_t num_blocks) {
329
0
  sha256_block_data_order(state, data, num_blocks);
330
0
  return bcm_infallible_approved;
331
0
}
332
333
#undef Sigma0
334
#undef Sigma1
335
#undef sigma0
336
#undef sigma1
337
#undef Ch
338
#undef Maj
339
#undef ROUND_00_15
340
#undef ROUND_16_63