4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
35 * based on: http://csrc.nist.gov/fips/fip180-1.txt
36 * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
41 #include <sys/param.h>
47 static uint32 _K
[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
49 #define K(t) _K[(t) / 20]
51 #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
52 #define F1(b, c, d) (((b) ^ (c)) ^ (d))
53 #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
54 #define F3(b, c, d) (((b) ^ (c)) ^ (d))
56 #define S(n, x) (((x) << (n)) | ((x) >> (32 - (n))))
58 #define H(n) (ctxt->h.b32[(n)])
59 #define COUNT (ctxt->count)
60 #define BCOUNT (ctxt->c.b64[0] / 8)
61 #define W(n) (ctxt->m.b32[(n)])
65 ctxt->m.b8[(COUNT % 64)] = (x); \
68 ctxt->c.b64[0] += 8; \
69 if (COUNT % 64 == 0) \
75 ctxt->m.b8[(COUNT % 64)] = (x); \
78 if (COUNT % 64 == 0) \
82 static void sha1_step(struct sha1_ctxt
*);
85 sha1_step(struct sha1_ctxt
* ctxt
)
96 #ifndef WORDS_BIGENDIAN
97 struct sha1_ctxt tctxt
;
99 memmove(&tctxt
.m
.b8
[0], &ctxt
->m
.b8
[0], 64);
100 ctxt
->m
.b8
[0] = tctxt
.m
.b8
[3];
101 ctxt
->m
.b8
[1] = tctxt
.m
.b8
[2];
102 ctxt
->m
.b8
[2] = tctxt
.m
.b8
[1];
103 ctxt
->m
.b8
[3] = tctxt
.m
.b8
[0];
104 ctxt
->m
.b8
[4] = tctxt
.m
.b8
[7];
105 ctxt
->m
.b8
[5] = tctxt
.m
.b8
[6];
106 ctxt
->m
.b8
[6] = tctxt
.m
.b8
[5];
107 ctxt
->m
.b8
[7] = tctxt
.m
.b8
[4];
108 ctxt
->m
.b8
[8] = tctxt
.m
.b8
[11];
109 ctxt
->m
.b8
[9] = tctxt
.m
.b8
[10];
110 ctxt
->m
.b8
[10] = tctxt
.m
.b8
[9];
111 ctxt
->m
.b8
[11] = tctxt
.m
.b8
[8];
112 ctxt
->m
.b8
[12] = tctxt
.m
.b8
[15];
113 ctxt
->m
.b8
[13] = tctxt
.m
.b8
[14];
114 ctxt
->m
.b8
[14] = tctxt
.m
.b8
[13];
115 ctxt
->m
.b8
[15] = tctxt
.m
.b8
[12];
116 ctxt
->m
.b8
[16] = tctxt
.m
.b8
[19];
117 ctxt
->m
.b8
[17] = tctxt
.m
.b8
[18];
118 ctxt
->m
.b8
[18] = tctxt
.m
.b8
[17];
119 ctxt
->m
.b8
[19] = tctxt
.m
.b8
[16];
120 ctxt
->m
.b8
[20] = tctxt
.m
.b8
[23];
121 ctxt
->m
.b8
[21] = tctxt
.m
.b8
[22];
122 ctxt
->m
.b8
[22] = tctxt
.m
.b8
[21];
123 ctxt
->m
.b8
[23] = tctxt
.m
.b8
[20];
124 ctxt
->m
.b8
[24] = tctxt
.m
.b8
[27];
125 ctxt
->m
.b8
[25] = tctxt
.m
.b8
[26];
126 ctxt
->m
.b8
[26] = tctxt
.m
.b8
[25];
127 ctxt
->m
.b8
[27] = tctxt
.m
.b8
[24];
128 ctxt
->m
.b8
[28] = tctxt
.m
.b8
[31];
129 ctxt
->m
.b8
[29] = tctxt
.m
.b8
[30];
130 ctxt
->m
.b8
[30] = tctxt
.m
.b8
[29];
131 ctxt
->m
.b8
[31] = tctxt
.m
.b8
[28];
132 ctxt
->m
.b8
[32] = tctxt
.m
.b8
[35];
133 ctxt
->m
.b8
[33] = tctxt
.m
.b8
[34];
134 ctxt
->m
.b8
[34] = tctxt
.m
.b8
[33];
135 ctxt
->m
.b8
[35] = tctxt
.m
.b8
[32];
136 ctxt
->m
.b8
[36] = tctxt
.m
.b8
[39];
137 ctxt
->m
.b8
[37] = tctxt
.m
.b8
[38];
138 ctxt
->m
.b8
[38] = tctxt
.m
.b8
[37];
139 ctxt
->m
.b8
[39] = tctxt
.m
.b8
[36];
140 ctxt
->m
.b8
[40] = tctxt
.m
.b8
[43];
141 ctxt
->m
.b8
[41] = tctxt
.m
.b8
[42];
142 ctxt
->m
.b8
[42] = tctxt
.m
.b8
[41];
143 ctxt
->m
.b8
[43] = tctxt
.m
.b8
[40];
144 ctxt
->m
.b8
[44] = tctxt
.m
.b8
[47];
145 ctxt
->m
.b8
[45] = tctxt
.m
.b8
[46];
146 ctxt
->m
.b8
[46] = tctxt
.m
.b8
[45];
147 ctxt
->m
.b8
[47] = tctxt
.m
.b8
[44];
148 ctxt
->m
.b8
[48] = tctxt
.m
.b8
[51];
149 ctxt
->m
.b8
[49] = tctxt
.m
.b8
[50];
150 ctxt
->m
.b8
[50] = tctxt
.m
.b8
[49];
151 ctxt
->m
.b8
[51] = tctxt
.m
.b8
[48];
152 ctxt
->m
.b8
[52] = tctxt
.m
.b8
[55];
153 ctxt
->m
.b8
[53] = tctxt
.m
.b8
[54];
154 ctxt
->m
.b8
[54] = tctxt
.m
.b8
[53];
155 ctxt
->m
.b8
[55] = tctxt
.m
.b8
[52];
156 ctxt
->m
.b8
[56] = tctxt
.m
.b8
[59];
157 ctxt
->m
.b8
[57] = tctxt
.m
.b8
[58];
158 ctxt
->m
.b8
[58] = tctxt
.m
.b8
[57];
159 ctxt
->m
.b8
[59] = tctxt
.m
.b8
[56];
160 ctxt
->m
.b8
[60] = tctxt
.m
.b8
[63];
161 ctxt
->m
.b8
[61] = tctxt
.m
.b8
[62];
162 ctxt
->m
.b8
[62] = tctxt
.m
.b8
[61];
163 ctxt
->m
.b8
[63] = tctxt
.m
.b8
[60];
172 for (t
= 0; t
< 20; t
++)
176 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
177 tmp
= S(5, a
) + F0(b
, c
, d
) + e
+ W(s
) + K(t
);
184 for (t
= 20; t
< 40; t
++)
187 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
188 tmp
= S(5, a
) + F1(b
, c
, d
) + e
+ W(s
) + K(t
);
195 for (t
= 40; t
< 60; t
++)
198 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
199 tmp
= S(5, a
) + F2(b
, c
, d
) + e
+ W(s
) + K(t
);
206 for (t
= 60; t
< 80; t
++)
209 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
210 tmp
= S(5, a
) + F3(b
, c
, d
) + e
+ W(s
) + K(t
);
224 memset(&ctxt
->m
.b8
[0], 0, 64);
227 /*------------------------------------------------------------*/
230 sha1_init(struct sha1_ctxt
* ctxt
)
232 memset(ctxt
, 0, sizeof(struct sha1_ctxt
));
241 sha1_pad(struct sha1_ctxt
* ctxt
)
243 size_t padlen
; /* pad length in bytes */
248 padstart
= COUNT
% 64;
249 padlen
= 64 - padstart
;
252 memset(&ctxt
->m
.b8
[padstart
], 0, padlen
);
256 padstart
= COUNT
% 64; /* should be 0 */
257 padlen
= 64 - padstart
; /* should be 64 */
259 memset(&ctxt
->m
.b8
[padstart
], 0, padlen
- 8);
260 COUNT
+= (padlen
- 8);
262 #ifdef WORDS_BIGENDIAN
263 PUTPAD(ctxt
->c
.b8
[0]);
264 PUTPAD(ctxt
->c
.b8
[1]);
265 PUTPAD(ctxt
->c
.b8
[2]);
266 PUTPAD(ctxt
->c
.b8
[3]);
267 PUTPAD(ctxt
->c
.b8
[4]);
268 PUTPAD(ctxt
->c
.b8
[5]);
269 PUTPAD(ctxt
->c
.b8
[6]);
270 PUTPAD(ctxt
->c
.b8
[7]);
272 PUTPAD(ctxt
->c
.b8
[7]);
273 PUTPAD(ctxt
->c
.b8
[6]);
274 PUTPAD(ctxt
->c
.b8
[5]);
275 PUTPAD(ctxt
->c
.b8
[4]);
276 PUTPAD(ctxt
->c
.b8
[3]);
277 PUTPAD(ctxt
->c
.b8
[2]);
278 PUTPAD(ctxt
->c
.b8
[1]);
279 PUTPAD(ctxt
->c
.b8
[0]);
284 sha1_loop(struct sha1_ctxt
* ctxt
, const uint8
*input0
, size_t len
)
292 input
= (const uint8
*) input0
;
297 gapstart
= COUNT
% 64;
298 gaplen
= 64 - gapstart
;
300 copysiz
= (gaplen
< len
- off
) ? gaplen
: len
- off
;
301 memmove(&ctxt
->m
.b8
[gapstart
], &input
[off
], copysiz
);
304 ctxt
->c
.b64
[0] += copysiz
* 8;
312 sha1_result(struct sha1_ctxt
* ctxt
, uint8
*digest0
)
316 digest
= (uint8
*) digest0
;
318 #ifdef WORDS_BIGENDIAN
319 memmove(digest
, &ctxt
->h
.b8
[0], 20);
321 digest
[0] = ctxt
->h
.b8
[3];
322 digest
[1] = ctxt
->h
.b8
[2];
323 digest
[2] = ctxt
->h
.b8
[1];
324 digest
[3] = ctxt
->h
.b8
[0];
325 digest
[4] = ctxt
->h
.b8
[7];
326 digest
[5] = ctxt
->h
.b8
[6];
327 digest
[6] = ctxt
->h
.b8
[5];
328 digest
[7] = ctxt
->h
.b8
[4];
329 digest
[8] = ctxt
->h
.b8
[11];
330 digest
[9] = ctxt
->h
.b8
[10];
331 digest
[10] = ctxt
->h
.b8
[9];
332 digest
[11] = ctxt
->h
.b8
[8];
333 digest
[12] = ctxt
->h
.b8
[15];
334 digest
[13] = ctxt
->h
.b8
[14];
335 digest
[14] = ctxt
->h
.b8
[13];
336 digest
[15] = ctxt
->h
.b8
[12];
337 digest
[16] = ctxt
->h
.b8
[19];
338 digest
[17] = ctxt
->h
.b8
[18];
339 digest
[18] = ctxt
->h
.b8
[17];
340 digest
[19] = ctxt
->h
.b8
[16];