• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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