xref: /aosp_15_r20/external/boringssl/src/crypto/fipsmodule/sha/sha256.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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 <openssl/sha.h>
58 
59 #include <string.h>
60 
61 #include <openssl/mem.h>
62 
63 #include "../../internal.h"
64 #include "../digest/md32_common.h"
65 #include "../service_indicator/internal.h"
66 #include "internal.h"
67 
68 
SHA224_Init(SHA256_CTX * sha)69 int SHA224_Init(SHA256_CTX *sha) {
70   OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
71   sha->h[0] = 0xc1059ed8UL;
72   sha->h[1] = 0x367cd507UL;
73   sha->h[2] = 0x3070dd17UL;
74   sha->h[3] = 0xf70e5939UL;
75   sha->h[4] = 0xffc00b31UL;
76   sha->h[5] = 0x68581511UL;
77   sha->h[6] = 0x64f98fa7UL;
78   sha->h[7] = 0xbefa4fa4UL;
79   sha->md_len = SHA224_DIGEST_LENGTH;
80   return 1;
81 }
82 
SHA256_Init(SHA256_CTX * sha)83 int SHA256_Init(SHA256_CTX *sha) {
84   OPENSSL_memset(sha, 0, sizeof(SHA256_CTX));
85   sha->h[0] = 0x6a09e667UL;
86   sha->h[1] = 0xbb67ae85UL;
87   sha->h[2] = 0x3c6ef372UL;
88   sha->h[3] = 0xa54ff53aUL;
89   sha->h[4] = 0x510e527fUL;
90   sha->h[5] = 0x9b05688cUL;
91   sha->h[6] = 0x1f83d9abUL;
92   sha->h[7] = 0x5be0cd19UL;
93   sha->md_len = SHA256_DIGEST_LENGTH;
94   return 1;
95 }
96 
SHA224(const uint8_t * data,size_t len,uint8_t out[SHA224_DIGEST_LENGTH])97 uint8_t *SHA224(const uint8_t *data, size_t len,
98                 uint8_t out[SHA224_DIGEST_LENGTH]) {
99   SHA256_CTX ctx;
100   SHA224_Init(&ctx);
101   SHA224_Update(&ctx, data, len);
102   SHA224_Final(out, &ctx);
103   OPENSSL_cleanse(&ctx, sizeof(ctx));
104   return out;
105 }
106 
SHA256(const uint8_t * data,size_t len,uint8_t out[SHA256_DIGEST_LENGTH])107 uint8_t *SHA256(const uint8_t *data, size_t len,
108                 uint8_t out[SHA256_DIGEST_LENGTH]) {
109   SHA256_CTX ctx;
110   SHA256_Init(&ctx);
111   SHA256_Update(&ctx, data, len);
112   SHA256_Final(out, &ctx);
113   OPENSSL_cleanse(&ctx, sizeof(ctx));
114   return out;
115 }
116 
117 #if !defined(SHA256_ASM)
118 static void sha256_block_data_order(uint32_t state[8], const uint8_t *in,
119                                     size_t num);
120 #endif
121 
SHA256_Transform(SHA256_CTX * c,const uint8_t data[SHA256_CBLOCK])122 void SHA256_Transform(SHA256_CTX *c, const uint8_t data[SHA256_CBLOCK]) {
123   sha256_block_data_order(c->h, data, 1);
124 }
125 
SHA256_Update(SHA256_CTX * c,const void * data,size_t len)126 int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) {
127   crypto_md32_update(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK,
128                      &c->num, &c->Nh, &c->Nl, data, len);
129   return 1;
130 }
131 
SHA224_Update(SHA256_CTX * ctx,const void * data,size_t len)132 int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) {
133   return SHA256_Update(ctx, data, len);
134 }
135 
sha256_final_impl(uint8_t * out,size_t md_len,SHA256_CTX * c)136 static int sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) {
137   crypto_md32_final(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK,
138                     &c->num, c->Nh, c->Nl, /*is_big_endian=*/1);
139 
140   // TODO(davidben): This overflow check one of the few places a low-level hash
141   // 'final' function can fail. SHA-512 does not have a corresponding check.
142   // These functions already misbehave if the caller arbitrarily mutates |c|, so
143   // can we assume one of |SHA256_Init| or |SHA224_Init| was used?
144   if (md_len > SHA256_DIGEST_LENGTH) {
145     return 0;
146   }
147 
148   assert(md_len % 4 == 0);
149   const size_t out_words = md_len / 4;
150   for (size_t i = 0; i < out_words; i++) {
151     CRYPTO_store_u32_be(out, c->h[i]);
152     out += 4;
153   }
154 
155   FIPS_service_indicator_update_state();
156   return 1;
157 }
158 
SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH],SHA256_CTX * c)159 int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *c) {
160   // Ideally we would assert |sha->md_len| is |SHA256_DIGEST_LENGTH| to match
161   // the size hint, but calling code often pairs |SHA224_Init| with
162   // |SHA256_Final| and expects |sha->md_len| to carry the size over.
163   //
164   // TODO(davidben): Add an assert and fix code to match them up.
165   return sha256_final_impl(out, c->md_len, c);
166 }
167 
SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH],SHA256_CTX * ctx)168 int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *ctx) {
169   // This function must be paired with |SHA224_Init|, which sets |ctx->md_len|
170   // to |SHA224_DIGEST_LENGTH|.
171   assert(ctx->md_len == SHA224_DIGEST_LENGTH);
172   return sha256_final_impl(out, SHA224_DIGEST_LENGTH, ctx);
173 }
174 
175 #if !defined(SHA256_ASM)
176 
177 #if !defined(SHA256_ASM_NOHW)
178 static const uint32_t K256[64] = {
179     0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
180     0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
181     0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
182     0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
183     0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
184     0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
185     0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
186     0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
187     0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
188     0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
189     0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
190     0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
191     0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
192 
193 // See FIPS 180-4, section 4.1.2.
194 #define Sigma0(x)                                       \
195   (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \
196    CRYPTO_rotr_u32((x), 22))
197 #define Sigma1(x)                                       \
198   (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \
199    CRYPTO_rotr_u32((x), 25))
200 #define sigma0(x) \
201   (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3))
202 #define sigma1(x) \
203   (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10))
204 
205 #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
206 #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
207 
208 #define ROUND_00_15(i, a, b, c, d, e, f, g, h)   \
209   do {                                           \
210     T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
211     h = Sigma0(a) + Maj(a, b, c);                \
212     d += T1;                                     \
213     h += T1;                                     \
214   } while (0)
215 
216 #define ROUND_16_63(i, a, b, c, d, e, f, g, h, X)      \
217   do {                                                 \
218     s0 = X[(i + 1) & 0x0f];                            \
219     s0 = sigma0(s0);                                   \
220     s1 = X[(i + 14) & 0x0f];                           \
221     s1 = sigma1(s1);                                   \
222     T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \
223     ROUND_00_15(i, a, b, c, d, e, f, g, h);            \
224   } while (0)
225 
sha256_block_data_order_nohw(uint32_t state[8],const uint8_t * data,size_t num)226 static void sha256_block_data_order_nohw(uint32_t state[8], const uint8_t *data,
227                                          size_t num) {
228   uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
229   uint32_t X[16];
230   int i;
231 
232   while (num--) {
233     a = state[0];
234     b = state[1];
235     c = state[2];
236     d = state[3];
237     e = state[4];
238     f = state[5];
239     g = state[6];
240     h = state[7];
241 
242     T1 = X[0] = CRYPTO_load_u32_be(data);
243     data += 4;
244     ROUND_00_15(0, a, b, c, d, e, f, g, h);
245     T1 = X[1] = CRYPTO_load_u32_be(data);
246     data += 4;
247     ROUND_00_15(1, h, a, b, c, d, e, f, g);
248     T1 = X[2] = CRYPTO_load_u32_be(data);
249     data += 4;
250     ROUND_00_15(2, g, h, a, b, c, d, e, f);
251     T1 = X[3] = CRYPTO_load_u32_be(data);
252     data += 4;
253     ROUND_00_15(3, f, g, h, a, b, c, d, e);
254     T1 = X[4] = CRYPTO_load_u32_be(data);
255     data += 4;
256     ROUND_00_15(4, e, f, g, h, a, b, c, d);
257     T1 = X[5] = CRYPTO_load_u32_be(data);
258     data += 4;
259     ROUND_00_15(5, d, e, f, g, h, a, b, c);
260     T1 = X[6] = CRYPTO_load_u32_be(data);
261     data += 4;
262     ROUND_00_15(6, c, d, e, f, g, h, a, b);
263     T1 = X[7] = CRYPTO_load_u32_be(data);
264     data += 4;
265     ROUND_00_15(7, b, c, d, e, f, g, h, a);
266     T1 = X[8] = CRYPTO_load_u32_be(data);
267     data += 4;
268     ROUND_00_15(8, a, b, c, d, e, f, g, h);
269     T1 = X[9] = CRYPTO_load_u32_be(data);
270     data += 4;
271     ROUND_00_15(9, h, a, b, c, d, e, f, g);
272     T1 = X[10] = CRYPTO_load_u32_be(data);
273     data += 4;
274     ROUND_00_15(10, g, h, a, b, c, d, e, f);
275     T1 = X[11] = CRYPTO_load_u32_be(data);
276     data += 4;
277     ROUND_00_15(11, f, g, h, a, b, c, d, e);
278     T1 = X[12] = CRYPTO_load_u32_be(data);
279     data += 4;
280     ROUND_00_15(12, e, f, g, h, a, b, c, d);
281     T1 = X[13] = CRYPTO_load_u32_be(data);
282     data += 4;
283     ROUND_00_15(13, d, e, f, g, h, a, b, c);
284     T1 = X[14] = CRYPTO_load_u32_be(data);
285     data += 4;
286     ROUND_00_15(14, c, d, e, f, g, h, a, b);
287     T1 = X[15] = CRYPTO_load_u32_be(data);
288     data += 4;
289     ROUND_00_15(15, b, c, d, e, f, g, h, a);
290 
291     for (i = 16; i < 64; i += 8) {
292       ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
293       ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
294       ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
295       ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
296       ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
297       ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
298       ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
299       ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
300     }
301 
302     state[0] += a;
303     state[1] += b;
304     state[2] += c;
305     state[3] += d;
306     state[4] += e;
307     state[5] += f;
308     state[6] += g;
309     state[7] += h;
310   }
311 }
312 
313 #endif  // !defined(SHA256_ASM_NOHW)
314 
sha256_block_data_order(uint32_t state[8],const uint8_t * data,size_t num)315 static void sha256_block_data_order(uint32_t state[8], const uint8_t *data,
316                                     size_t num) {
317 #if defined(SHA256_ASM_HW)
318   if (sha256_hw_capable()) {
319     sha256_block_data_order_hw(state, data, num);
320     return;
321   }
322 #endif
323 #if defined(SHA256_ASM_AVX)
324   if (sha256_avx_capable()) {
325     sha256_block_data_order_avx(state, data, num);
326     return;
327   }
328 #endif
329 #if defined(SHA256_ASM_SSSE3)
330   if (sha256_ssse3_capable()) {
331     sha256_block_data_order_ssse3(state, data, num);
332     return;
333   }
334 #endif
335 #if defined(SHA256_ASM_NEON)
336   if (CRYPTO_is_NEON_capable()) {
337     sha256_block_data_order_neon(state, data, num);
338     return;
339   }
340 #endif
341   sha256_block_data_order_nohw(state, data, num);
342 }
343 
344 #endif  // !defined(SHA256_ASM)
345 
346 
SHA256_TransformBlocks(uint32_t state[8],const uint8_t * data,size_t num_blocks)347 void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data,
348                             size_t num_blocks) {
349   sha256_block_data_order(state, data, num_blocks);
350 }
351 
352 #undef Sigma0
353 #undef Sigma1
354 #undef sigma0
355 #undef sigma1
356 #undef Ch
357 #undef Maj
358 #undef ROUND_00_15
359 #undef ROUND_16_63
360