sha1-internal.c revision 252726
1/*
2 * SHA1 hash implementation and interface functions
3 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "sha1.h"
13#include "sha1_i.h"
14#include "md5.h"
15#include "crypto.h"
16
17typedef struct SHA1Context SHA1_CTX;
18
19void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
20
21
22/**
23 * sha1_vector - SHA-1 hash for data vector
24 * @num_elem: Number of elements in the data vector
25 * @addr: Pointers to the data areas
26 * @len: Lengths of the data blocks
27 * @mac: Buffer for the hash
28 * Returns: 0 on success, -1 of failure
29 */
30int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
31{
32	SHA1_CTX ctx;
33	size_t i;
34
35	SHA1Init(&ctx);
36	for (i = 0; i < num_elem; i++)
37		SHA1Update(&ctx, addr[i], len[i]);
38	SHA1Final(mac, &ctx);
39	return 0;
40}
41
42
43/* ===== start - public domain SHA1 implementation ===== */
44
45/*
46SHA-1 in C
47By Steve Reid <sreid@sea-to-sky.net>
48100% Public Domain
49
50-----------------
51Modified 7/98
52By James H. Brown <jbrown@burgoyne.com>
53Still 100% Public Domain
54
55Corrected a problem which generated improper hash values on 16 bit machines
56Routine SHA1Update changed from
57	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
58len)
59to
60	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
61long len)
62
63The 'len' parameter was declared an int which works fine on 32 bit machines.
64However, on 16 bit machines an int is too small for the shifts being done
65against
66it.  This caused the hash function to generate incorrect values if len was
67greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
68
69Since the file IO in main() reads 16K at a time, any file 8K or larger would
70be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
71"a"s).
72
73I also changed the declaration of variables i & j in SHA1Update to
74unsigned long from unsigned int for the same reason.
75
76These changes should make no difference to any 32 bit implementations since
77an
78int and a long are the same size in those environments.
79
80--
81I also corrected a few compiler warnings generated by Borland C.
821. Added #include <process.h> for exit() prototype
832. Removed unused variable 'j' in SHA1Final
843. Changed exit(0) to return(0) at end of main.
85
86ALL changes I made can be located by searching for comments containing 'JHB'
87-----------------
88Modified 8/98
89By Steve Reid <sreid@sea-to-sky.net>
90Still 100% public domain
91
921- Removed #include <process.h> and used return() instead of exit()
932- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
943- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
95
96-----------------
97Modified 4/01
98By Saul Kravitz <Saul.Kravitz@celera.com>
99Still 100% PD
100Modified to run on Compaq Alpha hardware.
101
102-----------------
103Modified 4/01
104By Jouni Malinen <j@w1.fi>
105Minor changes to match the coding style used in Dynamics.
106
107Modified September 24, 2004
108By Jouni Malinen <j@w1.fi>
109Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
110
111*/
112
113/*
114Test Vectors (from FIPS PUB 180-1)
115"abc"
116  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
117"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
118  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
119A million repetitions of "a"
120  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
121*/
122
123#define SHA1HANDSOFF
124
125#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
126
127/* blk0() and blk() perform the initial expand. */
128/* I got the idea of expanding during the round function from SSLeay */
129#ifndef WORDS_BIGENDIAN
130#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
131	(rol(block->l[i], 8) & 0x00FF00FF))
132#else
133#define blk0(i) block->l[i]
134#endif
135#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
136	block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
137
138/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
139#define R0(v,w,x,y,z,i) \
140	z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
141	w = rol(w, 30);
142#define R1(v,w,x,y,z,i) \
143	z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
144	w = rol(w, 30);
145#define R2(v,w,x,y,z,i) \
146	z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
147#define R3(v,w,x,y,z,i) \
148	z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
149	w = rol(w, 30);
150#define R4(v,w,x,y,z,i) \
151	z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
152	w=rol(w, 30);
153
154
155#ifdef VERBOSE  /* SAK */
156void SHAPrintContext(SHA1_CTX *context, char *msg)
157{
158	printf("%s (%d,%d) %x %x %x %x %x\n",
159	       msg,
160	       context->count[0], context->count[1],
161	       context->state[0],
162	       context->state[1],
163	       context->state[2],
164	       context->state[3],
165	       context->state[4]);
166}
167#endif
168
169/* Hash a single 512-bit block. This is the core of the algorithm. */
170
171void SHA1Transform(u32 state[5], const unsigned char buffer[64])
172{
173	u32 a, b, c, d, e;
174	typedef union {
175		unsigned char c[64];
176		u32 l[16];
177	} CHAR64LONG16;
178	CHAR64LONG16* block;
179#ifdef SHA1HANDSOFF
180	CHAR64LONG16 workspace;
181	block = &workspace;
182	os_memcpy(block, buffer, 64);
183#else
184	block = (CHAR64LONG16 *) buffer;
185#endif
186	/* Copy context->state[] to working vars */
187	a = state[0];
188	b = state[1];
189	c = state[2];
190	d = state[3];
191	e = state[4];
192	/* 4 rounds of 20 operations each. Loop unrolled. */
193	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
194	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
195	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
196	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
197	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
198	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
199	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
200	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
201	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
202	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
203	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
204	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
205	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
206	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
207	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
208	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
209	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
210	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
211	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
212	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
213	/* Add the working vars back into context.state[] */
214	state[0] += a;
215	state[1] += b;
216	state[2] += c;
217	state[3] += d;
218	state[4] += e;
219	/* Wipe variables */
220	a = b = c = d = e = 0;
221#ifdef SHA1HANDSOFF
222	os_memset(block, 0, 64);
223#endif
224}
225
226
227/* SHA1Init - Initialize new context */
228
229void SHA1Init(SHA1_CTX* context)
230{
231	/* SHA1 initialization constants */
232	context->state[0] = 0x67452301;
233	context->state[1] = 0xEFCDAB89;
234	context->state[2] = 0x98BADCFE;
235	context->state[3] = 0x10325476;
236	context->state[4] = 0xC3D2E1F0;
237	context->count[0] = context->count[1] = 0;
238}
239
240
241/* Run your data through this. */
242
243void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
244{
245	u32 i, j;
246	const unsigned char *data = _data;
247
248#ifdef VERBOSE
249	SHAPrintContext(context, "before");
250#endif
251	j = (context->count[0] >> 3) & 63;
252	if ((context->count[0] += len << 3) < (len << 3))
253		context->count[1]++;
254	context->count[1] += (len >> 29);
255	if ((j + len) > 63) {
256		os_memcpy(&context->buffer[j], data, (i = 64-j));
257		SHA1Transform(context->state, context->buffer);
258		for ( ; i + 63 < len; i += 64) {
259			SHA1Transform(context->state, &data[i]);
260		}
261		j = 0;
262	}
263	else i = 0;
264	os_memcpy(&context->buffer[j], &data[i], len - i);
265#ifdef VERBOSE
266	SHAPrintContext(context, "after ");
267#endif
268}
269
270
271/* Add padding and return the message digest. */
272
273void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
274{
275	u32 i;
276	unsigned char finalcount[8];
277
278	for (i = 0; i < 8; i++) {
279		finalcount[i] = (unsigned char)
280			((context->count[(i >= 4 ? 0 : 1)] >>
281			  ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
282	}
283	SHA1Update(context, (unsigned char *) "\200", 1);
284	while ((context->count[0] & 504) != 448) {
285		SHA1Update(context, (unsigned char *) "\0", 1);
286	}
287	SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
288					      */
289	for (i = 0; i < 20; i++) {
290		digest[i] = (unsigned char)
291			((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
292			 255);
293	}
294	/* Wipe variables */
295	i = 0;
296	os_memset(context->buffer, 0, 64);
297	os_memset(context->state, 0, 20);
298	os_memset(context->count, 0, 8);
299	os_memset(finalcount, 0, 8);
300}
301
302/* ===== end - public domain SHA1 implementation ===== */
303