1 /***********************************************************
2 * libsrs_alt - A simple SRS implementation *
3 ***********************************************************/
4
5 /* (C)2004 Miles Wilton <miles@mirtol.com> */
6
7 /* License: GPL */
8
9 /* This file:
10
11 sha1.c
12
13 Perform SHA1
14 */
15
16 #include <string.h>
17
18 #include "sha1.h"
19
20
21 /* mHMAC Structure */
22
23 mHMAC_DIGEST mHMACD_SHA1 = {
24 64,
25 20,
26 sizeof(mSHA1),
27 mSHA1_start,
28 mSHA1_block,
29 mSHA1_process,
30 mSHA1_end
31 };
32
33
34 /***********************************************************
35 mSHA1_start - Init SHA1 structure
36
37 */
38
mSHA1_start(mSHA1 * sha1)39 int mSHA1_start(mSHA1 *sha1)
40 {
41 sha1->len = 0;
42 sha1->blen = 0;
43 sha1->H[0] = 0x67452301;
44 sha1->H[1] = 0xEFCDAB89;
45 sha1->H[2] = 0x98BADCFE;
46 sha1->H[3] = 0x10325476;
47 sha1->H[4] = 0xC3D2E1F0;
48
49 return 0;
50 }
51
52
53 /***********************************************************
54 mSHA1_block - Process 512-bit block
55
56 */
57
mSHA1_block(mSHA1 * sha1,unsigned char * block)58 int mSHA1_block(mSHA1 *sha1, unsigned char *block)
59 {
60 u_int32_t A, B, C, D, E;
61 u_int32_t W[80];
62 int t;
63
64 // Compute Ws
65 for(t = 0; t < 16; t++)
66 {
67 W[t] = (block[0] << 24) | (block[1] << 16) | (block[2] << 8) | block[3]; // Ensure byte order
68 block += 4;
69 }
70 for(t = 16; t < 80; t++)
71 {
72 register u_int32_t X = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
73 W[t] = (X << 1) | (X >> 31);
74 }
75
76 A = sha1->H[0];
77 B = sha1->H[1];
78 C = sha1->H[2];
79 D = sha1->H[3];
80 E = sha1->H[4];
81
82 // Digest (in 4 runs for different f-functions/K-values)
83 for(t = 0; t < 20; t++)
84 {
85 register u_int32_t TEMP = ((A << 5) | (A >> 27)) + ((B & C) | ((~B) & D)) + E + W[t] + 0x5A827999;
86 E = D;
87 D = C;
88 C = (B << 30) | (B >> 2);
89 B = A;
90 A = TEMP;
91 }
92 for(; t < 40; t++)
93 {
94 register u_int32_t TEMP = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[t] + 0x6ED9EBA1;
95 E = D;
96 D = C;
97 C = (B << 30) | (B >> 2);
98 B = A;
99 A = TEMP;
100 }
101 for(; t < 60; t++)
102 {
103 register u_int32_t TEMP = ((A << 5) | (A >> 27)) + ((B & C) | (B & D) | (C & D)) + E + W[t] + 0x8F1BBCDC;
104 E = D;
105 D = C;
106 C = (B << 30) | (B >> 2);
107 B = A;
108 A = TEMP;
109 }
110 for(; t < 80; t++)
111 {
112 register u_int32_t TEMP = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[t] + 0xCA62C1D6;
113 E = D;
114 D = C;
115 C = (B << 30) | (B >> 2);
116 B = A;
117 A = TEMP;
118 }
119
120 // Update hash
121 sha1->H[0] += A;
122 sha1->H[1] += B;
123 sha1->H[2] += C;
124 sha1->H[3] += D;
125 sha1->H[4] += E;
126
127 return 0;
128 }
129
130
131 /***********************************************************
132 mSHA1_process - Add a string to hash
133
134 */
mSHA1_process(mSHA1 * sha1,unsigned char * data,int data_len)135 int mSHA1_process(mSHA1 *sha1, unsigned char *data, int data_len)
136 {
137 int b, n = 0;
138
139 // Fulfill buffered data obligations
140 if(sha1->blen)
141 {
142 b = 64 - sha1->blen;
143 if(b > data_len)
144 {
145 // Just add data to buffer and return
146 memcpy(&sha1->b[sha1->blen], data, data_len);
147 sha1->blen += data_len;
148 return 0;
149 }
150 else
151 {
152 // Fill buffer and process block
153 memcpy(&sha1->b[sha1->blen], data, b);
154 n += b;
155 mSHA1_block(sha1, sha1->b);
156 }
157 }
158
159 // Go until we don't have a full block
160 while(data_len - n >= 64)
161 {
162 mSHA1_block(sha1, &data[n]);
163 sha1->len += 512;
164 n += 64;
165 }
166
167 // copy remaining data to buffer
168 sha1->blen = data_len - n;
169 memcpy(sha1->b, &data[n], sha1->blen);
170
171 return 0;
172 }
173
174
175 /***********************************************************
176 mSHA1_end - Finalise hash
177
178 */
mSHA1_end(mSHA1 * sha1,unsigned char * hash_buffer)179 int mSHA1_end(mSHA1 *sha1, unsigned char *hash_buffer)
180 {
181 // sha1->blen should _NEVER_ be 64
182 sha1->b[sha1->blen] = 0x80;
183
184 // Calculate final length
185 sha1->len += sha1->blen << 3;
186
187 // Pad remaining data
188 if(sha1->blen > 55)
189 {
190 memset(&sha1->b[sha1->blen+1], 0, 63 - sha1->blen);
191 mSHA1_block(sha1, sha1->b);
192
193 memset(sha1->b, 0, 56);
194 }
195 else
196 memset(&sha1->b[sha1->blen+1], 0, 55 - sha1->blen);
197
198 // Add length (ensuring byte order)
199 sha1->b[56] = (sha1->len >> 56) & 0xFF;
200 sha1->b[57] = (sha1->len >> 48) & 0xFF;
201 sha1->b[58] = (sha1->len >> 40) & 0xFF;
202 sha1->b[59] = (sha1->len >> 32) & 0xFF;
203 sha1->b[60] = (sha1->len >> 24) & 0xFF;
204 sha1->b[61] = (sha1->len >> 16) & 0xFF;
205 sha1->b[62] = (sha1->len >> 8) & 0xFF;
206 sha1->b[63] = sha1->len & 0xFF;
207
208 // Process final block
209 mSHA1_block(sha1, sha1->b);
210
211 // Get hash
212 if(hash_buffer)
213 mSHA1_gethash(sha1, hash_buffer);
214
215 return 0;
216 }
217
218
219 /***********************************************************
220 mSHA1_gethash - Get hash string (fills 20 bytes)
221
222 */
mSHA1_gethash(mSHA1 * sha1,unsigned char * hash_buffer)223 int mSHA1_gethash(mSHA1 *sha1, unsigned char *hash_buffer)
224 {
225 int n;
226
227 for(n = 0; n < 5; n++)
228 {
229 *hash_buffer++ = (sha1->H[n] >> 24) & 0xFF;
230 *hash_buffer++ = (sha1->H[n] >> 16) & 0xFF;
231 *hash_buffer++ = (sha1->H[n] >> 8) & 0xFF;
232 *hash_buffer++ = sha1->H[n] & 0xFF;
233 }
234
235 return 0;
236 }
237
238
239