Upgrade to Digest::SHA 5.46
[p5sagit/p5-mst-13.2.git] / ext / Digest / SHA / src / sha.c
CommitLineData
05128928 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 *
747da336 6 * Copyright (C) 2003-2007 Mark Shelor, All Rights Reserved
05128928 7 *
0bc2b4f8 8 * Version: 5.46
9 * Wed Apr 9 05:04:00 MST 2008
05128928 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
48static 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
68static W32 H01[5] = /* SHA-1 initial hash value */
69{
70 C32(0x67452301), C32(0xefcdab89), C32(0x98badcfe),
71 C32(0x10325476), C32(0xc3d2e1f0)
72};
73
74static 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
80static 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
44e8b72c 86static void sha1(SHA *s, UCHR *block) /* SHA-1 transform */
05128928 87{
88 W32 a, b, c, d, e;
89 SHA_STO_CLASS W32 W[16];
90 W32 *wp = W;
91 W32 *H = (W32 *) s->H;
92
93 SHA32_SCHED(W, block);
94
95/*
96 * Use SHA-1 alternate method from FIPS PUB 180-2 (ref. 6.1.3)
97 *
98 * To improve performance, unroll the loop and consolidate assignments
99 * by changing the roles of variables "a" through "e" at each step.
100 * Note that the variable "T" is no longer needed.
101 */
102
103#define M1(a, b, c, d, e, f, k, w) \
104 e += ROTL(a, 5) + f(b, c, d) + k + w; \
105 b = ROTL(b, 30)
106
107#define M11(f, k, w) M1(a, b, c, d, e, f, k, w);
108#define M12(f, k, w) M1(e, a, b, c, d, f, k, w);
109#define M13(f, k, w) M1(d, e, a, b, c, f, k, w);
110#define M14(f, k, w) M1(c, d, e, a, b, f, k, w);
111#define M15(f, k, w) M1(b, c, d, e, a, f, k, w);
112
113#define W11(s) W[(s+ 0) & 0xf]
114#define W12(s) W[(s+13) & 0xf]
115#define W13(s) W[(s+ 8) & 0xf]
116#define W14(s) W[(s+ 2) & 0xf]
117
118#define A1(s) (W11(s) = ROTL(W11(s) ^ W12(s) ^ W13(s) ^ W14(s), 1))
119
120 a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4];
121
122 M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); M13(Ch, K1, *wp++);
123 M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); M11(Ch, K1, *wp++);
124 M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); M14(Ch, K1, *wp++);
125 M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); M12(Ch, K1, *wp++);
126 M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); M15(Ch, K1, *wp++);
127 M11(Ch, K1, *wp ); M12(Ch, K1, A1( 0)); M13(Ch, K1, A1( 1));
128 M14(Ch, K1, A1( 2)); M15(Ch, K1, A1( 3)); M11(Pa, K2, A1( 4));
129 M12(Pa, K2, A1( 5)); M13(Pa, K2, A1( 6)); M14(Pa, K2, A1( 7));
130 M15(Pa, K2, A1( 8)); M11(Pa, K2, A1( 9)); M12(Pa, K2, A1(10));
131 M13(Pa, K2, A1(11)); M14(Pa, K2, A1(12)); M15(Pa, K2, A1(13));
132 M11(Pa, K2, A1(14)); M12(Pa, K2, A1(15)); M13(Pa, K2, A1( 0));
133 M14(Pa, K2, A1( 1)); M15(Pa, K2, A1( 2)); M11(Pa, K2, A1( 3));
134 M12(Pa, K2, A1( 4)); M13(Pa, K2, A1( 5)); M14(Pa, K2, A1( 6));
135 M15(Pa, K2, A1( 7)); M11(Ma, K3, A1( 8)); M12(Ma, K3, A1( 9));
136 M13(Ma, K3, A1(10)); M14(Ma, K3, A1(11)); M15(Ma, K3, A1(12));
137 M11(Ma, K3, A1(13)); M12(Ma, K3, A1(14)); M13(Ma, K3, A1(15));
138 M14(Ma, K3, A1( 0)); M15(Ma, K3, A1( 1)); M11(Ma, K3, A1( 2));
139 M12(Ma, K3, A1( 3)); M13(Ma, K3, A1( 4)); M14(Ma, K3, A1( 5));
140 M15(Ma, K3, A1( 6)); M11(Ma, K3, A1( 7)); M12(Ma, K3, A1( 8));
141 M13(Ma, K3, A1( 9)); M14(Ma, K3, A1(10)); M15(Ma, K3, A1(11));
142 M11(Pa, K4, A1(12)); M12(Pa, K4, A1(13)); M13(Pa, K4, A1(14));
143 M14(Pa, K4, A1(15)); M15(Pa, K4, A1( 0)); M11(Pa, K4, A1( 1));
144 M12(Pa, K4, A1( 2)); M13(Pa, K4, A1( 3)); M14(Pa, K4, A1( 4));
145 M15(Pa, K4, A1( 5)); M11(Pa, K4, A1( 6)); M12(Pa, K4, A1( 7));
146 M13(Pa, K4, A1( 8)); M14(Pa, K4, A1( 9)); M15(Pa, K4, A1(10));
147 M11(Pa, K4, A1(11)); M12(Pa, K4, A1(12)); M13(Pa, K4, A1(13));
148 M14(Pa, K4, A1(14)); M15(Pa, K4, A1(15));
149
150 H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e;
151}
152
44e8b72c 153static void sha256(SHA *s, UCHR *block) /* SHA-224/256 transform */
05128928 154{
155 W32 a, b, c, d, e, f, g, h, T1;
156 SHA_STO_CLASS W32 W[16];
157 W32 *kp = K256;
158 W32 *wp = W;
159 W32 *H = (W32 *) s->H;
160
161 SHA32_SCHED(W, block);
162
163/*
164 * Use same technique as in sha1()
165 *
166 * To improve performance, unroll the loop and consolidate assignments
167 * by changing the roles of variables "a" through "h" at each step.
168 * Note that the variable "T2" is no longer needed.
169 */
170
171#define M2(a, b, c, d, e, f, g, h, w) \
172 T1 = h + SIGMA1(e) + Ch(e, f, g) + (*kp++) + w; \
173 h = T1 + SIGMA0(a) + Ma(a, b, c); d += T1;
174
175#define W21(s) W[(s+ 0) & 0xf]
176#define W22(s) W[(s+14) & 0xf]
177#define W23(s) W[(s+ 9) & 0xf]
178#define W24(s) W[(s+ 1) & 0xf]
179
180#define A2(s) (W21(s) += sigma1(W22(s)) + W23(s) + sigma0(W24(s)))
181
182#define M21(w) M2(a, b, c, d, e, f, g, h, w)
183#define M22(w) M2(h, a, b, c, d, e, f, g, w)
184#define M23(w) M2(g, h, a, b, c, d, e, f, w)
185#define M24(w) M2(f, g, h, a, b, c, d, e, w)
186#define M25(w) M2(e, f, g, h, a, b, c, d, w)
187#define M26(w) M2(d, e, f, g, h, a, b, c, w)
188#define M27(w) M2(c, d, e, f, g, h, a, b, w)
189#define M28(w) M2(b, c, d, e, f, g, h, a, w)
190
191 a = H[0]; b = H[1]; c = H[2]; d = H[3];
192 e = H[4]; f = H[5]; g = H[6]; h = H[7];
193
194 M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
195 M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++);
196 M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
197 M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp );
198 M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
199 M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
200 M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
201 M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
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
211 H[0] += a; H[1] += b; H[2] += c; H[3] += d;
212 H[4] += e; H[5] += f; H[6] += g; H[7] += h;
213}
214
215#include "sha64bit.c"
216
217#define SETBIT(s, pos) s[(pos) >> 3] |= (0x01 << (7 - (pos) % 8))
218#define CLRBIT(s, pos) s[(pos) >> 3] &= ~(0x01 << (7 - (pos) % 8))
219#define NBYTES(nbits) ((nbits) > 0 ? 1 + (((nbits) - 1) >> 3) : 0)
220#define HEXLEN(nbytes) ((nbytes) << 1)
221#define B64LEN(nbytes) (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \
222 : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1)
223
224/* w32mem: writes 32-bit word to memory in big-endian order */
44e8b72c 225static void w32mem(UCHR *mem, W32 w32)
05128928 226{
227 int i;
228
229 for (i = 0; i < 4; i++)
230 *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff);
231}
232
233/* digcpy: writes current state to digest buffer */
44e8b72c 234static void digcpy(SHA *s)
05128928 235{
236 UINT i;
237 UCHR *d = s->digest;
238 W32 *p32 = (W32 *) s->H;
239 W64 *p64 = (W64 *) s->H;
240
241 if (s->alg <= SHA256)
242 for (i = 0; i < 8; i++, d += 4)
243 w32mem(d, *p32++);
244 else
245 for (i = 0; i < 8; i++, d += 8) {
246 w32mem(d, (W32) ((*p64 >> 16) >> 16));
247 w32mem(d+4, (W32) (*p64++ & SHA32_MAX));
248 }
249}
250
251#define SHA_INIT(algo, transform) \
252 do { \
253 memset(s, 0, sizeof(SHA)); \
254 s->alg = algo; s->sha = sha ## transform; \
255 memcpy(s->H, H0 ## algo, sizeof(H0 ## algo)); \
256 s->blocksize = SHA ## algo ## _BLOCK_BITS; \
257 s->digestlen = SHA ## algo ## _DIGEST_BITS >> 3; \
258 } while (0)
259
260/* sharewind: re-initializes the digest object */
44e8b72c 261void sharewind(SHA *s)
05128928 262{
263 if (s->alg == SHA1) SHA_INIT(1, 1);
264 else if (s->alg == SHA224) SHA_INIT(224, 256);
265 else if (s->alg == SHA256) SHA_INIT(256, 256);
266 else if (s->alg == SHA384) SHA_INIT(384, 512);
267 else if (s->alg == SHA512) SHA_INIT(512, 512);
268}
269
270/* shaopen: creates a new digest object */
44e8b72c 271SHA *shaopen(int alg)
05128928 272{
273 SHA *s;
274
275 if (alg != SHA1 && alg != SHA224 && alg != SHA256 &&
276 alg != SHA384 && alg != SHA512)
277 return(NULL);
278 if (alg >= SHA384 && !sha_384_512)
279 return(NULL);
280 SHA_newz(0, s, 1, SHA);
281 if (s == NULL)
282 return(NULL);
283 s->alg = alg;
284 sharewind(s);
285 return(s);
286}
287
288/* shadirect: updates state directly (w/o going through s->block) */
44e8b72c 289static ULNG shadirect(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 290{
291 ULNG savecnt = bitcnt;
292
293 while (bitcnt >= s->blocksize) {
294 s->sha(s, bitstr);
295 bitstr += (s->blocksize >> 3);
296 bitcnt -= s->blocksize;
297 }
298 if (bitcnt > 0) {
299 memcpy(s->block, bitstr, NBYTES(bitcnt));
300 s->blockcnt = bitcnt;
301 }
302 return(savecnt);
303}
304
305/* shabytes: updates state for byte-aligned input data */
44e8b72c 306static ULNG shabytes(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 307{
308 UINT offset;
309 UINT nbits;
310 ULNG savecnt = bitcnt;
311
312 offset = s->blockcnt >> 3;
313 if (s->blockcnt + bitcnt >= s->blocksize) {
314 nbits = s->blocksize - s->blockcnt;
315 memcpy(s->block+offset, bitstr, nbits>>3);
316 bitcnt -= nbits;
317 bitstr += (nbits >> 3);
318 s->sha(s, s->block), s->blockcnt = 0;
319 shadirect(bitstr, bitcnt, s);
320 }
321 else {
322 memcpy(s->block+offset, bitstr, NBYTES(bitcnt));
323 s->blockcnt += bitcnt;
324 }
325 return(savecnt);
326}
327
328/* shabits: updates state for bit-aligned input data */
44e8b72c 329static ULNG shabits(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 330{
331 UINT i;
332 UINT gap;
333 ULNG nbits;
334 UCHR buf[1<<9];
335 UINT bufsize = sizeof(buf);
336 ULNG bufbits = (ULNG) bufsize << 3;
337 UINT nbytes = NBYTES(bitcnt);
338 ULNG savecnt = bitcnt;
339
340 gap = 8 - s->blockcnt % 8;
341 s->block[s->blockcnt>>3] &= ~0 << gap;
342 s->block[s->blockcnt>>3] |= *bitstr >> (8 - gap);
343 s->blockcnt += bitcnt < gap ? bitcnt : gap;
344 if (bitcnt < gap)
345 return(savecnt);
346 if (s->blockcnt == s->blocksize)
347 s->sha(s, s->block), s->blockcnt = 0;
348 if ((bitcnt -= gap) == 0)
349 return(savecnt);
350 while (nbytes > bufsize) {
351 for (i = 0; i < bufsize; i++)
352 buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
353 nbits = bitcnt < bufbits ? bitcnt : bufbits;
354 shabytes(buf, nbits, s);
355 bitcnt -= nbits, bitstr += bufsize, nbytes -= bufsize;
356 }
357 for (i = 0; i < nbytes - 1; i++)
358 buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
359 buf[nbytes-1] = bitstr[nbytes-1] << gap;
360 shabytes(buf, bitcnt, s);
361 return(savecnt);
362}
363
364/* shawrite: triggers a state update using data in bitstr/bitcnt */
44e8b72c 365ULNG shawrite(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 366{
367 if (bitcnt < 1)
368 return(0);
369 if (SHA_LO32(s->lenll += bitcnt) < bitcnt)
370 if (SHA_LO32(++s->lenlh) == 0)
371 if (SHA_LO32(++s->lenhl) == 0)
372 s->lenhh++;
373 if (s->blockcnt == 0)
374 return(shadirect(bitstr, bitcnt, s));
375 else if (s->blockcnt % 8 == 0)
376 return(shabytes(bitstr, bitcnt, s));
377 else
378 return(shabits(bitstr, bitcnt, s));
379}
380
381/* shafinish: pads remaining block(s) and computes final digest state */
44e8b72c 382void shafinish(SHA *s)
05128928 383{
384 UINT lenpos, lhpos, llpos;
385
386 lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896;
387 lhpos = s->blocksize == SHA1_BLOCK_BITS ? 56 : 120;
388 llpos = s->blocksize == SHA1_BLOCK_BITS ? 60 : 124;
389 SETBIT(s->block, s->blockcnt), s->blockcnt++;
390 while (s->blockcnt > lenpos)
391 if (s->blockcnt < s->blocksize)
392 CLRBIT(s->block, s->blockcnt), s->blockcnt++;
393 else
394 s->sha(s, s->block), s->blockcnt = 0;
395 while (s->blockcnt < lenpos)
396 CLRBIT(s->block, s->blockcnt), s->blockcnt++;
397 if (s->blocksize > SHA1_BLOCK_BITS) {
398 w32mem(s->block + 112, s->lenhh);
399 w32mem(s->block + 116, s->lenhl);
400 }
401 w32mem(s->block + lhpos, s->lenlh);
402 w32mem(s->block + llpos, s->lenll);
403 s->sha(s, s->block);
404}
405
406/* shadigest: returns pointer to current digest (binary) */
44e8b72c 407UCHR *shadigest(SHA *s)
05128928 408{
409 digcpy(s);
410 return(s->digest);
411}
412
413/* shahex: returns pointer to current digest (hexadecimal) */
44e8b72c 414char *shahex(SHA *s)
05128928 415{
416 int i;
417
418 digcpy(s);
419 s->hex[0] = '\0';
420 if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex))
421 return(s->hex);
422 for (i = 0; i < s->digestlen; i++)
423 sprintf(s->hex+i*2, "%02x", s->digest[i]);
424 return(s->hex);
425}
426
427/* map: translation map for Base 64 encoding */
747da336 428static char map[] =
05128928 429 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
430
431/* encbase64: encodes input (0 to 3 bytes) into Base 64 */
44e8b72c 432static void encbase64(UCHR *in, int n, char *out)
05128928 433{
434 UCHR byte[3] = {0, 0, 0};
435
436 out[0] = '\0';
437 if (n < 1 || n > 3)
438 return;
439 memcpy(byte, in, n);
440 out[0] = map[byte[0] >> 2];
441 out[1] = map[((byte[0] & 0x03) << 4) | (byte[1] >> 4)];
442 out[2] = map[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)];
443 out[3] = map[byte[2] & 0x3f];
444 out[n+1] = '\0';
445}
446
447/* shabase64: returns pointer to current digest (Base 64) */
44e8b72c 448char *shabase64(SHA *s)
05128928 449{
450 int n;
451 UCHR *q;
452 char out[5];
453
454 digcpy(s);
455 s->base64[0] = '\0';
456 if (B64LEN(s->digestlen) >= sizeof(s->base64))
457 return(s->base64);
458 for (n = s->digestlen, q = s->digest; n > 3; n -= 3, q += 3) {
459 encbase64(q, 3, out);
460 strcat(s->base64, out);
461 }
462 encbase64(q, n, out);
463 strcat(s->base64, out);
464 return(s->base64);
465}
466
467/* shadsize: returns length of digest in bytes */
44e8b72c 468int shadsize(SHA *s)
05128928 469{
470 return(s->digestlen);
471}
472
473/* shadup: duplicates current digest object */
44e8b72c 474SHA *shadup(SHA *s)
05128928 475{
476 SHA *p;
477
478 SHA_new(0, p, 1, SHA);
479 if (p == NULL)
480 return(NULL);
481 memcpy(p, s, sizeof(SHA));
482 return(p);
483}
484
485/* shadump: dumps digest object to a human-readable ASCII file */
44e8b72c 486int shadump(char *file, SHA *s)
05128928 487{
dcbcf62d 488 int i, j;
05128928 489 SHA_FILE *f;
490 UCHR *p = shadigest(s);
491
492 if (file == NULL || strlen(file) == 0)
493 f = SHA_stdout();
494 else if ((f = SHA_open(file, "w")) == NULL)
495 return(0);
496 SHA_fprintf(f, "alg:%d\nH", s->alg);
497 for (i = 0; i < 8; i++)
57303e6c 498 for (j = 0; j < (s->alg <= 256 ? 4 : 8); j++)
05128928 499 SHA_fprintf(f, "%s%02x", j==0 ? ":" : "", *p++);
500 SHA_fprintf(f, "\nblock");
dcbcf62d 501 for (i = 0; i < (int) (s->blocksize >> 3); i++)
05128928 502 SHA_fprintf(f, ":%02x", s->block[i]);
503 SHA_fprintf(f, "\nblockcnt:%u\n", s->blockcnt);
504 SHA_fprintf(f, "lenhh:%lu\nlenhl:%lu\nlenlh:%lu\nlenll:%lu\n",
505 (ULNG) LO32(s->lenhh), (ULNG) LO32(s->lenhl),
506 (ULNG) LO32(s->lenlh), (ULNG) LO32(s->lenll));
507 if (f != SHA_stdout())
508 SHA_close(f);
509 return(1);
510}
511
512/* fgetstr: reads (and returns pointer to) next line of file */
44e8b72c 513static char *fgetstr(char *line, UINT maxsize, SHA_FILE *f)
05128928 514{
515 char *p;
516
517 if (SHA_feof(f) || maxsize == 0)
518 return(NULL);
519 for (p = line; !SHA_feof(f) && maxsize > 1; maxsize--)
520 if ((*p++ = SHA_getc(f)) == '\n')
521 break;
522 *p = '\0';
523 return(line);
524}
525
526/* empty: returns true if line contains only whitespace characters */
44e8b72c 527static int empty(char *line)
05128928 528{
529 char *p;
530
531 for (p = line; *p; p++)
532 if (!isspace(*p))
533 return(0);
534 return(1);
535}
536
537/* getval: null-terminates field value, and sets pointer to rest of line */
44e8b72c 538static char *getval(char *line, char **pprest)
05128928 539{
540 char *p, *v;
541
542 for (v = line; *v == ':' || isspace(*v); v++)
543 ;
544 for (p = v; *p; p++) {
545 if (*p == ':' || isspace(*p)) {
546 *p++ = '\0';
547 break;
548 }
549 }
550 *pprest = p;
551 return(p == v ? NULL : v);
552}
553
554/* types of values present in dump file */
555#define T_C 1 /* character */
556#define T_I 2 /* normal integer */
557#define T_L 3 /* 32-bit value */
558#define T_Q 4 /* 64-bit value */
559
560/* ldvals: checks next line in dump file against tag, and loads values */
44e8b72c 561static int ldvals(
562 SHA_FILE *f,
0bc2b4f8 563 const char *tag,
44e8b72c 564 int type,
565 void *pval,
566 int reps,
567 int base)
05128928 568{
569 char *p, *pr, line[512];
570 UCHR *pc = (UCHR *) pval; UINT *pi = (UINT *) pval;
571 W32 *pl = (W32 *) pval; W64 *pq = (W64 *) pval;
572
573 while ((p = fgetstr(line, sizeof(line), f)) != NULL)
574 if (line[0] != '#' && !empty(line))
575 break;
576 if (p == NULL || strcmp(getval(line, &pr), tag) != 0)
577 return(0);
578 while (reps-- > 0) {
579 if ((p = getval(pr, &pr)) == NULL)
580 return(1);
581 switch (type) {
582 case T_C: *pc++ = (UCHR) strtoul(p, NULL, base); break;
583 case T_I: *pi++ = (UINT) strtoul(p, NULL, base); break;
584 case T_L: *pl++ = (W32 ) strtoul(p, NULL, base); break;
585 case T_Q: *pq++ = (W64 ) strto64(p ); break;
586 }
587 }
588 return(1);
589}
590
591/* closeall: closes dump file and de-allocates digest object */
44e8b72c 592static SHA *closeall(SHA_FILE *f, SHA *s)
05128928 593{
594 if (f != NULL && f != SHA_stdin())
595 SHA_close(f);
596 if (s != NULL)
597 shaclose(s);
598 return(NULL);
599}
600
601/* shaload: creates digest object corresponding to contents of dump file */
44e8b72c 602SHA *shaload(char *file)
05128928 603{
604 int alg;
605 SHA *s = NULL;
606 SHA_FILE *f;
607
608 if (file == NULL || strlen(file) == 0)
609 f = SHA_stdin();
610 else if ((f = SHA_open(file, "r")) == NULL)
611 return(NULL);
612 if (
613 /* avoid parens by exploiting precedence of (type)&-> */
614 !ldvals(f,"alg",T_I,(VP)&alg,1,10) ||
615 ((s = shaopen(alg)) == NULL) ||
616 !ldvals(f,"H",alg<=SHA256?T_L:T_Q,(VP)s->H,8,16) ||
617 !ldvals(f,"block",T_C,(VP)s->block,s->blocksize/8,16) ||
618 !ldvals(f,"blockcnt",T_I,(VP)&s->blockcnt,1,10) ||
619 (alg <= SHA256 && s->blockcnt >= SHA1_BLOCK_BITS) ||
620 (alg >= SHA384 && s->blockcnt >= SHA384_BLOCK_BITS) ||
621 !ldvals(f,"lenhh",T_L,(VP)&s->lenhh,1,10) ||
622 !ldvals(f,"lenhl",T_L,(VP)&s->lenhl,1,10) ||
623 !ldvals(f,"lenlh",T_L,(VP)&s->lenlh,1,10) ||
624 !ldvals(f,"lenll",T_L,(VP)&s->lenll,1,10)
625 )
626 return(closeall(f, s));
627 if (f != SHA_stdin())
628 SHA_close(f);
629 return(s);
630}
631
632/* shaclose: de-allocates digest object */
44e8b72c 633int shaclose(SHA *s)
05128928 634{
635 if (s != NULL) {
636 memset(s, 0, sizeof(SHA));
637 SHA_free(s);
638 }
639 return(0);
640}