Coverage Report

Created: 2024-11-21 06:47

/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
0
bcm_infallible BCM_sha224_init(SHA256_CTX *sha) {
69
0
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
70
0
  sha->h[0] = 0xc1059ed8UL;
71
0
  sha->h[1] = 0x367cd507UL;
72
0
  sha->h[2] = 0x3070dd17UL;
73
0
  sha->h[3] = 0xf70e5939UL;
74
0
  sha->h[4] = 0xffc00b31UL;
75
0
  sha->h[5] = 0x68581511UL;
76
0
  sha->h[6] = 0x64f98fa7UL;
77
0
  sha->h[7] = 0xbefa4fa4UL;
78
0
  sha->md_len = BCM_SHA224_DIGEST_LENGTH;
79
0
  return bcm_infallible_approved;
80
0
}
81
82
0
bcm_infallible BCM_sha256_init(SHA256_CTX *sha) {
83
0
  OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
84
0
  sha->h[0] = 0x6a09e667UL;
85
0
  sha->h[1] = 0xbb67ae85UL;
86
0
  sha->h[2] = 0x3c6ef372UL;
87
0
  sha->h[3] = 0xa54ff53aUL;
88
0
  sha->h[4] = 0x510e527fUL;
89
0
  sha->h[5] = 0x9b05688cUL;
90
0
  sha->h[6] = 0x1f83d9abUL;
91
0
  sha->h[7] = 0x5be0cd19UL;
92
0
  sha->md_len = BCM_SHA256_DIGEST_LENGTH;
93
0
  return bcm_infallible_approved;
94
0
}
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
0
bcm_infallible BCM_sha256_update(SHA256_CTX *c, const void *data, size_t len) {
108
0
  crypto_md32_update(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
109
0
                     &c->num, &c->Nh, &c->Nl, data, len);
110
0
  return bcm_infallible_approved;
111
0
}
112
113
bcm_infallible BCM_sha224_update(SHA256_CTX *ctx, const void *data,
114
0
                                 size_t len) {
115
0
  return BCM_sha256_update(ctx, data, len);
116
0
}
117
118
0
static void sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
119
0
  crypto_md32_final(&sha256_block_data_order, c->h, c->data, BCM_SHA256_CBLOCK,
120
0
                    &c->num, c->Nh, c->Nl, /*is_big_endian=*/1);
121
122
0
  BSSL_CHECK(md_len <= BCM_SHA256_DIGEST_LENGTH);
123
124
0
  assert(md_len % 4 == 0);
125
0
  const size_t out_words = md_len / 4;
126
0
  for (size_t i = 0; i < out_words; i++) {
127
0
    CRYPTO_store_u32_be(out, c->h[i]);
128
0
    out += 4;
129
0
  }
130
131
0
  FIPS_service_indicator_update_state();
132
0
}
133
134
bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
135
0
                                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
0
  sha256_final_impl(out, c->md_len, c);
142
0
  return bcm_infallible_approved;
143
0
}
144
145
bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
146
0
                                SHA256_CTX *ctx) {
147
  // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
148
  // to |BCM_SHA224_DIGEST_LENGTH|.
149
0
  assert(ctx->md_len == BCM_SHA224_DIGEST_LENGTH);
150
0
  sha256_final_impl(out, BCM_SHA224_DIGEST_LENGTH, ctx);
151
0
  return bcm_infallible_approved;
152
0
}
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
  (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \
175
   CRYPTO_rotr_u32((x), 22))
176
#define Sigma1(x)                                       \
177
  (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \
178
   CRYPTO_rotr_u32((x), 25))
179
#define sigma0(x) \
180
  (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3))
181
#define sigma1(x) \
182
  (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10))
183
184
#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
185
#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
  do {                                           \
189
    T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
190
    h = Sigma0(a) + Maj(a, b, c);                \
191
    d += T1;                                     \
192
    h += T1;                                     \
193
  } while (0)
194
195
#define ROUND_16_63(i, a, b, c, d, e, f, g, h, X)      \
196
  do {                                                 \
197
    s0 = X[(i + 1) & 0x0f];                            \
198
    s0 = sigma0(s0);                                   \
199
    s1 = X[(i + 14) & 0x0f];                           \
200
    s1 = sigma1(s1);                                   \
201
    T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \
202
    ROUND_00_15(i, a, b, c, d, e, f, g, h);            \
203
  } while (0)
204
205
static void sha256_block_data_order_nohw(uint32_t state[8], const uint8_t *data,
206
                                         size_t num) {
207
  uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
208
  uint32_t X[16];
209
  int i;
210
211
  while (num--) {
212
    a = state[0];
213
    b = state[1];
214
    c = state[2];
215
    d = state[3];
216
    e = state[4];
217
    f = state[5];
218
    g = state[6];
219
    h = state[7];
220
221
    T1 = X[0] = CRYPTO_load_u32_be(data);
222
    data += 4;
223
    ROUND_00_15(0, a, b, c, d, e, f, g, h);
224
    T1 = X[1] = CRYPTO_load_u32_be(data);
225
    data += 4;
226
    ROUND_00_15(1, h, a, b, c, d, e, f, g);
227
    T1 = X[2] = CRYPTO_load_u32_be(data);
228
    data += 4;
229
    ROUND_00_15(2, g, h, a, b, c, d, e, f);
230
    T1 = X[3] = CRYPTO_load_u32_be(data);
231
    data += 4;
232
    ROUND_00_15(3, f, g, h, a, b, c, d, e);
233
    T1 = X[4] = CRYPTO_load_u32_be(data);
234
    data += 4;
235
    ROUND_00_15(4, e, f, g, h, a, b, c, d);
236
    T1 = X[5] = CRYPTO_load_u32_be(data);
237
    data += 4;
238
    ROUND_00_15(5, d, e, f, g, h, a, b, c);
239
    T1 = X[6] = CRYPTO_load_u32_be(data);
240
    data += 4;
241
    ROUND_00_15(6, c, d, e, f, g, h, a, b);
242
    T1 = X[7] = CRYPTO_load_u32_be(data);
243
    data += 4;
244
    ROUND_00_15(7, b, c, d, e, f, g, h, a);
245
    T1 = X[8] = CRYPTO_load_u32_be(data);
246
    data += 4;
247
    ROUND_00_15(8, a, b, c, d, e, f, g, h);
248
    T1 = X[9] = CRYPTO_load_u32_be(data);
249
    data += 4;
250
    ROUND_00_15(9, h, a, b, c, d, e, f, g);
251
    T1 = X[10] = CRYPTO_load_u32_be(data);
252
    data += 4;
253
    ROUND_00_15(10, g, h, a, b, c, d, e, f);
254
    T1 = X[11] = CRYPTO_load_u32_be(data);
255
    data += 4;
256
    ROUND_00_15(11, f, g, h, a, b, c, d, e);
257
    T1 = X[12] = CRYPTO_load_u32_be(data);
258
    data += 4;
259
    ROUND_00_15(12, e, f, g, h, a, b, c, d);
260
    T1 = X[13] = CRYPTO_load_u32_be(data);
261
    data += 4;
262
    ROUND_00_15(13, d, e, f, g, h, a, b, c);
263
    T1 = X[14] = CRYPTO_load_u32_be(data);
264
    data += 4;
265
    ROUND_00_15(14, c, d, e, f, g, h, a, b);
266
    T1 = X[15] = CRYPTO_load_u32_be(data);
267
    data += 4;
268
    ROUND_00_15(15, b, c, d, e, f, g, h, a);
269
270
    for (i = 16; i < 64; i += 8) {
271
      ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
272
      ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
273
      ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
274
      ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
275
      ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
276
      ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
277
      ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
278
      ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
279
    }
280
281
    state[0] += a;
282
    state[1] += b;
283
    state[2] += c;
284
    state[3] += d;
285
    state[4] += e;
286
    state[5] += f;
287
    state[6] += g;
288
    state[7] += h;
289
  }
290
}
291
292
#endif  // !defined(SHA256_ASM_NOHW)
293
294
static void sha256_block_data_order(uint32_t state[8], const uint8_t *data,
295
0
                                    size_t num) {
296
0
#if defined(SHA256_ASM_HW)
297
0
  if (sha256_hw_capable()) {
298
0
    sha256_block_data_order_hw(state, data, num);
299
0
    return;
300
0
  }
301
0
#endif
302
0
#if defined(SHA256_ASM_AVX)
303
0
  if (sha256_avx_capable()) {
304
0
    sha256_block_data_order_avx(state, data, num);
305
0
    return;
306
0
  }
307
0
#endif
308
0
#if defined(SHA256_ASM_SSSE3)
309
0
  if (sha256_ssse3_capable()) {
310
0
    sha256_block_data_order_ssse3(state, data, num);
311
0
    return;
312
0
  }
313
0
#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
0
  sha256_block_data_order_nohw(state, data, num);
321
0
}
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