File Coverage

inc/matrixssl-3-9-3-open/crypto/digest/sha256.c
Criterion Covered Total %
statement 63 63 100.0
branch 26 26 100.0
condition n/a
subroutine n/a
pod n/a
total 89 89 100.0


line stmt bran cond sub pod time code
1             /**
2             * @file sha256.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * SHA256 hash implementation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             #ifdef USE_MATRIX_SHA256
38              
39             /******************************************************************************/
40              
41             # ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
42              
43             /* The K array */
44             static const uint32_t K[64] = {
45             0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
46             0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
47             0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
48             0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
49             0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
50             0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
51             0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
52             0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
53             0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
54             0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
55             0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
56             0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
57             0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
58             };
59             # endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
60              
61             /* Various logical functions */
62             # define Ch(x, y, z) (z ^ (x & (y ^ z)))
63             # define Maj(x, y, z) (((x | y) & z) | (x & y))
64             # define S(x, n) ROR((x), (n))
65             # define R(x, n) (((x) & 0xFFFFFFFFUL) >> (n))
66             # define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
67             # define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
68             # define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
69             # define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
70              
71             /*
72             compress 512-bits
73             */
74             # ifdef USE_BURN_STACK
75 106769           static void _sha256_compress(psSha256_t *sha256, const unsigned char *buf)
76             # else
77             static void sha256_compress(psSha256_t *sha256, const unsigned char *buf)
78             # endif /* CLEAN_STACK */
79             {
80              
81             uint32 S[8], W[64], t0, t1;
82             # ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
83             uint32 t;
84             # endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
85             int32 i;
86              
87             /* copy state into S */
88 960921 100         for (i = 0; i < 8; i++)
89             {
90 854152           S[i] = sha256->state[i];
91             }
92              
93             /* copy the state into 512-bits into W[0..15] */
94 1815073 100         for (i = 0; i < 16; i++)
95             {
96 1708304           LOAD32H(W[i], buf + (4 * i));
97             }
98              
99             /* fill W[16..63] */
100 5231681 100         for (i = 16; i < 64; i++)
101             {
102 5124912           W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
103             }
104              
105             /* Compress */
106             # ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
107             # define RND(a, b, c, d, e, f, g, h, i) \
108             t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
109             t1 = Sigma0(a) + Maj(a, b, c); \
110             d += t0; \
111             h = t0 + t1;
112              
113 6939985 100         for (i = 0; i < 64; ++i)
114             {
115 6833216           RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
116 6833216           t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
117 6833216           S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
118             }
119             # else /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
120             # define RND(a, b, c, d, e, f, g, h, i, ki) \
121             t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
122             t1 = Sigma0(a) + Maj(a, b, c); \
123             d += t0; \
124             h = t0 + t1;
125              
126             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 0, 0x428a2f98);
127             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 1, 0x71374491);
128             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 2, 0xb5c0fbcf);
129             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 3, 0xe9b5dba5);
130             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 4, 0x3956c25b);
131             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 5, 0x59f111f1);
132             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 6, 0x923f82a4);
133             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 7, 0xab1c5ed5);
134             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 8, 0xd807aa98);
135             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 9, 0x12835b01);
136             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 10, 0x243185be);
137             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 11, 0x550c7dc3);
138             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 12, 0x72be5d74);
139             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 13, 0x80deb1fe);
140             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 14, 0x9bdc06a7);
141             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 15, 0xc19bf174);
142             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 16, 0xe49b69c1);
143             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 17, 0xefbe4786);
144             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 18, 0x0fc19dc6);
145             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 19, 0x240ca1cc);
146             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 20, 0x2de92c6f);
147             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 21, 0x4a7484aa);
148             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 22, 0x5cb0a9dc);
149             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 23, 0x76f988da);
150             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 24, 0x983e5152);
151             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 25, 0xa831c66d);
152             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 26, 0xb00327c8);
153             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 27, 0xbf597fc7);
154             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 28, 0xc6e00bf3);
155             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 29, 0xd5a79147);
156             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 30, 0x06ca6351);
157             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 31, 0x14292967);
158             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 32, 0x27b70a85);
159             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 33, 0x2e1b2138);
160             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 34, 0x4d2c6dfc);
161             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 35, 0x53380d13);
162             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 36, 0x650a7354);
163             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 37, 0x766a0abb);
164             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 38, 0x81c2c92e);
165             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 39, 0x92722c85);
166             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 40, 0xa2bfe8a1);
167             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 41, 0xa81a664b);
168             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 42, 0xc24b8b70);
169             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 43, 0xc76c51a3);
170             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 44, 0xd192e819);
171             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 45, 0xd6990624);
172             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 46, 0xf40e3585);
173             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 47, 0x106aa070);
174             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 48, 0x19a4c116);
175             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 49, 0x1e376c08);
176             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 50, 0x2748774c);
177             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 51, 0x34b0bcb5);
178             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 52, 0x391c0cb3);
179             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 53, 0x4ed8aa4a);
180             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 54, 0x5b9cca4f);
181             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 55, 0x682e6ff3);
182             RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 56, 0x748f82ee);
183             RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 57, 0x78a5636f);
184             RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 58, 0x84c87814);
185             RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 59, 0x8cc70208);
186             RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 60, 0x90befffa);
187             RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 61, 0xa4506ceb);
188             RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 62, 0xbef9a3f7);
189             RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 63, 0xc67178f2);
190              
191             # undef RND
192              
193             # endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
194              
195             /* feedback */
196 960921 100         for (i = 0; i < 8; i++)
197             {
198 854152           sha256->state[i] = sha256->state[i] + S[i];
199             }
200              
201 106769           }
202              
203             # ifdef USE_BURN_STACK
204 106769           static void sha256_compress(psSha256_t *sha256, const unsigned char *buf)
205             {
206 106769           _sha256_compress(sha256, buf);
207 106769           psBurnStack(sizeof(uint32) * 74);
208 106769           }
209             # endif /* USE_BURN_STACK */
210              
211             /******************************************************************************/
212              
213 17066           int32_t psSha256Init(psSha256_t *sha256)
214             {
215             # ifdef CRYPTO_ASSERT
216             psAssert(sha256 != NULL);
217             # endif
218 17066           sha256->curlen = 0;
219 17066           sha256->state[0] = 0x6A09E667UL;
220 17066           sha256->state[1] = 0xBB67AE85UL;
221 17066           sha256->state[2] = 0x3C6EF372UL;
222 17066           sha256->state[3] = 0xA54FF53AUL;
223 17066           sha256->state[4] = 0x510E527FUL;
224 17066           sha256->state[5] = 0x9B05688CUL;
225 17066           sha256->state[6] = 0x1F83D9ABUL;
226 17066           sha256->state[7] = 0x5BE0CD19UL;
227             # ifdef HAVE_NATIVE_INT64
228 17066           sha256->length = 0;
229             # else
230             sha256->lengthHi = 0;
231             sha256->lengthLo = 0;
232             # endif /* HAVE_NATIVE_INT64 */
233 17066           return PS_SUCCESS;
234             }
235              
236             /******************************************************************************/
237              
238 36946           void psSha256Update(psSha256_t *sha256, const unsigned char *buf, uint32_t len)
239             {
240             uint32 n;
241              
242             # ifdef CRYPTO_ASSERT
243             psAssert(sha256 != NULL);
244             psAssert(buf != NULL);
245             # endif
246              
247 173575 100         while (len > 0)
248             {
249 136629 100         if (sha256->curlen == 0 && len >= 64)
    100          
250             {
251 88735           sha256_compress(sha256, (unsigned char *) buf);
252             # ifdef HAVE_NATIVE_INT64
253 88735           sha256->length += 512;
254             # else
255             n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
256             if (n < sha256->lengthLo)
257             {
258             sha256->lengthHi++;
259             }
260             sha256->lengthLo = n;
261             # endif /* HAVE_NATIVE_INT64 */
262 88735           buf += 64;
263 88735           len -= 64;
264             }
265             else
266             {
267 47894           n = min(len, (64 - sha256->curlen));
268 47894           memcpy(sha256->buf + sha256->curlen, buf, (size_t) n);
269 47894           sha256->curlen += n;
270 47894           buf += n;
271 47894           len -= n;
272              
273 47894 100         if (sha256->curlen == 64)
274             {
275 13247           sha256_compress(sha256, sha256->buf);
276             # ifdef HAVE_NATIVE_INT64
277 13247           sha256->length += 512;
278             # else
279             n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
280             if (n < sha256->lengthLo)
281             {
282             sha256->lengthHi++;
283             }
284             sha256->lengthLo = n;
285             # endif /* HAVE_NATIVE_INT64 */
286 13247           sha256->curlen = 0;
287             }
288             }
289             }
290 36946           return;
291             }
292              
293             /******************************************************************************/
294              
295 4762           void psSha256Final(psSha256_t *sha256, unsigned char hash[SHA256_HASHLEN])
296             {
297             int32 i;
298              
299             # ifndef HAVE_NATIVE_INT64
300             uint32 n;
301             # endif
302              
303             # ifdef CRYPTO_ASSERT
304             psAssert(sha256 != NULL);
305             psAssert(hash != NULL);
306             if (sha256->curlen >= sizeof(sha256->buf))
307             {
308             psTraceCrypto("psSha256Final error\n");
309             return;
310             }
311             # endif
312              
313             /* increase the length of the message */
314             # ifdef HAVE_NATIVE_INT64
315 4762           sha256->length += sha256->curlen << 3;
316             # else
317             n = (sha256->lengthLo + (sha256->curlen << 3)) & 0xFFFFFFFFL;
318             if (n < sha256->lengthLo)
319             {
320             sha256->lengthHi++;
321             }
322             sha256->lengthHi += (sha256->curlen >> 29);
323             sha256->lengthLo = n;
324             # endif /* HAVE_NATIVE_INT64 */
325              
326             /* append the '1' bit */
327 4762           sha256->buf[sha256->curlen++] = (unsigned char) 0x80;
328              
329             /*
330             if the length is currently above 56 bytes we append zeros then compress.
331             Then we can fall back to padding zeros and length encoding like normal.
332             */
333 4762 100         if (sha256->curlen > 56)
334             {
335 145 100         while (sha256->curlen < 64)
336             {
337 120           sha256->buf[sha256->curlen++] = (unsigned char) 0;
338             }
339 25           sha256_compress(sha256, sha256->buf);
340 25           sha256->curlen = 0;
341             }
342             /* pad upto 56 bytes of zeroes */
343 175148 100         while (sha256->curlen < 56)
344             {
345 170386           sha256->buf[sha256->curlen++] = (unsigned char) 0;
346             }
347              
348             /* store length */
349             # ifdef HAVE_NATIVE_INT64
350 4762           STORE64H(sha256->length, sha256->buf + 56);
351             # else
352             STORE32H(sha256->lengthHi, sha256->buf + 56);
353             STORE32H(sha256->lengthLo, sha256->buf + 60);
354             # endif /* HAVE_NATIVE_INT64 */
355 4762           sha256_compress(sha256, sha256->buf);
356              
357             /* copy output */
358 42858 100         for (i = 0; i < 8; i++)
359             {
360 38096           STORE32H(sha256->state[i], hash + (4 * i));
361             }
362 4762           memset(sha256, 0x0, sizeof(psSha256_t));
363 4762           }
364              
365             # ifdef USE_SHA224
366             /******************************************************************************/
367              
368             void psSha224Init(psSha256_t *sha256)
369             {
370             # ifdef CRYPTO_ASSERT
371             psAssert(sha256 != NULL);
372             # endif
373              
374             sha256->curlen = 0;
375             # ifdef HAVE_NATIVE_INT64
376             sha256->length = 0;
377             # else
378             sha256->lengthHi = 0;
379             sha256->lengthLo = 0;
380             # endif /* HAVE_NATIVE_INT64 */
381             sha256->state[0] = 0xc1059ed8UL;
382             sha256->state[1] = 0x367cd507UL;
383             sha256->state[2] = 0x3070dd17UL;
384             sha256->state[3] = 0xf70e5939UL;
385             sha256->state[4] = 0xffc00b31UL;
386             sha256->state[5] = 0x68581511UL;
387             sha256->state[6] = 0x64f98fa7UL;
388             sha256->state[7] = 0xbefa4fa4UL;
389             }
390              
391             /******************************************************************************/
392              
393             void psSha224Update(psSha256_t *sha256, const unsigned char *buf, uint32 len)
394             {
395             psSha256Update(sha256, buf, len);
396             }
397              
398             /******************************************************************************/
399              
400             void psSha224Final(psSha256_t *sha256, unsigned char out[SHA224_HASHLEN])
401             {
402             unsigned char buf[SHA224_HASHLEN];
403              
404             # ifdef CRYPTO_ASSERT
405             psAssert(sha256 != NULL);
406             psAssert(out != NULL);
407             # endif
408             psSha256Final(sha256, buf);
409             memcpy(out, buf, SHA224_HASH_SIZE);
410             # ifdef USE_BURN_STACK
411             psBurnStack(sizeof(buf));
412             # endif
413             }
414             # endif /* USE_SHA224 */
415              
416             #endif /* USE_MATRIX_SHA256 */
417              
418             /******************************************************************************/
419