1214501Srpaulo/*
2214501Srpaulo * SHA1 hash implementation and interface functions
3214501Srpaulo * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4214501Srpaulo *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7214501Srpaulo */
8214501Srpaulo
9214501Srpaulo#include "includes.h"
10214501Srpaulo
11214501Srpaulo#include "common.h"
12214501Srpaulo#include "sha1.h"
13214501Srpaulo#include "sha1_i.h"
14214501Srpaulo#include "md5.h"
15214501Srpaulo#include "crypto.h"
16214501Srpaulo
17214501Srpaulotypedef struct SHA1Context SHA1_CTX;
18214501Srpaulo
19214501Srpaulovoid SHA1Transform(u32 state[5], const unsigned char buffer[64]);
20214501Srpaulo
21214501Srpaulo
22214501Srpaulo/**
23214501Srpaulo * sha1_vector - SHA-1 hash for data vector
24214501Srpaulo * @num_elem: Number of elements in the data vector
25214501Srpaulo * @addr: Pointers to the data areas
26214501Srpaulo * @len: Lengths of the data blocks
27214501Srpaulo * @mac: Buffer for the hash
28214501Srpaulo * Returns: 0 on success, -1 of failure
29214501Srpaulo */
30214501Srpauloint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
31214501Srpaulo{
32214501Srpaulo	SHA1_CTX ctx;
33214501Srpaulo	size_t i;
34214501Srpaulo
35214501Srpaulo	SHA1Init(&ctx);
36214501Srpaulo	for (i = 0; i < num_elem; i++)
37214501Srpaulo		SHA1Update(&ctx, addr[i], len[i]);
38214501Srpaulo	SHA1Final(mac, &ctx);
39214501Srpaulo	return 0;
40214501Srpaulo}
41214501Srpaulo
42214501Srpaulo
43214501Srpaulo/* ===== start - public domain SHA1 implementation ===== */
44214501Srpaulo
45214501Srpaulo/*
46214501SrpauloSHA-1 in C
47214501SrpauloBy Steve Reid <sreid@sea-to-sky.net>
48214501Srpaulo100% Public Domain
49214501Srpaulo
50214501Srpaulo-----------------
51214501SrpauloModified 7/98
52214501SrpauloBy James H. Brown <jbrown@burgoyne.com>
53214501SrpauloStill 100% Public Domain
54214501Srpaulo
55214501SrpauloCorrected a problem which generated improper hash values on 16 bit machines
56214501SrpauloRoutine SHA1Update changed from
57214501Srpaulo	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
58214501Srpaulolen)
59214501Srpauloto
60214501Srpaulo	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
61214501Srpaulolong len)
62214501Srpaulo
63214501SrpauloThe 'len' parameter was declared an int which works fine on 32 bit machines.
64214501SrpauloHowever, on 16 bit machines an int is too small for the shifts being done
65214501Srpauloagainst
66214501Srpauloit.  This caused the hash function to generate incorrect values if len was
67214501Srpaulogreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
68214501Srpaulo
69214501SrpauloSince the file IO in main() reads 16K at a time, any file 8K or larger would
70214501Srpaulobe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
71214501Srpaulo"a"s).
72214501Srpaulo
73214501SrpauloI also changed the declaration of variables i & j in SHA1Update to
74214501Srpaulounsigned long from unsigned int for the same reason.
75214501Srpaulo
76214501SrpauloThese changes should make no difference to any 32 bit implementations since
77214501Srpauloan
78214501Srpauloint and a long are the same size in those environments.
79214501Srpaulo
80214501Srpaulo--
81214501SrpauloI also corrected a few compiler warnings generated by Borland C.
82214501Srpaulo1. Added #include <process.h> for exit() prototype
83214501Srpaulo2. Removed unused variable 'j' in SHA1Final
84214501Srpaulo3. Changed exit(0) to return(0) at end of main.
85214501Srpaulo
86214501SrpauloALL changes I made can be located by searching for comments containing 'JHB'
87214501Srpaulo-----------------
88214501SrpauloModified 8/98
89214501SrpauloBy Steve Reid <sreid@sea-to-sky.net>
90214501SrpauloStill 100% public domain
91214501Srpaulo
92214501Srpaulo1- Removed #include <process.h> and used return() instead of exit()
93214501Srpaulo2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
94214501Srpaulo3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
95214501Srpaulo
96214501Srpaulo-----------------
97214501SrpauloModified 4/01
98214501SrpauloBy Saul Kravitz <Saul.Kravitz@celera.com>
99214501SrpauloStill 100% PD
100214501SrpauloModified to run on Compaq Alpha hardware.
101214501Srpaulo
102214501Srpaulo-----------------
103214501SrpauloModified 4/01
104214501SrpauloBy Jouni Malinen <j@w1.fi>
105214501SrpauloMinor changes to match the coding style used in Dynamics.
106214501Srpaulo
107214501SrpauloModified September 24, 2004
108214501SrpauloBy Jouni Malinen <j@w1.fi>
109214501SrpauloFixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
110214501Srpaulo
111214501Srpaulo*/
112214501Srpaulo
113214501Srpaulo/*
114214501SrpauloTest Vectors (from FIPS PUB 180-1)
115214501Srpaulo"abc"
116214501Srpaulo  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
117214501Srpaulo"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
118214501Srpaulo  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
119214501SrpauloA million repetitions of "a"
120214501Srpaulo  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
121214501Srpaulo*/
122214501Srpaulo
123214501Srpaulo#define SHA1HANDSOFF
124214501Srpaulo
125214501Srpaulo#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
126214501Srpaulo
127214501Srpaulo/* blk0() and blk() perform the initial expand. */
128214501Srpaulo/* I got the idea of expanding during the round function from SSLeay */
129214501Srpaulo#ifndef WORDS_BIGENDIAN
130214501Srpaulo#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
131214501Srpaulo	(rol(block->l[i], 8) & 0x00FF00FF))
132214501Srpaulo#else
133214501Srpaulo#define blk0(i) block->l[i]
134214501Srpaulo#endif
135214501Srpaulo#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
136214501Srpaulo	block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
137214501Srpaulo
138214501Srpaulo/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
139214501Srpaulo#define R0(v,w,x,y,z,i) \
140214501Srpaulo	z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
141214501Srpaulo	w = rol(w, 30);
142214501Srpaulo#define R1(v,w,x,y,z,i) \
143214501Srpaulo	z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
144214501Srpaulo	w = rol(w, 30);
145214501Srpaulo#define R2(v,w,x,y,z,i) \
146214501Srpaulo	z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
147214501Srpaulo#define R3(v,w,x,y,z,i) \
148214501Srpaulo	z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
149214501Srpaulo	w = rol(w, 30);
150214501Srpaulo#define R4(v,w,x,y,z,i) \
151214501Srpaulo	z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
152214501Srpaulo	w=rol(w, 30);
153214501Srpaulo
154214501Srpaulo
155214501Srpaulo#ifdef VERBOSE  /* SAK */
156214501Srpaulovoid SHAPrintContext(SHA1_CTX *context, char *msg)
157214501Srpaulo{
158214501Srpaulo	printf("%s (%d,%d) %x %x %x %x %x\n",
159214501Srpaulo	       msg,
160214501Srpaulo	       context->count[0], context->count[1],
161214501Srpaulo	       context->state[0],
162214501Srpaulo	       context->state[1],
163214501Srpaulo	       context->state[2],
164214501Srpaulo	       context->state[3],
165214501Srpaulo	       context->state[4]);
166214501Srpaulo}
167214501Srpaulo#endif
168214501Srpaulo
169214501Srpaulo/* Hash a single 512-bit block. This is the core of the algorithm. */
170214501Srpaulo
171214501Srpaulovoid SHA1Transform(u32 state[5], const unsigned char buffer[64])
172214501Srpaulo{
173214501Srpaulo	u32 a, b, c, d, e;
174214501Srpaulo	typedef union {
175214501Srpaulo		unsigned char c[64];
176214501Srpaulo		u32 l[16];
177214501Srpaulo	} CHAR64LONG16;
178214501Srpaulo	CHAR64LONG16* block;
179214501Srpaulo#ifdef SHA1HANDSOFF
180214501Srpaulo	CHAR64LONG16 workspace;
181214501Srpaulo	block = &workspace;
182214501Srpaulo	os_memcpy(block, buffer, 64);
183214501Srpaulo#else
184214501Srpaulo	block = (CHAR64LONG16 *) buffer;
185214501Srpaulo#endif
186214501Srpaulo	/* Copy context->state[] to working vars */
187214501Srpaulo	a = state[0];
188214501Srpaulo	b = state[1];
189214501Srpaulo	c = state[2];
190214501Srpaulo	d = state[3];
191214501Srpaulo	e = state[4];
192214501Srpaulo	/* 4 rounds of 20 operations each. Loop unrolled. */
193214501Srpaulo	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);
194214501Srpaulo	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);
195214501Srpaulo	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);
196214501Srpaulo	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);
197214501Srpaulo	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);
198214501Srpaulo	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);
199214501Srpaulo	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);
200214501Srpaulo	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);
201214501Srpaulo	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);
202214501Srpaulo	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);
203214501Srpaulo	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);
204214501Srpaulo	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);
205214501Srpaulo	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);
206214501Srpaulo	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);
207214501Srpaulo	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);
208214501Srpaulo	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);
209214501Srpaulo	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);
210214501Srpaulo	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);
211214501Srpaulo	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);
212214501Srpaulo	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);
213214501Srpaulo	/* Add the working vars back into context.state[] */
214214501Srpaulo	state[0] += a;
215214501Srpaulo	state[1] += b;
216214501Srpaulo	state[2] += c;
217214501Srpaulo	state[3] += d;
218214501Srpaulo	state[4] += e;
219214501Srpaulo	/* Wipe variables */
220214501Srpaulo	a = b = c = d = e = 0;
221214501Srpaulo#ifdef SHA1HANDSOFF
222214501Srpaulo	os_memset(block, 0, 64);
223214501Srpaulo#endif
224214501Srpaulo}
225214501Srpaulo
226214501Srpaulo
227214501Srpaulo/* SHA1Init - Initialize new context */
228214501Srpaulo
229214501Srpaulovoid SHA1Init(SHA1_CTX* context)
230214501Srpaulo{
231214501Srpaulo	/* SHA1 initialization constants */
232214501Srpaulo	context->state[0] = 0x67452301;
233214501Srpaulo	context->state[1] = 0xEFCDAB89;
234214501Srpaulo	context->state[2] = 0x98BADCFE;
235214501Srpaulo	context->state[3] = 0x10325476;
236214501Srpaulo	context->state[4] = 0xC3D2E1F0;
237214501Srpaulo	context->count[0] = context->count[1] = 0;
238214501Srpaulo}
239214501Srpaulo
240214501Srpaulo
241214501Srpaulo/* Run your data through this. */
242214501Srpaulo
243214501Srpaulovoid SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
244214501Srpaulo{
245214501Srpaulo	u32 i, j;
246214501Srpaulo	const unsigned char *data = _data;
247214501Srpaulo
248214501Srpaulo#ifdef VERBOSE
249214501Srpaulo	SHAPrintContext(context, "before");
250214501Srpaulo#endif
251214501Srpaulo	j = (context->count[0] >> 3) & 63;
252214501Srpaulo	if ((context->count[0] += len << 3) < (len << 3))
253214501Srpaulo		context->count[1]++;
254214501Srpaulo	context->count[1] += (len >> 29);
255214501Srpaulo	if ((j + len) > 63) {
256214501Srpaulo		os_memcpy(&context->buffer[j], data, (i = 64-j));
257214501Srpaulo		SHA1Transform(context->state, context->buffer);
258214501Srpaulo		for ( ; i + 63 < len; i += 64) {
259214501Srpaulo			SHA1Transform(context->state, &data[i]);
260214501Srpaulo		}
261214501Srpaulo		j = 0;
262214501Srpaulo	}
263214501Srpaulo	else i = 0;
264214501Srpaulo	os_memcpy(&context->buffer[j], &data[i], len - i);
265214501Srpaulo#ifdef VERBOSE
266214501Srpaulo	SHAPrintContext(context, "after ");
267214501Srpaulo#endif
268214501Srpaulo}
269214501Srpaulo
270214501Srpaulo
271214501Srpaulo/* Add padding and return the message digest. */
272214501Srpaulo
273214501Srpaulovoid SHA1Final(unsigned char digest[20], SHA1_CTX* context)
274214501Srpaulo{
275214501Srpaulo	u32 i;
276214501Srpaulo	unsigned char finalcount[8];
277214501Srpaulo
278214501Srpaulo	for (i = 0; i < 8; i++) {
279214501Srpaulo		finalcount[i] = (unsigned char)
280214501Srpaulo			((context->count[(i >= 4 ? 0 : 1)] >>
281214501Srpaulo			  ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
282214501Srpaulo	}
283214501Srpaulo	SHA1Update(context, (unsigned char *) "\200", 1);
284214501Srpaulo	while ((context->count[0] & 504) != 448) {
285214501Srpaulo		SHA1Update(context, (unsigned char *) "\0", 1);
286214501Srpaulo	}
287214501Srpaulo	SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
288214501Srpaulo					      */
289214501Srpaulo	for (i = 0; i < 20; i++) {
290214501Srpaulo		digest[i] = (unsigned char)
291214501Srpaulo			((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
292214501Srpaulo			 255);
293214501Srpaulo	}
294214501Srpaulo	/* Wipe variables */
295214501Srpaulo	i = 0;
296214501Srpaulo	os_memset(context->buffer, 0, 64);
297214501Srpaulo	os_memset(context->state, 0, 20);
298214501Srpaulo	os_memset(context->count, 0, 8);
299214501Srpaulo	os_memset(finalcount, 0, 8);
300214501Srpaulo}
301214501Srpaulo
302214501Srpaulo/* ===== end - public domain SHA1 implementation ===== */
303