Silence another VC++ warning
[p5sagit/p5-mst-13.2.git] / ext / Digest / SHA / src / sha.c
1 /*
2  * sha.c: routines to compute SHA-1/224/256/384/512 digests
3  *
4  * Ref: NIST FIPS PUB 180-2 Secure Hash Standard
5  *
6  * Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved
7  *
8  * Version: 5.34
9  * Thu Feb  2 18:55:40 MST 2006
10  *
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stddef.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include "sha.h"
19 #include "sha64bit.h"
20
21 #define W32     SHA32                   /* useful abbreviations */
22 #define C32     SHA32_CONST
23 #define SR32    SHA32_SHR
24 #define SL32    SHA32_SHL
25 #define LO32    SHA_LO32
26 #define UCHR    unsigned char
27 #define UINT    unsigned int
28 #define ULNG    unsigned long
29 #define VP      void *
30
31 #define ROTR(x, n)      (SR32(x, n) | SL32(x, 32-(n)))
32 #define ROTL(x, n)      (SL32(x, n) | SR32(x, 32-(n)))
33
34 #define Ch(x, y, z)     ((z) ^ ((x) & ((y) ^ (z))))
35 #define Pa(x, y, z)     ((x) ^ (y) ^ (z))
36 #define Ma(x, y, z)     (((x) & (y)) | ((z) & ((x) | (y))))
37
38 #define SIGMA0(x)       (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
39 #define SIGMA1(x)       (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
40 #define sigma0(x)       (ROTR(x,  7) ^ ROTR(x, 18) ^ SR32(x,  3))
41 #define sigma1(x)       (ROTR(x, 17) ^ ROTR(x, 19) ^ SR32(x, 10))
42
43 #define K1      C32(0x5a827999)         /* SHA-1 constants */
44 #define K2      C32(0x6ed9eba1)
45 #define K3      C32(0x8f1bbcdc)
46 #define K4      C32(0xca62c1d6)
47
48 static W32 K256[64] =                   /* SHA-224/256 constants */
49 {
50         C32(0x428a2f98), C32(0x71374491), C32(0xb5c0fbcf), C32(0xe9b5dba5),
51         C32(0x3956c25b), C32(0x59f111f1), C32(0x923f82a4), C32(0xab1c5ed5),
52         C32(0xd807aa98), C32(0x12835b01), C32(0x243185be), C32(0x550c7dc3),
53         C32(0x72be5d74), C32(0x80deb1fe), C32(0x9bdc06a7), C32(0xc19bf174),
54         C32(0xe49b69c1), C32(0xefbe4786), C32(0x0fc19dc6), C32(0x240ca1cc),
55         C32(0x2de92c6f), C32(0x4a7484aa), C32(0x5cb0a9dc), C32(0x76f988da),
56         C32(0x983e5152), C32(0xa831c66d), C32(0xb00327c8), C32(0xbf597fc7),
57         C32(0xc6e00bf3), C32(0xd5a79147), C32(0x06ca6351), C32(0x14292967),
58         C32(0x27b70a85), C32(0x2e1b2138), C32(0x4d2c6dfc), C32(0x53380d13),
59         C32(0x650a7354), C32(0x766a0abb), C32(0x81c2c92e), C32(0x92722c85),
60         C32(0xa2bfe8a1), C32(0xa81a664b), C32(0xc24b8b70), C32(0xc76c51a3),
61         C32(0xd192e819), C32(0xd6990624), C32(0xf40e3585), C32(0x106aa070),
62         C32(0x19a4c116), C32(0x1e376c08), C32(0x2748774c), C32(0x34b0bcb5),
63         C32(0x391c0cb3), C32(0x4ed8aa4a), C32(0x5b9cca4f), C32(0x682e6ff3),
64         C32(0x748f82ee), C32(0x78a5636f), C32(0x84c87814), C32(0x8cc70208),
65         C32(0x90befffa), C32(0xa4506ceb), C32(0xbef9a3f7), C32(0xc67178f2)
66 };
67
68 static W32 H01[5] =                     /* SHA-1 initial hash value */
69 {
70         C32(0x67452301), C32(0xefcdab89), C32(0x98badcfe),
71         C32(0x10325476), C32(0xc3d2e1f0)
72 };
73
74 static W32 H0224[8] =                   /* SHA-224 initial hash value */
75 {
76         C32(0xc1059ed8), C32(0x367cd507), C32(0x3070dd17), C32(0xf70e5939),
77         C32(0xffc00b31), C32(0x68581511), C32(0x64f98fa7), C32(0xbefa4fa4)
78 };
79
80 static W32 H0256[8] =                   /* SHA-256 initial hash value */
81 {
82         C32(0x6a09e667), C32(0xbb67ae85), C32(0x3c6ef372), C32(0xa54ff53a),
83         C32(0x510e527f), C32(0x9b05688c), C32(0x1f83d9ab), C32(0x5be0cd19)
84 };
85
86 static void sha1(s, block)              /* SHA-1 transform */
87 SHA *s;
88 UCHR *block;
89 {
90         W32 a, b, c, d, e;
91         SHA_STO_CLASS W32 W[16];
92         W32 *wp = W;
93         W32 *H = (W32 *) s->H;
94
95         SHA32_SCHED(W, block);
96
97 /*
98  * Use SHA-1 alternate method from FIPS PUB 180-2 (ref. 6.1.3)
99  *
100  * To improve performance, unroll the loop and consolidate assignments
101  * by changing the roles of variables "a" through "e" at each step.
102  * Note that the variable "T" is no longer needed.
103  */
104
105 #define M1(a, b, c, d, e, f, k, w)              \
106         e += ROTL(a, 5) + f(b, c, d) + k + w;   \
107         b =  ROTL(b, 30)
108
109 #define M11(f, k, w)    M1(a, b, c, d, e, f, k, w);
110 #define M12(f, k, w)    M1(e, a, b, c, d, f, k, w);
111 #define M13(f, k, w)    M1(d, e, a, b, c, f, k, w);
112 #define M14(f, k, w)    M1(c, d, e, a, b, f, k, w);
113 #define M15(f, k, w)    M1(b, c, d, e, a, f, k, w);
114
115 #define W11(s)  W[(s+ 0) & 0xf]
116 #define W12(s)  W[(s+13) & 0xf]
117 #define W13(s)  W[(s+ 8) & 0xf]
118 #define W14(s)  W[(s+ 2) & 0xf]
119
120 #define A1(s)   (W11(s) = ROTL(W11(s) ^ W12(s) ^ W13(s) ^ W14(s), 1))
121
122         a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4];
123
124         M11(Ch, K1,  *wp++); M12(Ch, K1,  *wp++); M13(Ch, K1,  *wp++);
125         M14(Ch, K1,  *wp++); M15(Ch, K1,  *wp++); M11(Ch, K1,  *wp++);
126         M12(Ch, K1,  *wp++); M13(Ch, K1,  *wp++); M14(Ch, K1,  *wp++);
127         M15(Ch, K1,  *wp++); M11(Ch, K1,  *wp++); M12(Ch, K1,  *wp++);
128         M13(Ch, K1,  *wp++); M14(Ch, K1,  *wp++); M15(Ch, K1,  *wp++);
129         M11(Ch, K1,  *wp  ); M12(Ch, K1, A1( 0)); M13(Ch, K1, A1( 1));
130         M14(Ch, K1, A1( 2)); M15(Ch, K1, A1( 3)); M11(Pa, K2, A1( 4));
131         M12(Pa, K2, A1( 5)); M13(Pa, K2, A1( 6)); M14(Pa, K2, A1( 7));
132         M15(Pa, K2, A1( 8)); M11(Pa, K2, A1( 9)); M12(Pa, K2, A1(10));
133         M13(Pa, K2, A1(11)); M14(Pa, K2, A1(12)); M15(Pa, K2, A1(13));
134         M11(Pa, K2, A1(14)); M12(Pa, K2, A1(15)); M13(Pa, K2, A1( 0));
135         M14(Pa, K2, A1( 1)); M15(Pa, K2, A1( 2)); M11(Pa, K2, A1( 3));
136         M12(Pa, K2, A1( 4)); M13(Pa, K2, A1( 5)); M14(Pa, K2, A1( 6));
137         M15(Pa, K2, A1( 7)); M11(Ma, K3, A1( 8)); M12(Ma, K3, A1( 9));
138         M13(Ma, K3, A1(10)); M14(Ma, K3, A1(11)); M15(Ma, K3, A1(12));
139         M11(Ma, K3, A1(13)); M12(Ma, K3, A1(14)); M13(Ma, K3, A1(15));
140         M14(Ma, K3, A1( 0)); M15(Ma, K3, A1( 1)); M11(Ma, K3, A1( 2));
141         M12(Ma, K3, A1( 3)); M13(Ma, K3, A1( 4)); M14(Ma, K3, A1( 5));
142         M15(Ma, K3, A1( 6)); M11(Ma, K3, A1( 7)); M12(Ma, K3, A1( 8));
143         M13(Ma, K3, A1( 9)); M14(Ma, K3, A1(10)); M15(Ma, K3, A1(11));
144         M11(Pa, K4, A1(12)); M12(Pa, K4, A1(13)); M13(Pa, K4, A1(14));
145         M14(Pa, K4, A1(15)); M15(Pa, K4, A1( 0)); M11(Pa, K4, A1( 1));
146         M12(Pa, K4, A1( 2)); M13(Pa, K4, A1( 3)); M14(Pa, K4, A1( 4));
147         M15(Pa, K4, A1( 5)); M11(Pa, K4, A1( 6)); M12(Pa, K4, A1( 7));
148         M13(Pa, K4, A1( 8)); M14(Pa, K4, A1( 9)); M15(Pa, K4, A1(10));
149         M11(Pa, K4, A1(11)); M12(Pa, K4, A1(12)); M13(Pa, K4, A1(13));
150         M14(Pa, K4, A1(14)); M15(Pa, K4, A1(15));
151
152         H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e;
153 }
154
155 static void sha256(s, block)            /* SHA-224/256 transform */
156 SHA *s;
157 UCHR *block;
158 {
159         W32 a, b, c, d, e, f, g, h, T1;
160         SHA_STO_CLASS W32 W[16];
161         W32 *kp = K256;
162         W32 *wp = W;
163         W32 *H = (W32 *) s->H;
164
165         SHA32_SCHED(W, block);
166
167 /*
168  * Use same technique as in sha1()
169  *
170  * To improve performance, unroll the loop and consolidate assignments
171  * by changing the roles of variables "a" through "h" at each step.
172  * Note that the variable "T2" is no longer needed.
173  */
174
175 #define M2(a, b, c, d, e, f, g, h, w)                           \
176         T1 = h  + SIGMA1(e) + Ch(e, f, g) + (*kp++) + w;        \
177         h  = T1 + SIGMA0(a) + Ma(a, b, c); d += T1;
178
179 #define W21(s)  W[(s+ 0) & 0xf]
180 #define W22(s)  W[(s+14) & 0xf]
181 #define W23(s)  W[(s+ 9) & 0xf]
182 #define W24(s)  W[(s+ 1) & 0xf]
183
184 #define A2(s)   (W21(s) += sigma1(W22(s)) + W23(s) + sigma0(W24(s)))
185
186 #define M21(w)  M2(a, b, c, d, e, f, g, h, w)
187 #define M22(w)  M2(h, a, b, c, d, e, f, g, w)
188 #define M23(w)  M2(g, h, a, b, c, d, e, f, w)
189 #define M24(w)  M2(f, g, h, a, b, c, d, e, w)
190 #define M25(w)  M2(e, f, g, h, a, b, c, d, w)
191 #define M26(w)  M2(d, e, f, g, h, a, b, c, w)
192 #define M27(w)  M2(c, d, e, f, g, h, a, b, w)
193 #define M28(w)  M2(b, c, d, e, f, g, h, a, w)
194
195         a = H[0]; b = H[1]; c = H[2]; d = H[3];
196         e = H[4]; f = H[5]; g = H[6]; h = H[7];
197
198         M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
199         M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++);
200         M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
201         M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp  );
202         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
203         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
204         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
205         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
206         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
207         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
208         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
209         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
210         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
211         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
212         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
213         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
214
215         H[0] += a; H[1] += b; H[2] += c; H[3] += d;
216         H[4] += e; H[5] += f; H[6] += g; H[7] += h;
217 }
218
219 #include "sha64bit.c"
220
221 #define SETBIT(s, pos)  s[(pos) >> 3] |=  (0x01 << (7 - (pos) % 8))
222 #define CLRBIT(s, pos)  s[(pos) >> 3] &= ~(0x01 << (7 - (pos) % 8))
223 #define NBYTES(nbits)   ((nbits) > 0 ? 1 + (((nbits) - 1) >> 3) : 0)
224 #define HEXLEN(nbytes)  ((nbytes) << 1)
225 #define B64LEN(nbytes)  (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \
226                         : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1)
227
228 /* w32mem: writes 32-bit word to memory in big-endian order */
229 static void w32mem(mem, w32)
230 UCHR *mem;
231 W32 w32;
232 {
233         int i;
234
235         for (i = 0; i < 4; i++)
236                 *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff);
237 }
238
239 /* digcpy: writes current state to digest buffer */
240 static void digcpy(s)
241 SHA *s;
242 {
243         UINT i;
244         UCHR *d = s->digest;
245         W32 *p32 = (W32 *) s->H;
246         W64 *p64 = (W64 *) s->H;
247
248         if (s->alg <= SHA256)
249                 for (i = 0; i < 8; i++, d += 4)
250                         w32mem(d, *p32++);
251         else
252                 for (i = 0; i < 8; i++, d += 8) {
253                         w32mem(d, (W32) ((*p64 >> 16) >> 16));
254                         w32mem(d+4, (W32) (*p64++ & SHA32_MAX));
255                 }
256 }
257
258 #define SHA_INIT(algo, transform)                                       \
259         do {                                                            \
260                 memset(s, 0, sizeof(SHA));                              \
261                 s->alg = algo; s->sha = sha ## transform;               \
262                 memcpy(s->H, H0 ## algo, sizeof(H0 ## algo));           \
263                 s->blocksize = SHA ## algo ## _BLOCK_BITS;              \
264                 s->digestlen = SHA ## algo ## _DIGEST_BITS >> 3;        \
265         } while (0)
266
267 /* sharewind: re-initializes the digest object */
268 void sharewind(s)
269 SHA *s;
270 {
271         if      (s->alg == SHA1)   SHA_INIT(1, 1);
272         else if (s->alg == SHA224) SHA_INIT(224, 256);
273         else if (s->alg == SHA256) SHA_INIT(256, 256);
274         else if (s->alg == SHA384) SHA_INIT(384, 512);
275         else if (s->alg == SHA512) SHA_INIT(512, 512);
276 }
277
278 /* shaopen: creates a new digest object */
279 SHA *shaopen(alg)
280 int alg;
281 {
282         SHA *s;
283
284         if (alg != SHA1 && alg != SHA224 && alg != SHA256 &&
285                 alg != SHA384 && alg != SHA512)
286                 return(NULL);
287         if (alg >= SHA384 && !sha_384_512)
288                 return(NULL);
289         SHA_newz(0, s, 1, SHA);
290         if (s == NULL)
291                 return(NULL);
292         s->alg = alg;
293         sharewind(s);
294         return(s);
295 }
296
297 /* shadirect: updates state directly (w/o going through s->block) */
298 static ULNG shadirect(bitstr, bitcnt, s)
299 UCHR *bitstr;
300 ULNG bitcnt;
301 SHA *s;
302 {
303         ULNG savecnt = bitcnt;
304
305         while (bitcnt >= s->blocksize) {
306                 s->sha(s, bitstr);
307                 bitstr += (s->blocksize >> 3);
308                 bitcnt -= s->blocksize;
309         }
310         if (bitcnt > 0) {
311                 memcpy(s->block, bitstr, NBYTES(bitcnt));
312                 s->blockcnt = bitcnt;
313         }
314         return(savecnt);
315 }
316
317 /* shabytes: updates state for byte-aligned input data */
318 static ULNG shabytes(bitstr, bitcnt, s)
319 UCHR *bitstr;
320 ULNG bitcnt;
321 SHA *s;
322 {
323         UINT offset;
324         UINT nbits;
325         ULNG savecnt = bitcnt;
326
327         offset = s->blockcnt >> 3;
328         if (s->blockcnt + bitcnt >= s->blocksize) {
329                 nbits = s->blocksize - s->blockcnt;
330                 memcpy(s->block+offset, bitstr, nbits>>3);
331                 bitcnt -= nbits;
332                 bitstr += (nbits >> 3);
333                 s->sha(s, s->block), s->blockcnt = 0;
334                 shadirect(bitstr, bitcnt, s);
335         }
336         else {
337                 memcpy(s->block+offset, bitstr, NBYTES(bitcnt));
338                 s->blockcnt += bitcnt;
339         }
340         return(savecnt);
341 }
342
343 /* shabits: updates state for bit-aligned input data */
344 static ULNG shabits(bitstr, bitcnt, s)
345 UCHR *bitstr;
346 ULNG bitcnt;
347 SHA *s;
348 {
349         UINT i;
350         UINT gap;
351         ULNG nbits;
352         UCHR buf[1<<9];
353         UINT bufsize = sizeof(buf);
354         ULNG bufbits = (ULNG) bufsize << 3;
355         UINT nbytes = NBYTES(bitcnt);
356         ULNG savecnt = bitcnt;
357
358         gap = 8 - s->blockcnt % 8;
359         s->block[s->blockcnt>>3] &= ~0 << gap;
360         s->block[s->blockcnt>>3] |= *bitstr >> (8 - gap);
361         s->blockcnt += bitcnt < gap ? bitcnt : gap;
362         if (bitcnt < gap)
363                 return(savecnt);
364         if (s->blockcnt == s->blocksize)
365                 s->sha(s, s->block), s->blockcnt = 0;
366         if ((bitcnt -= gap) == 0)
367                 return(savecnt);
368         while (nbytes > bufsize) {
369                 for (i = 0; i < bufsize; i++)
370                         buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
371                 nbits = bitcnt < bufbits ? bitcnt : bufbits;
372                 shabytes(buf, nbits, s);
373                 bitcnt -= nbits, bitstr += bufsize, nbytes -= bufsize;
374         }
375         for (i = 0; i < nbytes - 1; i++)
376                 buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
377         buf[nbytes-1] = bitstr[nbytes-1] << gap;
378         shabytes(buf, bitcnt, s);
379         return(savecnt);
380 }
381
382 /* shawrite: triggers a state update using data in bitstr/bitcnt */
383 ULNG shawrite(bitstr, bitcnt, s)
384 UCHR *bitstr;
385 ULNG bitcnt;
386 SHA *s;
387 {
388         if (bitcnt < 1)
389                 return(0);
390         if (SHA_LO32(s->lenll += bitcnt) < bitcnt)
391                 if (SHA_LO32(++s->lenlh) == 0)
392                         if (SHA_LO32(++s->lenhl) == 0)
393                                 s->lenhh++;
394         if (s->blockcnt == 0)
395                 return(shadirect(bitstr, bitcnt, s));
396         else if (s->blockcnt % 8 == 0)
397                 return(shabytes(bitstr, bitcnt, s));
398         else
399                 return(shabits(bitstr, bitcnt, s));
400 }
401
402 /* shafinish: pads remaining block(s) and computes final digest state */
403 void shafinish(s)
404 SHA *s;
405 {
406         UINT lenpos, lhpos, llpos;
407
408         lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896;
409         lhpos  = s->blocksize == SHA1_BLOCK_BITS ?  56 : 120;
410         llpos  = s->blocksize == SHA1_BLOCK_BITS ?  60 : 124;
411         SETBIT(s->block, s->blockcnt), s->blockcnt++;
412         while (s->blockcnt > lenpos)
413                 if (s->blockcnt < s->blocksize)
414                         CLRBIT(s->block, s->blockcnt), s->blockcnt++;
415                 else
416                         s->sha(s, s->block), s->blockcnt = 0;
417         while (s->blockcnt < lenpos)
418                 CLRBIT(s->block, s->blockcnt), s->blockcnt++;
419         if (s->blocksize > SHA1_BLOCK_BITS) {
420                 w32mem(s->block + 112, s->lenhh);
421                 w32mem(s->block + 116, s->lenhl);
422         }
423         w32mem(s->block + lhpos, s->lenlh);
424         w32mem(s->block + llpos, s->lenll);
425         s->sha(s, s->block);
426 }
427
428 /* shadigest: returns pointer to current digest (binary) */
429 UCHR *shadigest(s)
430 SHA *s;
431 {
432         digcpy(s);
433         return(s->digest);
434 }
435
436 /* shahex: returns pointer to current digest (hexadecimal) */
437 char *shahex(s)
438 SHA *s;
439 {
440         int i;
441
442         digcpy(s);
443         s->hex[0] = '\0';
444         if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex))
445                 return(s->hex);
446         for (i = 0; i < s->digestlen; i++)
447                 sprintf(s->hex+i*2, "%02x", s->digest[i]);
448         return(s->hex);
449 }
450
451 /* map: translation map for Base 64 encoding */
452 static char map[] =             
453         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
454
455 /* encbase64: encodes input (0 to 3 bytes) into Base 64 */
456 static void encbase64(in, n, out)
457 UCHR *in;
458 int n;
459 char *out;
460 {
461         UCHR byte[3] = {0, 0, 0};
462
463         out[0] = '\0';
464         if (n < 1 || n > 3)
465                 return;
466         memcpy(byte, in, n);
467         out[0] = map[byte[0] >> 2];
468         out[1] = map[((byte[0] & 0x03) << 4) | (byte[1] >> 4)];
469         out[2] = map[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)];
470         out[3] = map[byte[2] & 0x3f];
471         out[n+1] = '\0';
472 }
473
474 /* shabase64: returns pointer to current digest (Base 64) */
475 char *shabase64(s)
476 SHA *s;
477 {
478         int n;
479         UCHR *q;
480         char out[5];
481
482         digcpy(s);
483         s->base64[0] = '\0';
484         if (B64LEN(s->digestlen) >= sizeof(s->base64))
485                 return(s->base64);
486         for (n = s->digestlen, q = s->digest; n > 3; n -= 3, q += 3) {
487                 encbase64(q, 3, out);
488                 strcat(s->base64, out);
489         }
490         encbase64(q, n, out);
491         strcat(s->base64, out);
492         return(s->base64);
493 }
494
495 /* shadsize: returns length of digest in bytes */
496 int shadsize(s)
497 SHA *s;
498 {
499         return(s->digestlen);
500 }
501
502 /* shadup: duplicates current digest object */
503 SHA *shadup(s)
504 SHA *s;
505 {
506         SHA *p;
507
508         SHA_new(0, p, 1, SHA);
509         if (p == NULL)
510                 return(NULL);
511         memcpy(p, s, sizeof(SHA));
512         return(p);
513 }
514
515 /* shadump: dumps digest object to a human-readable ASCII file */
516 int shadump(file, s)
517 char *file;
518 SHA *s;
519 {
520         unsigned int i, j;
521         SHA_FILE *f;
522         UCHR *p = shadigest(s);
523
524         if (file == NULL || strlen(file) == 0)
525                 f = SHA_stdout();
526         else if ((f = SHA_open(file, "w")) == NULL)
527                 return(0);
528         SHA_fprintf(f, "alg:%d\nH", s->alg);
529         for (i = 0; i < 8; i++)
530                 for (j = 0; j < (UINT) (s->alg <= 256 ? 4 : 8); j++)
531                         SHA_fprintf(f, "%s%02x", j==0 ? ":" : "", *p++);
532         SHA_fprintf(f, "\nblock");
533         for (i = 0; i < s->blocksize>>3; i++)
534                 SHA_fprintf(f, ":%02x", s->block[i]);
535         SHA_fprintf(f, "\nblockcnt:%u\n", s->blockcnt);
536         SHA_fprintf(f, "lenhh:%lu\nlenhl:%lu\nlenlh:%lu\nlenll:%lu\n",
537                 (ULNG) LO32(s->lenhh), (ULNG) LO32(s->lenhl),
538                 (ULNG) LO32(s->lenlh), (ULNG) LO32(s->lenll));
539         if (f != SHA_stdout())
540                 SHA_close(f);
541         return(1);
542 }
543
544 /* fgetstr: reads (and returns pointer to) next line of file */
545 static char *fgetstr(line, maxsize, f)
546 char *line;
547 UINT maxsize;
548 SHA_FILE *f;
549 {
550         char *p;
551
552         if (SHA_feof(f) || maxsize == 0)
553                 return(NULL);
554         for (p = line; !SHA_feof(f) && maxsize > 1; maxsize--)
555                 if ((*p++ = SHA_getc(f)) == '\n')
556                         break;
557         *p = '\0';
558         return(line);
559 }
560
561 /* empty: returns true if line contains only whitespace characters */
562 static int empty(line)
563 char *line;
564 {
565         char *p;
566
567         for (p = line; *p; p++)
568                 if (!isspace(*p))
569                         return(0);
570         return(1);
571 }
572
573 /* getval: null-terminates field value, and sets pointer to rest of line */
574 static char *getval(line, pprest)
575 char *line;
576 char **pprest;
577 {
578         char *p, *v;
579
580         for (v = line; *v == ':' || isspace(*v); v++)
581                 ;
582         for (p = v; *p; p++) {
583                 if (*p == ':' || isspace(*p)) {
584                         *p++ = '\0';
585                         break;
586                 }
587         }
588         *pprest = p;
589         return(p == v ? NULL : v);
590 }
591
592 /* types of values present in dump file */
593 #define T_C 1                   /* character */
594 #define T_I 2                   /* normal integer */
595 #define T_L 3                   /* 32-bit value */
596 #define T_Q 4                   /* 64-bit value */
597
598 /* ldvals: checks next line in dump file against tag, and loads values */
599 static int ldvals(f, tag, type, pval, reps, base)
600 SHA_FILE *f;
601 char *tag;
602 int type;
603 void *pval;
604 int reps;
605 int base;
606 {
607         char *p, *pr, line[512];
608         UCHR *pc = (UCHR *) pval; UINT *pi = (UINT *) pval;
609         W32  *pl = (W32  *) pval; W64  *pq = (W64  *) pval;
610
611         while ((p = fgetstr(line, sizeof(line), f)) != NULL)
612                 if (line[0] != '#' && !empty(line))
613                         break;
614         if (p == NULL || strcmp(getval(line, &pr), tag) != 0)
615                 return(0);
616         while (reps-- > 0) {
617                 if ((p = getval(pr, &pr)) == NULL)
618                         return(1);
619                 switch (type) {
620                 case T_C: *pc++ = (UCHR) strtoul(p, NULL, base); break;
621                 case T_I: *pi++ = (UINT) strtoul(p, NULL, base); break;
622                 case T_L: *pl++ = (W32 ) strtoul(p, NULL, base); break;
623                 case T_Q: *pq++ = (W64 ) strto64(p            ); break;
624                 }
625         }
626         return(1);
627 }
628
629 /* closeall: closes dump file and de-allocates digest object */
630 static SHA *closeall(f, s)
631 SHA_FILE *f;
632 SHA *s;
633 {
634         if (f != NULL && f != SHA_stdin())
635                 SHA_close(f);
636         if (s != NULL)
637                 shaclose(s);
638         return(NULL);
639 }
640
641 /* shaload: creates digest object corresponding to contents of dump file */
642 SHA *shaload(file)
643 char *file;
644 {
645         int alg;
646         SHA *s = NULL;
647         SHA_FILE *f;
648
649         if (file == NULL || strlen(file) == 0)
650                 f = SHA_stdin();
651         else if ((f = SHA_open(file, "r")) == NULL)
652                 return(NULL);
653         if (
654                 /* avoid parens by exploiting precedence of (type)&-> */
655                 !ldvals(f,"alg",T_I,(VP)&alg,1,10)                      ||
656                 ((s = shaopen(alg)) == NULL)                            ||
657                 !ldvals(f,"H",alg<=SHA256?T_L:T_Q,(VP)s->H,8,16)        ||
658                 !ldvals(f,"block",T_C,(VP)s->block,s->blocksize/8,16)   ||
659                 !ldvals(f,"blockcnt",T_I,(VP)&s->blockcnt,1,10)         ||
660                 (alg <= SHA256 && s->blockcnt >= SHA1_BLOCK_BITS)       ||
661                 (alg >= SHA384 && s->blockcnt >= SHA384_BLOCK_BITS)     ||
662                 !ldvals(f,"lenhh",T_L,(VP)&s->lenhh,1,10)               ||
663                 !ldvals(f,"lenhl",T_L,(VP)&s->lenhl,1,10)               ||
664                 !ldvals(f,"lenlh",T_L,(VP)&s->lenlh,1,10)               ||
665                 !ldvals(f,"lenll",T_L,(VP)&s->lenll,1,10)
666         )
667                 return(closeall(f, s));
668         if (f != SHA_stdin())
669                 SHA_close(f);
670         return(s);
671 }
672
673 /* shaclose: de-allocates digest object */
674 int shaclose(s)
675 SHA *s;
676 {
677         if (s != NULL) {
678                 memset(s, 0, sizeof(SHA));
679                 SHA_free(s);
680         }
681         return(0);
682 }