File Coverage

deps/libzmq/external/sha1/sha1.c
Criterion Covered Total %
statement 0 185 0.0
branch 0 34 0.0
condition n/a
subroutine n/a
pod n/a
total 0 219 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3             * All rights reserved.
4             *
5             * Redistribution and use in source and binary forms, with or without
6             * modification, are permitted provided that the following conditions
7             * are met:
8             * 1. Redistributions of source code must retain the above copyright
9             * notice, this list of conditions and the following disclaimer.
10             * 2. Redistributions in binary form must reproduce the above copyright
11             * notice, this list of conditions and the following disclaimer in the
12             * documentation and/or other materials provided with the distribution.
13             * 3. Neither the name of the project nor the names of its contributors
14             * may be used to endorse or promote products derived from this software
15             * without specific prior written permission.
16             *
17             * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18             * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19             * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20             * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21             * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22             * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23             * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24             * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25             * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26             * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27             * SUCH DAMAGE.
28             */
29              
30             /*
31             * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
32             * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm
33             * implemented by Jun-ichiro itojun Itoh
34             */
35              
36             #include "sha1.h"
37             #include
38              
39              
40             /* constant table */
41             static uint32_t _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
42              
43             #define K(t) _K[(t) / 20]
44              
45             #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
46             #define F1(b, c, d) (((b) ^ (c)) ^ (d))
47             #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
48             #define F3(b, c, d) (((b) ^ (c)) ^ (d))
49              
50             #define S(n, x) (((x) << (n)) | ((x) >> (32 - (n))))
51              
52             #define H(n) (ctxt->h.b32[(n)])
53             #define COUNT (ctxt->count)
54             #define BCOUNT (ctxt->c.b64[0] / 8)
55             #define W(n) (ctxt->m.b32[(n)])
56              
57             #define PUTBYTE(x) \
58             do { \
59             ctxt->m.b8[(COUNT % 64)] = (x); \
60             COUNT++; \
61             COUNT %= 64; \
62             ctxt->c.b64[0] += 8; \
63             if (COUNT % 64 == 0) \
64             sha1_step(ctxt); \
65             } while (0)
66              
67             #define PUTPAD(x) \
68             do { \
69             ctxt->m.b8[(COUNT % 64)] = (x); \
70             COUNT++; \
71             COUNT %= 64; \
72             if (COUNT % 64 == 0) \
73             sha1_step(ctxt); \
74             } while (0)
75              
76             static void sha1_step(struct sha1_ctxt *);
77              
78             static void
79 0           sha1_step(struct sha1_ctxt * ctxt)
80             {
81             uint32_t a,
82             b,
83             c,
84             d,
85             e;
86             size_t t,
87             s;
88             uint32_t tmp;
89              
90             #ifndef WORDS_BIGENDIAN
91             struct sha1_ctxt tctxt;
92              
93 0           memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
94 0           ctxt->m.b8[0] = tctxt.m.b8[3];
95 0           ctxt->m.b8[1] = tctxt.m.b8[2];
96 0           ctxt->m.b8[2] = tctxt.m.b8[1];
97 0           ctxt->m.b8[3] = tctxt.m.b8[0];
98 0           ctxt->m.b8[4] = tctxt.m.b8[7];
99 0           ctxt->m.b8[5] = tctxt.m.b8[6];
100 0           ctxt->m.b8[6] = tctxt.m.b8[5];
101 0           ctxt->m.b8[7] = tctxt.m.b8[4];
102 0           ctxt->m.b8[8] = tctxt.m.b8[11];
103 0           ctxt->m.b8[9] = tctxt.m.b8[10];
104 0           ctxt->m.b8[10] = tctxt.m.b8[9];
105 0           ctxt->m.b8[11] = tctxt.m.b8[8];
106 0           ctxt->m.b8[12] = tctxt.m.b8[15];
107 0           ctxt->m.b8[13] = tctxt.m.b8[14];
108 0           ctxt->m.b8[14] = tctxt.m.b8[13];
109 0           ctxt->m.b8[15] = tctxt.m.b8[12];
110 0           ctxt->m.b8[16] = tctxt.m.b8[19];
111 0           ctxt->m.b8[17] = tctxt.m.b8[18];
112 0           ctxt->m.b8[18] = tctxt.m.b8[17];
113 0           ctxt->m.b8[19] = tctxt.m.b8[16];
114 0           ctxt->m.b8[20] = tctxt.m.b8[23];
115 0           ctxt->m.b8[21] = tctxt.m.b8[22];
116 0           ctxt->m.b8[22] = tctxt.m.b8[21];
117 0           ctxt->m.b8[23] = tctxt.m.b8[20];
118 0           ctxt->m.b8[24] = tctxt.m.b8[27];
119 0           ctxt->m.b8[25] = tctxt.m.b8[26];
120 0           ctxt->m.b8[26] = tctxt.m.b8[25];
121 0           ctxt->m.b8[27] = tctxt.m.b8[24];
122 0           ctxt->m.b8[28] = tctxt.m.b8[31];
123 0           ctxt->m.b8[29] = tctxt.m.b8[30];
124 0           ctxt->m.b8[30] = tctxt.m.b8[29];
125 0           ctxt->m.b8[31] = tctxt.m.b8[28];
126 0           ctxt->m.b8[32] = tctxt.m.b8[35];
127 0           ctxt->m.b8[33] = tctxt.m.b8[34];
128 0           ctxt->m.b8[34] = tctxt.m.b8[33];
129 0           ctxt->m.b8[35] = tctxt.m.b8[32];
130 0           ctxt->m.b8[36] = tctxt.m.b8[39];
131 0           ctxt->m.b8[37] = tctxt.m.b8[38];
132 0           ctxt->m.b8[38] = tctxt.m.b8[37];
133 0           ctxt->m.b8[39] = tctxt.m.b8[36];
134 0           ctxt->m.b8[40] = tctxt.m.b8[43];
135 0           ctxt->m.b8[41] = tctxt.m.b8[42];
136 0           ctxt->m.b8[42] = tctxt.m.b8[41];
137 0           ctxt->m.b8[43] = tctxt.m.b8[40];
138 0           ctxt->m.b8[44] = tctxt.m.b8[47];
139 0           ctxt->m.b8[45] = tctxt.m.b8[46];
140 0           ctxt->m.b8[46] = tctxt.m.b8[45];
141 0           ctxt->m.b8[47] = tctxt.m.b8[44];
142 0           ctxt->m.b8[48] = tctxt.m.b8[51];
143 0           ctxt->m.b8[49] = tctxt.m.b8[50];
144 0           ctxt->m.b8[50] = tctxt.m.b8[49];
145 0           ctxt->m.b8[51] = tctxt.m.b8[48];
146 0           ctxt->m.b8[52] = tctxt.m.b8[55];
147 0           ctxt->m.b8[53] = tctxt.m.b8[54];
148 0           ctxt->m.b8[54] = tctxt.m.b8[53];
149 0           ctxt->m.b8[55] = tctxt.m.b8[52];
150 0           ctxt->m.b8[56] = tctxt.m.b8[59];
151 0           ctxt->m.b8[57] = tctxt.m.b8[58];
152 0           ctxt->m.b8[58] = tctxt.m.b8[57];
153 0           ctxt->m.b8[59] = tctxt.m.b8[56];
154 0           ctxt->m.b8[60] = tctxt.m.b8[63];
155 0           ctxt->m.b8[61] = tctxt.m.b8[62];
156 0           ctxt->m.b8[62] = tctxt.m.b8[61];
157 0           ctxt->m.b8[63] = tctxt.m.b8[60];
158             #endif
159              
160 0           a = H(0);
161 0           b = H(1);
162 0           c = H(2);
163 0           d = H(3);
164 0           e = H(4);
165              
166 0 0         for (t = 0; t < 20; t++)
167             {
168 0           s = t & 0x0f;
169 0 0         if (t >= 16)
170 0           W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
171 0           tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
172 0           e = d;
173 0           d = c;
174 0           c = S(30, b);
175 0           b = a;
176 0           a = tmp;
177             }
178 0 0         for (t = 20; t < 40; t++)
179             {
180 0           s = t & 0x0f;
181 0           W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
182 0           tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
183 0           e = d;
184 0           d = c;
185 0           c = S(30, b);
186 0           b = a;
187 0           a = tmp;
188             }
189 0 0         for (t = 40; t < 60; t++)
190             {
191 0           s = t & 0x0f;
192 0           W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
193 0           tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
194 0           e = d;
195 0           d = c;
196 0           c = S(30, b);
197 0           b = a;
198 0           a = tmp;
199             }
200 0 0         for (t = 60; t < 80; t++)
201             {
202 0           s = t & 0x0f;
203 0           W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
204 0           tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
205 0           e = d;
206 0           d = c;
207 0           c = S(30, b);
208 0           b = a;
209 0           a = tmp;
210             }
211              
212 0           H(0) = H(0) + a;
213 0           H(1) = H(1) + b;
214 0           H(2) = H(2) + c;
215 0           H(3) = H(3) + d;
216 0           H(4) = H(4) + e;
217              
218 0           memset(&ctxt->m.b8[0], 0, 64);
219 0           }
220              
221             /*------------------------------------------------------------*/
222              
223             void
224 0           sha1_init(struct sha1_ctxt * ctxt)
225             {
226 0           memset(ctxt, 0, sizeof(struct sha1_ctxt));
227 0           H(0) = 0x67452301;
228 0           H(1) = 0xefcdab89;
229 0           H(2) = 0x98badcfe;
230 0           H(3) = 0x10325476;
231 0           H(4) = 0xc3d2e1f0;
232 0           }
233              
234             void
235 0           sha1_pad(struct sha1_ctxt * ctxt)
236             {
237             size_t padlen; /* pad length in bytes */
238             size_t padstart;
239              
240 0 0         PUTPAD(0x80);
241              
242 0           padstart = COUNT % 64;
243 0           padlen = 64 - padstart;
244 0 0         if (padlen < 8)
245             {
246 0           memset(&ctxt->m.b8[padstart], 0, padlen);
247 0           COUNT += (uint8_t) padlen;
248 0           COUNT %= 64;
249 0           sha1_step(ctxt);
250 0           padstart = COUNT % 64; /* should be 0 */
251 0           padlen = 64 - padstart; /* should be 64 */
252             }
253 0           memset(&ctxt->m.b8[padstart], 0, padlen - 8);
254 0           COUNT += ((uint8_t) padlen - 8);
255 0           COUNT %= 64;
256             #ifdef WORDS_BIGENDIAN
257             PUTPAD(ctxt->c.b8[0]);
258             PUTPAD(ctxt->c.b8[1]);
259             PUTPAD(ctxt->c.b8[2]);
260             PUTPAD(ctxt->c.b8[3]);
261             PUTPAD(ctxt->c.b8[4]);
262             PUTPAD(ctxt->c.b8[5]);
263             PUTPAD(ctxt->c.b8[6]);
264             PUTPAD(ctxt->c.b8[7]);
265             #else
266 0 0         PUTPAD(ctxt->c.b8[7]);
267 0 0         PUTPAD(ctxt->c.b8[6]);
268 0 0         PUTPAD(ctxt->c.b8[5]);
269 0 0         PUTPAD(ctxt->c.b8[4]);
270 0 0         PUTPAD(ctxt->c.b8[3]);
271 0 0         PUTPAD(ctxt->c.b8[2]);
272 0 0         PUTPAD(ctxt->c.b8[1]);
273 0 0         PUTPAD(ctxt->c.b8[0]);
274             #endif
275 0           }
276              
277             void
278 0           sha1_loop(struct sha1_ctxt * ctxt, const uint8_t *input0, size_t len)
279             {
280             const uint8_t *input;
281             size_t gaplen;
282             size_t gapstart;
283             size_t off;
284             size_t copysiz;
285              
286 0           input = (const uint8_t *) input0;
287 0           off = 0;
288              
289 0 0         while (off < len)
290             {
291 0           gapstart = COUNT % 64;
292 0           gaplen = 64 - gapstart;
293              
294 0           copysiz = (gaplen < len - off) ? gaplen : len - off;
295 0           memmove(&ctxt->m.b8[gapstart], &input[off], copysiz);
296 0           COUNT += (uint8_t) copysiz;
297 0           COUNT %= 64;
298 0           ctxt->c.b64[0] += copysiz * 8;
299 0 0         if (COUNT % 64 == 0)
300 0           sha1_step(ctxt);
301 0           off += copysiz;
302             }
303 0           }
304              
305             void
306 0           sha1_result(struct sha1_ctxt * ctxt, uint8_t *digest0)
307             {
308             uint8_t *digest;
309              
310 0           digest = (uint8_t *) digest0;
311 0           sha1_pad(ctxt);
312             #ifdef WORDS_BIGENDIAN
313             memmove(digest, &ctxt->h.b8[0], 20);
314             #else
315 0           digest[0] = ctxt->h.b8[3];
316 0           digest[1] = ctxt->h.b8[2];
317 0           digest[2] = ctxt->h.b8[1];
318 0           digest[3] = ctxt->h.b8[0];
319 0           digest[4] = ctxt->h.b8[7];
320 0           digest[5] = ctxt->h.b8[6];
321 0           digest[6] = ctxt->h.b8[5];
322 0           digest[7] = ctxt->h.b8[4];
323 0           digest[8] = ctxt->h.b8[11];
324 0           digest[9] = ctxt->h.b8[10];
325 0           digest[10] = ctxt->h.b8[9];
326 0           digest[11] = ctxt->h.b8[8];
327 0           digest[12] = ctxt->h.b8[15];
328 0           digest[13] = ctxt->h.b8[14];
329 0           digest[14] = ctxt->h.b8[13];
330 0           digest[15] = ctxt->h.b8[12];
331 0           digest[16] = ctxt->h.b8[19];
332 0           digest[17] = ctxt->h.b8[18];
333 0           digest[18] = ctxt->h.b8[17];
334 0           digest[19] = ctxt->h.b8[16];
335             #endif
336 0           }