Removal of:
[dyninst.git] / common / src / sha1.C
1 /*
2  * Copyright (c) 1996-2011 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 /*
32 SHA-1 in C
33 By Steve Reid <sreid@sea-to-sky.net>
34 100% Public Domain
35
36 -----------------
37 Modified 7/98 
38 By James H. Brown <jbrown@burgoyne.com>
39 Still 100% Public Domain
40
41 Corrected a problem which generated improper hash values on 16 bit machines
42 Routine SHA1Update changed from
43         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
44 len)
45 to
46         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
47 long len)
48
49 The 'len' parameter was declared an int which works fine on 32 bit machines.
50 However, on 16 bit machines an int is too small for the shifts being done
51 against
52 it.  This caused the hash function to generate incorrect values if len was
53 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
54
55 Since the file IO in main() reads 16K at a time, any file 8K or larger would
56 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
57 "a"s).
58
59 I also changed the declaration of variables i & j in SHA1Update to 
60 unsigned long from unsigned int for the same reason.
61
62 These changes should make no difference to any 32 bit implementations since
63 an
64 int and a long are the same size in those environments.
65
66 --
67 I also corrected a few compiler warnings generated by Borland C.
68 1. Added #include <process.h> for exit() prototype
69 2. Removed unused variable 'j' in SHA1Final
70 3. Changed exit(0) to return(0) at end of main.
71
72 ALL changes I made can be located by searching for comments containing 'JHB'
73 -----------------
74 Modified 8/98
75 By Steve Reid <sreid@sea-to-sky.net>
76 Still 100% public domain
77
78 1- Removed #include <process.h> and used return() instead of exit()
79 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
80 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
81
82 -----------------
83 Modified 4/01
84 By Saul Kravitz <Saul.Kravitz@celera.com>
85 Still 100% PD
86 Modified to run on Compaq Alpha hardware.  
87
88
89 */
90
91 /*
92 Test Vectors (from FIPS PUB 180-1)
93 "abc"
94   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
95 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
96   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
97 A million repetitions of "a"
98   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
99 */
100
101 /* #define SHA1HANDSOFF  */
102
103
104 #include <stdio.h>
105 #include <string.h>
106
107 #include "common/h/Types.h"
108 #include "common/h/sha1.h"
109 /* #include <process.h> */      /* prototype for exit() - JHB */
110 /* Using return() instead of exit() - SWR */
111
112 typedef struct {
113     uint32_t state[5];
114     uint32_t count[2];
115     unsigned char buffer[64];
116 } SHA1_CTX;
117
118 void SHA1Transform(uint32_t state[5], unsigned char buffer[64]);
119 void SHA1Init(SHA1_CTX* context);
120 void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len);  /*JHB */
121 void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
122
123 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
124
125 /* blk0() and blk() perform the initial expand. */
126 /* I got the idea of expanding during the round function from SSLeay */
127 #if defined(arch_power) //Big Endian
128 #define blk0(i) block->l[i]
129 #else
130 #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
131     |(rol(block->l[i],8)&0x00FF00FF))
132 #endif
133 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
134     ^block->l[(i+2)&15]^block->l[i&15],1))
135
136 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
137 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
138 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
139 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
140 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
141 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
142
143
144 #ifdef VERBOSE  /* SAK */
145 void SHAPrintContext(SHA1_CTX *context, char *msg){
146   printf("%s (%d,%d) %x %x %x %x %x\n",
147          msg,
148          context->count[0], context->count[1], 
149          context->state[0],
150          context->state[1],
151          context->state[2],
152          context->state[3],
153          context->state[4]);
154 }
155 #endif
156
157 /* Hash a single 512-bit block. This is the core of the algorithm. */
158
159 void SHA1Transform(uint32_t state[5], unsigned char buffer[64])
160 {
161 uint32_t a, b, c, d, e;
162 typedef union {
163     unsigned char c[64];
164     uint32_t l[16];
165 } CHAR64LONG16;
166 CHAR64LONG16* block;
167 #ifdef SHA1HANDSOFF
168 static unsigned char workspace[64];
169     block = (CHAR64LONG16*)workspace;
170     memcpy(block, buffer, 64);
171 #else
172     block = (CHAR64LONG16*)(void*)buffer;
173 #endif
174     /* Copy context->state[] to working vars */
175     a = state[0];
176     b = state[1];
177     c = state[2];
178     d = state[3];
179     e = state[4];
180     /* 4 rounds of 20 operations each. Loop unrolled. */
181     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);
182     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);
183     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);
184     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);
185     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);
186     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);
187     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);
188     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);
189     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);
190     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);
191     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);
192     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);
193     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);
194     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);
195     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);
196     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);
197     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);
198     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);
199     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);
200     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);
201     /* Add the working vars back into context.state[] */
202     state[0] += a;
203     state[1] += b;
204     state[2] += c;
205     state[3] += d;
206     state[4] += e;
207     /* Wipe variables */
208     a = b = c = d = e = 0;
209 }
210
211
212 /* SHA1Init - Initialize new context */
213
214 void SHA1Init(SHA1_CTX* context)
215 {
216     /* SHA1 initialization constants */
217     context->state[0] = 0x67452301;
218     context->state[1] = 0xEFCDAB89;
219     context->state[2] = 0x98BADCFE;
220     context->state[3] = 0x10325476;
221     context->state[4] = 0xC3D2E1F0;
222     context->count[0] = context->count[1] = 0;
223 }
224
225
226 /* Run your data through this. */
227
228 void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len)   /*JHB */
229 {
230 uint32_t i, j;  /* JHB */
231
232 #ifdef VERBOSE
233     SHAPrintContext(context, "before");
234 #endif
235     j = (context->count[0] >> 3) & 63;
236     if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
237     context->count[1] += (len >> 29);
238     if ((j + len) > 63) {
239         memcpy(&context->buffer[j], data, (i = 64-j));
240         SHA1Transform(context->state, context->buffer);
241         for ( ; i + 63 < len; i += 64) {
242             SHA1Transform(context->state, &data[i]);
243         }
244         j = 0;
245     }
246     else i = 0;
247     memcpy(&context->buffer[j], &data[i], len - i);
248 #ifdef VERBOSE
249     SHAPrintContext(context, "after ");
250 #endif
251 }
252
253
254 /* Add padding and return the message digest. */
255
256 void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
257 {
258 uint32_t i;     /* JHB */
259 unsigned char finalcount[8];
260
261     for (i = 0; i < 8; i++) {
262         finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
263          >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
264     }
265     SHA1Update(context, (unsigned char *)const_cast< char *>("\200"), 1);
266     while ((context->count[0] & 504) != 448) {
267         SHA1Update(context, (unsigned char *)const_cast<char *>("\0"), 1);
268     }
269     SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
270     for (i = 0; i < 20; i++) {
271         digest[i] = (unsigned char)
272          ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
273     }
274     /* Wipe variables */
275     i = 0;      /* JHB */
276     memset(context->buffer, 0, 64);
277     memset(context->state, 0, 20);
278     memset(context->count, 0, 8);
279     memset(finalcount, 0, 8);   /* SWR */
280 #ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
281     SHA1Transform(context->state, context->buffer);
282 #endif
283 }
284   
285 /*************************************************************/
286
287 char *sha1_file(const char *filename, char *result_ptr)
288 {
289     static char result[SHA1_STRING_LEN] = {0};
290
291     SHA1_CTX ctx;
292     unsigned char buf[16384];
293
294     if (result_ptr == NULL)
295         result_ptr = result;
296
297     FILE *fd = fopen(filename, "r");
298     if (!fd) return NULL;
299
300     SHA1Init(&ctx);
301     while (!feof(fd)) {
302         unsigned long len = fread((char *)buf, sizeof(char), sizeof(buf), fd);
303         if (ferror(fd)) {
304             fclose(fd);
305             return NULL;
306         }
307         SHA1Update(&ctx, buf, len);
308     }
309     SHA1Final(buf, &ctx);
310
311     fclose(fd);
312
313     for (unsigned int i = 0; i < SHA1_DIGEST_LEN; ++i)
314         sprintf(&result_ptr[i*2], "%02x", buf[i]);
315
316     return result_ptr;
317 }