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 <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 #ifndef SHA256_ASM
118 static void sha256_block_data_order(uint32_t *state, 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,SHA256_CTX * c)136 static int sha256_final_impl(uint8_t *out, 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 (c->md_len > SHA256_DIGEST_LENGTH) {
145 return 0;
146 }
147
148 assert(c->md_len % 4 == 0);
149 const size_t out_words = c->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);
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 // SHA224_Init sets |ctx->md_len| to |SHA224_DIGEST_LENGTH|, so this has a
170 // smaller output.
171 assert(ctx->md_len == SHA224_DIGEST_LENGTH);
172 return sha256_final_impl(out, ctx);
173 }
174
175 #ifndef SHA256_ASM
176 static const uint32_t K256[64] = {
177 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
178 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
179 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
180 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
181 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
182 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
183 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
184 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
185 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
186 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
187 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
188 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
189 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
190
191 // See FIPS 180-4, section 4.1.2.
192 #define Sigma0(x) \
193 (CRYPTO_rotr_u32((x), 2) ^ CRYPTO_rotr_u32((x), 13) ^ \
194 CRYPTO_rotr_u32((x), 22))
195 #define Sigma1(x) \
196 (CRYPTO_rotr_u32((x), 6) ^ CRYPTO_rotr_u32((x), 11) ^ \
197 CRYPTO_rotr_u32((x), 25))
198 #define sigma0(x) \
199 (CRYPTO_rotr_u32((x), 7) ^ CRYPTO_rotr_u32((x), 18) ^ ((x) >> 3))
200 #define sigma1(x) \
201 (CRYPTO_rotr_u32((x), 17) ^ CRYPTO_rotr_u32((x), 19) ^ ((x) >> 10))
202
203 #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
204 #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
205
206 #define ROUND_00_15(i, a, b, c, d, e, f, g, h) \
207 do { \
208 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
209 h = Sigma0(a) + Maj(a, b, c); \
210 d += T1; \
211 h += T1; \
212 } while (0)
213
214 #define ROUND_16_63(i, a, b, c, d, e, f, g, h, X) \
215 do { \
216 s0 = X[(i + 1) & 0x0f]; \
217 s0 = sigma0(s0); \
218 s1 = X[(i + 14) & 0x0f]; \
219 s1 = sigma1(s1); \
220 T1 = X[(i) & 0x0f] += s0 + s1 + X[(i + 9) & 0x0f]; \
221 ROUND_00_15(i, a, b, c, d, e, f, g, h); \
222 } while (0)
223
sha256_block_data_order(uint32_t * state,const uint8_t * data,size_t num)224 static void sha256_block_data_order(uint32_t *state, const uint8_t *data,
225 size_t num) {
226 uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
227 uint32_t X[16];
228 int i;
229
230 while (num--) {
231 a = state[0];
232 b = state[1];
233 c = state[2];
234 d = state[3];
235 e = state[4];
236 f = state[5];
237 g = state[6];
238 h = state[7];
239
240 T1 = X[0] = CRYPTO_load_u32_be(data);
241 data += 4;
242 ROUND_00_15(0, a, b, c, d, e, f, g, h);
243 T1 = X[1] = CRYPTO_load_u32_be(data);
244 data += 4;
245 ROUND_00_15(1, h, a, b, c, d, e, f, g);
246 T1 = X[2] = CRYPTO_load_u32_be(data);
247 data += 4;
248 ROUND_00_15(2, g, h, a, b, c, d, e, f);
249 T1 = X[3] = CRYPTO_load_u32_be(data);
250 data += 4;
251 ROUND_00_15(3, f, g, h, a, b, c, d, e);
252 T1 = X[4] = CRYPTO_load_u32_be(data);
253 data += 4;
254 ROUND_00_15(4, e, f, g, h, a, b, c, d);
255 T1 = X[5] = CRYPTO_load_u32_be(data);
256 data += 4;
257 ROUND_00_15(5, d, e, f, g, h, a, b, c);
258 T1 = X[6] = CRYPTO_load_u32_be(data);
259 data += 4;
260 ROUND_00_15(6, c, d, e, f, g, h, a, b);
261 T1 = X[7] = CRYPTO_load_u32_be(data);
262 data += 4;
263 ROUND_00_15(7, b, c, d, e, f, g, h, a);
264 T1 = X[8] = CRYPTO_load_u32_be(data);
265 data += 4;
266 ROUND_00_15(8, a, b, c, d, e, f, g, h);
267 T1 = X[9] = CRYPTO_load_u32_be(data);
268 data += 4;
269 ROUND_00_15(9, h, a, b, c, d, e, f, g);
270 T1 = X[10] = CRYPTO_load_u32_be(data);
271 data += 4;
272 ROUND_00_15(10, g, h, a, b, c, d, e, f);
273 T1 = X[11] = CRYPTO_load_u32_be(data);
274 data += 4;
275 ROUND_00_15(11, f, g, h, a, b, c, d, e);
276 T1 = X[12] = CRYPTO_load_u32_be(data);
277 data += 4;
278 ROUND_00_15(12, e, f, g, h, a, b, c, d);
279 T1 = X[13] = CRYPTO_load_u32_be(data);
280 data += 4;
281 ROUND_00_15(13, d, e, f, g, h, a, b, c);
282 T1 = X[14] = CRYPTO_load_u32_be(data);
283 data += 4;
284 ROUND_00_15(14, c, d, e, f, g, h, a, b);
285 T1 = X[15] = CRYPTO_load_u32_be(data);
286 data += 4;
287 ROUND_00_15(15, b, c, d, e, f, g, h, a);
288
289 for (i = 16; i < 64; i += 8) {
290 ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
291 ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
292 ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
293 ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
294 ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
295 ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
296 ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
297 ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
298 }
299
300 state[0] += a;
301 state[1] += b;
302 state[2] += c;
303 state[3] += d;
304 state[4] += e;
305 state[5] += f;
306 state[6] += g;
307 state[7] += h;
308 }
309 }
310
311 #endif // !SHA256_ASM
312
SHA256_TransformBlocks(uint32_t state[8],const uint8_t * data,size_t num_blocks)313 void SHA256_TransformBlocks(uint32_t state[8], const uint8_t *data,
314 size_t num_blocks) {
315 sha256_block_data_order(state, data, num_blocks);
316 }
317
318 #undef Sigma0
319 #undef Sigma1
320 #undef sigma0
321 #undef sigma1
322 #undef Ch
323 #undef Maj
324 #undef ROUND_00_15
325 #undef ROUND_16_63
326