File Coverage

inc/matrixssl-3-9-3-open/crypto/digest/sha1.c
Criterion Covered Total %
statement 81 81 100.0
branch 24 24 100.0
condition n/a
subroutine n/a
pod n/a
total 105 105 100.0


line stmt bran cond sub pod time code
1             /**
2             * @file sha1.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * SHA1 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_SHA1
38              
39             /******************************************************************************/
40              
41             # define F0(x, y, z) (z ^ (x & (y ^ z)))
42             # define F1(x, y, z) (x ^ y ^ z)
43             # define F2(x, y, z) ((x & y) | (z & (x | y)))
44             # define F3(x, y, z) (x ^ y ^ z)
45              
46             # ifdef USE_BURN_STACK
47 313036           static void _sha1_compress(psSha1_t *sha1)
48             # else
49             static void sha1_compress(psSha1_t *sha1)
50             # endif /* USE_BURN_STACK */
51             {
52             uint32 a, b, c, d, e, W[80], i;
53              
54             # ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
55             uint32 t;
56             # endif
57              
58             /* copy the state into 512-bits into W[0..15] */
59 5321612 100         for (i = 0; i < 16; i++)
60             {
61 5008576           LOAD32H(W[i], sha1->buf + (4 * i));
62             }
63              
64             /* copy state */
65 313036           a = sha1->state[0];
66 313036           b = sha1->state[1];
67 313036           c = sha1->state[2];
68 313036           d = sha1->state[3];
69 313036           e = sha1->state[4];
70              
71             /* expand it */
72 20347340 100         for (i = 16; i < 80; i++)
73             {
74 20034304           W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
75             }
76              
77             /* compress round one */
78             # define FF0(a, b, c, d, e, i) e = (ROL(a, 5) + F0(b, c, d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);
79             # define FF1(a, b, c, d, e, i) e = (ROL(a, 5) + F1(b, c, d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);
80             # define FF2(a, b, c, d, e, i) e = (ROL(a, 5) + F2(b, c, d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
81             # define FF3(a, b, c, d, e, i) e = (ROL(a, 5) + F3(b, c, d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
82              
83             # ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
84             for (i = 0; i < 20; )
85             {
86             FF0(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
87             }
88              
89             for (; i < 40; )
90             {
91             FF1(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
92             }
93              
94             for (; i < 60; )
95             {
96             FF2(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
97             }
98              
99             for (; i < 80; )
100             {
101             FF3(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
102             }
103             # else /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
104 1565180 100         for (i = 0; i < 20; )
105             {
106 1252144           FF0(a, b, c, d, e, i++);
107 1252144           FF0(e, a, b, c, d, i++);
108 1252144           FF0(d, e, a, b, c, i++);
109 1252144           FF0(c, d, e, a, b, i++);
110 1252144           FF0(b, c, d, e, a, i++);
111             }
112              
113             /* round two */
114 1565180 100         for (; i < 40; )
115             {
116 1252144           FF1(a, b, c, d, e, i++);
117 1252144           FF1(e, a, b, c, d, i++);
118 1252144           FF1(d, e, a, b, c, i++);
119 1252144           FF1(c, d, e, a, b, i++);
120 1252144           FF1(b, c, d, e, a, i++);
121             }
122              
123             /* round three */
124 1565180 100         for (; i < 60; )
125             {
126 1252144           FF2(a, b, c, d, e, i++);
127 1252144           FF2(e, a, b, c, d, i++);
128 1252144           FF2(d, e, a, b, c, i++);
129 1252144           FF2(c, d, e, a, b, i++);
130 1252144           FF2(b, c, d, e, a, i++);
131             }
132              
133             /* round four */
134 1565180 100         for (; i < 80; )
135             {
136 1252144           FF3(a, b, c, d, e, i++);
137 1252144           FF3(e, a, b, c, d, i++);
138 1252144           FF3(d, e, a, b, c, i++);
139 1252144           FF3(c, d, e, a, b, i++);
140 1252144           FF3(b, c, d, e, a, i++);
141             }
142             # endif /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
143              
144             # undef FF0
145             # undef FF1
146             # undef FF2
147             # undef FF3
148              
149             /* store */
150 313036           sha1->state[0] = sha1->state[0] + a;
151 313036           sha1->state[1] = sha1->state[1] + b;
152 313036           sha1->state[2] = sha1->state[2] + c;
153 313036           sha1->state[3] = sha1->state[3] + d;
154 313036           sha1->state[4] = sha1->state[4] + e;
155 313036           }
156              
157             # ifdef USE_BURN_STACK
158 313036           static void sha1_compress(psSha1_t *sha1)
159             {
160 313036           _sha1_compress(sha1);
161 313036           psBurnStack(sizeof(uint32) * 87);
162 313036           }
163             # endif /* USE_BURN_STACK */
164              
165             /******************************************************************************/
166              
167 172912           int32_t psSha1Init(psSha1_t *sha1)
168             {
169             # ifdef CRYPTO_ASSERT
170             psAssert(sha1 != NULL);
171             # endif
172 172912           sha1->state[0] = 0x67452301UL;
173 172912           sha1->state[1] = 0xefcdab89UL;
174 172912           sha1->state[2] = 0x98badcfeUL;
175 172912           sha1->state[3] = 0x10325476UL;
176 172912           sha1->state[4] = 0xc3d2e1f0UL;
177 172912           sha1->curlen = 0;
178             # ifdef HAVE_NATIVE_INT64
179 172912           sha1->length = 0;
180             # else
181             sha1->lengthHi = 0;
182             sha1->lengthLo = 0;
183             # endif /* HAVE_NATIVE_INT64 */
184 172912           return PS_SUCCESS;
185             }
186              
187 203729           void psSha1Update(psSha1_t *sha1, const unsigned char *buf, uint32_t len)
188             {
189             uint32_t n;
190              
191             # ifdef CRYPTO_ASSERT
192             psAssert(sha1 != NULL);
193             psAssert(buf != NULL);
194             # endif
195 571765 100         while (len > 0)
196             {
197 368036           n = min(len, (64 - sha1->curlen));
198 368036           memcpy(sha1->buf + sha1->curlen, buf, (size_t) n);
199 368036           sha1->curlen += n;
200 368036           buf += n;
201 368036           len -= n;
202              
203             /* is 64 bytes full? */
204 368036 100         if (sha1->curlen == 64)
205             {
206 164535           sha1_compress(sha1);
207             # ifdef HAVE_NATIVE_INT64
208 164535           sha1->length += 512;
209             # else
210             n = (sha1->lengthLo + 512) & 0xFFFFFFFFL;
211             if (n < sha1->lengthLo)
212             {
213             sha1->lengthHi++;
214             }
215             sha1->lengthLo = n;
216             # endif /* HAVE_NATIVE_INT64 */
217 164535           sha1->curlen = 0;
218             }
219             }
220 203729           }
221              
222             /******************************************************************************/
223              
224 148286           void psSha1Final(psSha1_t *sha1, unsigned char hash[SHA1_HASHLEN])
225             {
226             int32 i;
227              
228             # ifndef HAVE_NATIVE_INT64
229             uint32 n;
230             # endif
231             # ifdef CRYPTO_ASSERT
232             psAssert(sha1 != NULL);
233             if (sha1->curlen >= sizeof(sha1->buf) || hash == NULL)
234             {
235             psTraceCrypto("psSha1Final error\n");
236             return;
237             }
238             # endif
239             /* increase the length of the message */
240             # ifdef HAVE_NATIVE_INT64
241 148286           sha1->length += sha1->curlen << 3;
242             # else
243             n = (sha1->lengthLo + (sha1->curlen << 3)) & 0xFFFFFFFFL;
244             if (n < sha1->lengthLo)
245             {
246             sha1->lengthHi++;
247             }
248             sha1->lengthHi += (sha1->curlen >> 29);
249             sha1->lengthLo = n;
250             # endif /* HAVE_NATIVE_INT64 */
251              
252             /* append the '1' bit */
253 148286           sha1->buf[sha1->curlen++] = (unsigned char) 0x80;
254              
255             /*
256             if the length is currently above 56 bytes we append zeros then compress.
257             Then we can fall back to padding zeros and length encoding like normal.
258             */
259 148286 100         if (sha1->curlen > 56)
260             {
261 795 100         while (sha1->curlen < 64)
262             {
263 580           sha1->buf[sha1->curlen++] = (unsigned char) 0;
264             }
265 215           sha1_compress(sha1);
266 215           sha1->curlen = 0;
267             }
268             /* pad upto 56 bytes of zeroes */
269 5329590 100         while (sha1->curlen < 56)
270             {
271 5181304           sha1->buf[sha1->curlen++] = (unsigned char) 0;
272             }
273             /* store length */
274             # ifdef HAVE_NATIVE_INT64
275 148286           STORE64H(sha1->length, sha1->buf + 56);
276             # else
277             STORE32H(sha1->lengthHi, sha1->buf + 56);
278             STORE32H(sha1->lengthLo, sha1->buf + 60);
279             # endif /* HAVE_NATIVE_INT64 */
280 148286           sha1_compress(sha1);
281              
282             /* copy output */
283 889716 100         for (i = 0; i < 5; i++)
284             {
285 741430           STORE32H(sha1->state[i], hash + (4 * i));
286             }
287 148286           memset(sha1, 0x0, sizeof(psSha1_t));
288 148286           }
289              
290             #endif /* USE_MATRIX_SHA1 */
291              
292             /******************************************************************************/
293