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