/src/util-linux/lib/sha1.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * No copyright is claimed.  This code is in the public domain; do with  | 
3  |  |  * it what you wish.  | 
4  |  |  *  | 
5  |  |  * SHA-1 in C by Steve Reid <steve@edmweb.com>  | 
6  |  |  * 100% Public Domain  | 
7  |  |  *  | 
8  |  |  * Test Vectors (from FIPS PUB 180-1)  | 
9  |  |  * 1) "abc": A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D  | 
10  |  |  * 2) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq":  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1  | 
11  |  |  * 3) A million repetitions of "a":  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F  | 
12  |  |  */  | 
13  |  |  | 
14  |  | #define UL_SHA1HANDSOFF  | 
15  |  |  | 
16  |  | #include <stdio.h>  | 
17  |  | #include <string.h>  | 
18  |  | #include <stdint.h>  | 
19  |  |  | 
20  |  | #include "sha1.h"  | 
21  |  |  | 
22  | 0  | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))  | 
23  |  |  | 
24  |  | /* blk0() and blk() perform the initial expand. */  | 
25  |  | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__  | 
26  |  | # define blk0(i) block->l[i]  | 
27  |  | #else  | 
28  | 0  | # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \  | 
29  | 0  |     |(rol(block->l[i],8)&0x00FF00FF))  | 
30  |  | #endif  | 
31  |  |  | 
32  | 0  | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \  | 
33  | 0  |     ^block->l[(i+2)&15]^block->l[i&15],1))  | 
34  |  |  | 
35  |  | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */  | 
36  | 0  | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);  | 
37  | 0  | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);  | 
38  | 0  | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);  | 
39  | 0  | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);  | 
40  | 0  | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);  | 
41  |  |  | 
42  |  | /* Hash a single 512-bit block. This is the core of the algorithm. */  | 
43  |  |  | 
44  |  | void ul_SHA1Transform(uint32_t state[5], const unsigned char buffer[64])  | 
45  | 0  | { | 
46  | 0  |   uint32_t a, b, c, d, e;  | 
47  |  | 
  | 
48  | 0  |   typedef union { | 
49  | 0  |     unsigned char c[64];  | 
50  | 0  |     uint32_t l[16];  | 
51  | 0  |   } CHAR64LONG16;  | 
52  |  | 
  | 
53  | 0  | #ifdef UL_SHA1HANDSOFF  | 
54  | 0  |   CHAR64LONG16 block[1];  /* use array to appear as a pointer */  | 
55  |  | 
  | 
56  | 0  |   memcpy(block, buffer, 64);  | 
57  |  | #else  | 
58  |  |   /* The following had better never be used because it causes the  | 
59  |  |    * pointer-to-const buffer to be cast into a pointer to non-const.  | 
60  |  |    * And the result is written through.  I threw a "const" in, hoping  | 
61  |  |    * this will cause a diagnostic.  | 
62  |  |    */  | 
63  |  |   CHAR64LONG16 *block = (const CHAR64LONG16 *)buffer;  | 
64  |  | #endif  | 
65  |  |   /* Copy context->state[] to working vars */  | 
66  | 0  |   a = state[0];  | 
67  | 0  |   b = state[1];  | 
68  | 0  |   c = state[2];  | 
69  | 0  |   d = state[3];  | 
70  | 0  |   e = state[4];  | 
71  |  |   /* 4 rounds of 20 operations each. Loop unrolled. */  | 
72  | 0  |   R0(a, b, c, d, e, 0);  | 
73  | 0  |   R0(e, a, b, c, d, 1);  | 
74  | 0  |   R0(d, e, a, b, c, 2);  | 
75  | 0  |   R0(c, d, e, a, b, 3);  | 
76  | 0  |   R0(b, c, d, e, a, 4);  | 
77  | 0  |   R0(a, b, c, d, e, 5);  | 
78  | 0  |   R0(e, a, b, c, d, 6);  | 
79  | 0  |   R0(d, e, a, b, c, 7);  | 
80  | 0  |   R0(c, d, e, a, b, 8);  | 
81  | 0  |   R0(b, c, d, e, a, 9);  | 
82  | 0  |   R0(a, b, c, d, e, 10);  | 
83  | 0  |   R0(e, a, b, c, d, 11);  | 
84  | 0  |   R0(d, e, a, b, c, 12);  | 
85  | 0  |   R0(c, d, e, a, b, 13);  | 
86  | 0  |   R0(b, c, d, e, a, 14);  | 
87  | 0  |   R0(a, b, c, d, e, 15);  | 
88  | 0  |   R1(e, a, b, c, d, 16);  | 
89  | 0  |   R1(d, e, a, b, c, 17);  | 
90  | 0  |   R1(c, d, e, a, b, 18);  | 
91  | 0  |   R1(b, c, d, e, a, 19);  | 
92  | 0  |   R2(a, b, c, d, e, 20);  | 
93  | 0  |   R2(e, a, b, c, d, 21);  | 
94  | 0  |   R2(d, e, a, b, c, 22);  | 
95  | 0  |   R2(c, d, e, a, b, 23);  | 
96  | 0  |   R2(b, c, d, e, a, 24);  | 
97  | 0  |   R2(a, b, c, d, e, 25);  | 
98  | 0  |   R2(e, a, b, c, d, 26);  | 
99  | 0  |   R2(d, e, a, b, c, 27);  | 
100  | 0  |   R2(c, d, e, a, b, 28);  | 
101  | 0  |   R2(b, c, d, e, a, 29);  | 
102  | 0  |   R2(a, b, c, d, e, 30);  | 
103  | 0  |   R2(e, a, b, c, d, 31);  | 
104  | 0  |   R2(d, e, a, b, c, 32);  | 
105  | 0  |   R2(c, d, e, a, b, 33);  | 
106  | 0  |   R2(b, c, d, e, a, 34);  | 
107  | 0  |   R2(a, b, c, d, e, 35);  | 
108  | 0  |   R2(e, a, b, c, d, 36);  | 
109  | 0  |   R2(d, e, a, b, c, 37);  | 
110  | 0  |   R2(c, d, e, a, b, 38);  | 
111  | 0  |   R2(b, c, d, e, a, 39);  | 
112  | 0  |   R3(a, b, c, d, e, 40);  | 
113  | 0  |   R3(e, a, b, c, d, 41);  | 
114  | 0  |   R3(d, e, a, b, c, 42);  | 
115  | 0  |   R3(c, d, e, a, b, 43);  | 
116  | 0  |   R3(b, c, d, e, a, 44);  | 
117  | 0  |   R3(a, b, c, d, e, 45);  | 
118  | 0  |   R3(e, a, b, c, d, 46);  | 
119  | 0  |   R3(d, e, a, b, c, 47);  | 
120  | 0  |   R3(c, d, e, a, b, 48);  | 
121  | 0  |   R3(b, c, d, e, a, 49);  | 
122  | 0  |   R3(a, b, c, d, e, 50);  | 
123  | 0  |   R3(e, a, b, c, d, 51);  | 
124  | 0  |   R3(d, e, a, b, c, 52);  | 
125  | 0  |   R3(c, d, e, a, b, 53);  | 
126  | 0  |   R3(b, c, d, e, a, 54);  | 
127  | 0  |   R3(a, b, c, d, e, 55);  | 
128  | 0  |   R3(e, a, b, c, d, 56);  | 
129  | 0  |   R3(d, e, a, b, c, 57);  | 
130  | 0  |   R3(c, d, e, a, b, 58);  | 
131  | 0  |   R3(b, c, d, e, a, 59);  | 
132  | 0  |   R4(a, b, c, d, e, 60);  | 
133  | 0  |   R4(e, a, b, c, d, 61);  | 
134  | 0  |   R4(d, e, a, b, c, 62);  | 
135  | 0  |   R4(c, d, e, a, b, 63);  | 
136  | 0  |   R4(b, c, d, e, a, 64);  | 
137  | 0  |   R4(a, b, c, d, e, 65);  | 
138  | 0  |   R4(e, a, b, c, d, 66);  | 
139  | 0  |   R4(d, e, a, b, c, 67);  | 
140  | 0  |   R4(c, d, e, a, b, 68);  | 
141  | 0  |   R4(b, c, d, e, a, 69);  | 
142  | 0  |   R4(a, b, c, d, e, 70);  | 
143  | 0  |   R4(e, a, b, c, d, 71);  | 
144  | 0  |   R4(d, e, a, b, c, 72);  | 
145  | 0  |   R4(c, d, e, a, b, 73);  | 
146  | 0  |   R4(b, c, d, e, a, 74);  | 
147  | 0  |   R4(a, b, c, d, e, 75);  | 
148  | 0  |   R4(e, a, b, c, d, 76);  | 
149  | 0  |   R4(d, e, a, b, c, 77);  | 
150  | 0  |   R4(c, d, e, a, b, 78);  | 
151  | 0  |   R4(b, c, d, e, a, 79);  | 
152  |  |   /* Add the working vars back into context.state[] */  | 
153  | 0  |   state[0] += a;  | 
154  | 0  |   state[1] += b;  | 
155  | 0  |   state[2] += c;  | 
156  | 0  |   state[3] += d;  | 
157  | 0  |   state[4] += e;  | 
158  |  |   /* Wipe variables */  | 
159  | 0  | #ifdef HAVE_EXPLICIT_BZERO  | 
160  | 0  |   explicit_bzero(&a, sizeof(a));  | 
161  | 0  |   explicit_bzero(&b, sizeof(b));  | 
162  | 0  |   explicit_bzero(&c, sizeof(c));  | 
163  | 0  |   explicit_bzero(&d, sizeof(d));  | 
164  | 0  |   explicit_bzero(&e, sizeof(e));  | 
165  |  | #else  | 
166  |  |   a = b = c = d = e = 0;  | 
167  |  | #endif  | 
168  | 0  | #ifdef UL_SHA1HANDSOFF  | 
169  | 0  |   memset(block, '\0', sizeof(block));  | 
170  | 0  | #endif  | 
171  | 0  | }  | 
172  |  |  | 
173  |  | /* SHA1Init - Initialize new context */  | 
174  |  |  | 
175  |  | void ul_SHA1Init(UL_SHA1_CTX *context)  | 
176  | 0  | { | 
177  |  |   /* SHA1 initialization constants */  | 
178  | 0  |   context->state[0] = 0x67452301;  | 
179  | 0  |   context->state[1] = 0xEFCDAB89;  | 
180  | 0  |   context->state[2] = 0x98BADCFE;  | 
181  | 0  |   context->state[3] = 0x10325476;  | 
182  | 0  |   context->state[4] = 0xC3D2E1F0;  | 
183  | 0  |   context->count[0] = context->count[1] = 0;  | 
184  | 0  | }  | 
185  |  |  | 
186  |  | /* Run your data through this. */  | 
187  |  |  | 
188  |  | void ul_SHA1Update(UL_SHA1_CTX *context, const unsigned char *data, uint32_t len)  | 
189  | 0  | { | 
190  | 0  |   uint32_t i;  | 
191  |  | 
  | 
192  | 0  |   uint32_t j;  | 
193  |  | 
  | 
194  | 0  |   j = context->count[0];  | 
195  | 0  |   if ((context->count[0] += len << 3) < j)  | 
196  | 0  |     context->count[1]++;  | 
197  | 0  |   context->count[1] += (len >> 29);  | 
198  | 0  |   j = (j >> 3) & 63;  | 
199  | 0  |   if ((j + len) > 63) { | 
200  | 0  |     memcpy(&context->buffer[j], data, (i = 64 - j));  | 
201  | 0  |     ul_SHA1Transform(context->state, context->buffer);  | 
202  | 0  |     for (; i + 63 < len; i += 64) { | 
203  | 0  |       ul_SHA1Transform(context->state, &data[i]);  | 
204  | 0  |     }  | 
205  | 0  |     j = 0;  | 
206  | 0  |   } else  | 
207  | 0  |     i = 0;  | 
208  | 0  |   memcpy(&context->buffer[j], &data[i], len - i);  | 
209  | 0  | }  | 
210  |  |  | 
211  |  | /* Add padding and return the message digest. */  | 
212  |  |  | 
213  |  | void ul_SHA1Final(unsigned char digest[20], UL_SHA1_CTX *context)  | 
214  | 0  | { | 
215  | 0  |   unsigned i;  | 
216  |  | 
  | 
217  | 0  |   unsigned char finalcount[8];  | 
218  |  | 
  | 
219  | 0  |   unsigned char c;  | 
220  |  | 
  | 
221  |  | #if 0       /* untested "improvement" by DHR */  | 
222  |  |   /* Convert context->count to a sequence of bytes  | 
223  |  |    * in finalcount.  Second element first, but  | 
224  |  |    * big-endian order within element.  | 
225  |  |    * But we do it all backwards.  | 
226  |  |    */  | 
227  |  |   unsigned char *fcp = &finalcount[8];  | 
228  |  |  | 
229  |  |   for (i = 0; i < 2; i++) { | 
230  |  |     uint32_t t = context->count[i];  | 
231  |  |  | 
232  |  |     int j;  | 
233  |  |  | 
234  |  |     for (j = 0; j < 4; t >>= 8, j++)  | 
235  |  |       *--fcp = (unsigned char)t}  | 
236  |  | #else  | 
237  | 0  |   for (i = 0; i < 8; i++) { | 
238  | 0  |     finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255);  /* Endian independent */  | 
239  | 0  |   }  | 
240  | 0  | #endif  | 
241  | 0  |   c = 0200;  | 
242  | 0  |   ul_SHA1Update(context, &c, 1);  | 
243  | 0  |   while ((context->count[0] & 504) != 448) { | 
244  | 0  |     c = 0000;  | 
245  | 0  |     ul_SHA1Update(context, &c, 1);  | 
246  | 0  |   }  | 
247  | 0  |   ul_SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */  | 
248  | 0  |   for (i = 0; i < 20; i++) { | 
249  | 0  |     digest[i] = (unsigned char)  | 
250  | 0  |         ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);  | 
251  | 0  |   }  | 
252  |  |   /* Wipe variables */  | 
253  | 0  |   memset(context, '\0', sizeof(*context));  | 
254  | 0  |   memset(&finalcount, '\0', sizeof(finalcount));  | 
255  | 0  | }  | 
256  |  |  | 
257  |  | void ul_SHA1(char *hash_out, const char *str, unsigned len)  | 
258  | 0  | { | 
259  | 0  |   UL_SHA1_CTX ctx;  | 
260  | 0  |   unsigned int ii;  | 
261  |  | 
  | 
262  | 0  |   ul_SHA1Init(&ctx);  | 
263  | 0  |   for (ii = 0; ii < len; ii += 1)  | 
264  | 0  |     ul_SHA1Update(&ctx, (const unsigned char *)str + ii, 1);  | 
265  | 0  |   ul_SHA1Final((unsigned char *)hash_out, &ctx);  | 
266  | 0  |   hash_out[20] = '\0';  | 
267  | 0  | }  |