File Coverage

cpan/Digest-SHA/src/sha.c
Criterion Covered Total %
statement 119 310 38.4
branch n/a
condition n/a
subroutine n/a
total 119 310 38.4


line stmt bran cond sub time code
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-2013 Mark Shelor, All Rights Reserved
7           *
8           * Version: 5.85
9           * Wed Jun 26 04:05:26 MST 2013
10           *
11           */
12            
13           #include
14           #include
15           #include
16           #include
17           #include
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 5192         static void sha1(SHA *s, UCHR *block) /* SHA-1 transform */
87           {
88           W32 a, b, c, d, e;
89           W32 W[16];
90           W32 *wp = W;
91           W32 *H = (W32 *) s->H;
92            
93 5192         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 5192         a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4];
121            
122 5192         M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); M13(Ch, K1, *wp++);
123 5192         M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); M11(Ch, K1, *wp++);
124 5192         M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); M14(Ch, K1, *wp++);
125 5192         M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); M12(Ch, K1, *wp++);
126 5192         M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); M15(Ch, K1, *wp++);
127 5192         M11(Ch, K1, *wp ); M12(Ch, K1, A1( 0)); M13(Ch, K1, A1( 1));
128 5192         M14(Ch, K1, A1( 2)); M15(Ch, K1, A1( 3)); M11(Pa, K2, A1( 4));
129 5192         M12(Pa, K2, A1( 5)); M13(Pa, K2, A1( 6)); M14(Pa, K2, A1( 7));
130 5192         M15(Pa, K2, A1( 8)); M11(Pa, K2, A1( 9)); M12(Pa, K2, A1(10));
131 5192         M13(Pa, K2, A1(11)); M14(Pa, K2, A1(12)); M15(Pa, K2, A1(13));
132 5192         M11(Pa, K2, A1(14)); M12(Pa, K2, A1(15)); M13(Pa, K2, A1( 0));
133 5192         M14(Pa, K2, A1( 1)); M15(Pa, K2, A1( 2)); M11(Pa, K2, A1( 3));
134 5192         M12(Pa, K2, A1( 4)); M13(Pa, K2, A1( 5)); M14(Pa, K2, A1( 6));
135 5192         M15(Pa, K2, A1( 7)); M11(Ma, K3, A1( 8)); M12(Ma, K3, A1( 9));
136 5192         M13(Ma, K3, A1(10)); M14(Ma, K3, A1(11)); M15(Ma, K3, A1(12));
137 5192         M11(Ma, K3, A1(13)); M12(Ma, K3, A1(14)); M13(Ma, K3, A1(15));
138 5192         M14(Ma, K3, A1( 0)); M15(Ma, K3, A1( 1)); M11(Ma, K3, A1( 2));
139 5192         M12(Ma, K3, A1( 3)); M13(Ma, K3, A1( 4)); M14(Ma, K3, A1( 5));
140 5192         M15(Ma, K3, A1( 6)); M11(Ma, K3, A1( 7)); M12(Ma, K3, A1( 8));
141 5192         M13(Ma, K3, A1( 9)); M14(Ma, K3, A1(10)); M15(Ma, K3, A1(11));
142 5192         M11(Pa, K4, A1(12)); M12(Pa, K4, A1(13)); M13(Pa, K4, A1(14));
143 5192         M14(Pa, K4, A1(15)); M15(Pa, K4, A1( 0)); M11(Pa, K4, A1( 1));
144 5192         M12(Pa, K4, A1( 2)); M13(Pa, K4, A1( 3)); M14(Pa, K4, A1( 4));
145 5192         M15(Pa, K4, A1( 5)); M11(Pa, K4, A1( 6)); M12(Pa, K4, A1( 7));
146 5192         M13(Pa, K4, A1( 8)); M14(Pa, K4, A1( 9)); M15(Pa, K4, A1(10));
147 5192         M11(Pa, K4, A1(11)); M12(Pa, K4, A1(12)); M13(Pa, K4, A1(13));
148 5192         M14(Pa, K4, A1(14)); M15(Pa, K4, A1(15));
149            
150 5192         H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e;
151 5192         }
152            
153 36108         static void sha256(SHA *s, UCHR *block) /* SHA-224/256 transform */
154           {
155           W32 a, b, c, d, e, f, g, h, T1;
156           W32 W[16];
157           W32 *kp = K256;
158           W32 *wp = W;
159           W32 *H = (W32 *) s->H;
160            
161 36108         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 36108         a = H[0]; b = H[1]; c = H[2]; d = H[3];
192 36108         e = H[4]; f = H[5]; g = H[6]; h = H[7];
193            
194 36108         M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
195 36108         M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++);
196 36108         M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++);
197 36108         M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp );
198 36108         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
199 36108         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
200 36108         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
201 36108         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
202 36108         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
203 36108         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
204 36108         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
205 36108         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
206 36108         M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3));
207 36108         M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7));
208 36108         M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11));
209 36108         M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15));
210            
211 36108         H[0] += a; H[1] += b; H[2] += c; H[3] += d;
212 36108         H[4] += e; H[5] += f; H[6] += g; H[7] += h;
213 36108         }
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) + 7) >> 3)
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 */
225           static void w32mem(UCHR *mem, W32 w32)
226           {
227           int i;
228            
229 3600         for (i = 0; i < 4; i++)
230 3600         *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff);
231           }
232            
233           /* digcpy: writes current state to digest buffer */
234 90         static void digcpy(SHA *s)
235           {
236           UINT i;
237 90         UCHR *d = s->digest;
238 90         W32 *p32 = (W32 *) s->H;
239 90         W64 *p64 = (W64 *) s->H;
240            
241 90         if (s->alg <= SHA256)
242 720         for (i = 0; i < 8; i++, d += 4)
243 720         w32mem(d, *p32++);
244           else
245 0         for (i = 0; i < 8; i++, d += 8) {
246 0         w32mem(d, (W32) ((*p64 >> 16) >> 16));
247 0         w32mem(d+4, (W32) (*p64++ & SHA32_MAX));
248           }
249 90         }
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 */
261 160         static void sharewind(SHA *s)
262           {
263 392         if (s->alg == SHA1) SHA_INIT(1, 1);
264 44         else if (s->alg == SHA224) SHA_INIT(224, 256);
265 132         else if (s->alg == SHA256) SHA_INIT(256, 256);
266 0         else if (s->alg == SHA384) SHA_INIT(384, 512);
267 0         else if (s->alg == SHA512) SHA_INIT(512, 512);
268 0         else if (s->alg == SHA512224) SHA_INIT(512224, 512);
269 0         else if (s->alg == SHA512256) SHA_INIT(512256, 512);
270 160         }
271            
272           /* shaopen: creates a new digest object */
273 90         static SHA *shaopen(int alg)
274           {
275           SHA *s = NULL;
276            
277 122         if (alg != SHA1 && alg != SHA224 && alg != SHA256 &&
278 32         alg != SHA384 && alg != SHA512 &&
279 0         alg != SHA512224 && alg != SHA512256)
280           return(NULL);
281           if (alg >= SHA384 && !sha_384_512)
282           return(NULL);
283 90         SHA_newz(0, s, 1, SHA);
284 90         if (s == NULL)
285           return(NULL);
286 90         s->alg = alg;
287 90         sharewind(s);
288 90         return(s);
289           }
290            
291           /* shaclose: de-allocates digest object */
292 90         static int shaclose(SHA *s)
293           {
294 90         if (s != NULL) {
295           memset(s, 0, sizeof(SHA));
296 90         SHA_free(s);
297           }
298 90         return(0);
299           }
300            
301           /* shadirect: updates state directly (w/o going through s->block) */
302 570         static ULNG shadirect(UCHR *bitstr, ULNG bitcnt, SHA *s)
303           {
304           ULNG savecnt = bitcnt;
305            
306 42338         while (bitcnt >= s->blocksize) {
307 41198         s->sha(s, bitstr);
308 41198         bitstr += (s->blocksize >> 3);
309 41198         bitcnt -= s->blocksize;
310           }
311 570         if (bitcnt > 0) {
312 88         memcpy(s->block, bitstr, NBYTES(bitcnt));
313 88         s->blockcnt = bitcnt;
314           }
315 570         return(savecnt);
316           }
317            
318           /* shabytes: updates state for byte-aligned input data */
319 0         static ULNG shabytes(UCHR *bitstr, ULNG bitcnt, SHA *s)
320           {
321           UINT offset;
322           UINT nbits;
323           ULNG savecnt = bitcnt;
324            
325 0         offset = s->blockcnt >> 3;
326 0         if (s->blockcnt + bitcnt >= s->blocksize) {
327 0         nbits = s->blocksize - s->blockcnt;
328 0         memcpy(s->block+offset, bitstr, nbits>>3);
329 0         bitcnt -= nbits;
330 0         bitstr += (nbits >> 3);
331 0         s->sha(s, s->block), s->blockcnt = 0;
332 0         shadirect(bitstr, bitcnt, s);
333           }
334           else {
335 0         memcpy(s->block+offset, bitstr, NBYTES(bitcnt));
336 0         s->blockcnt += bitcnt;
337           }
338 0         return(savecnt);
339           }
340            
341           /* shabits: updates state for bit-aligned input data */
342 0         static ULNG shabits(UCHR *bitstr, ULNG bitcnt, SHA *s)
343           {
344           UINT i;
345           UINT gap;
346           ULNG nbits;
347           UCHR buf[1<<9];
348           UINT bufsize = sizeof(buf);
349           ULNG bufbits = (ULNG) bufsize << 3;
350 0         UINT nbytes = NBYTES(bitcnt);
351           ULNG savecnt = bitcnt;
352            
353 0         gap = 8 - s->blockcnt % 8;
354 0         s->block[s->blockcnt>>3] &= ~0 << gap;
355 0         s->block[s->blockcnt>>3] |= *bitstr >> (8 - gap);
356 0         s->blockcnt += bitcnt < gap ? bitcnt : gap;
357 0         if (bitcnt < gap)
358           return(savecnt);
359 0         if (s->blockcnt == s->blocksize)
360 0         s->sha(s, s->block), s->blockcnt = 0;
361 0         if ((bitcnt -= gap) == 0)
362           return(savecnt);
363 0         while (nbytes > bufsize) {
364 0         for (i = 0; i < bufsize; i++)
365 0         buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
366 0         nbits = bitcnt < bufbits ? bitcnt : bufbits;
367 0         shabytes(buf, nbits, s);
368 0         bitcnt -= nbits, bitstr += bufsize, nbytes -= bufsize;
369           }
370 0         for (i = 0; i < nbytes - 1; i++)
371 0         buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap);
372 0         buf[nbytes-1] = bitstr[nbytes-1] << gap;
373 0         shabytes(buf, bitcnt, s);
374 0         return(savecnt);
375           }
376            
377           /* shawrite: triggers a state update using data in bitstr/bitcnt */
378 570         static ULNG shawrite(UCHR *bitstr, ULNG bitcnt, SHA *s)
379           {
380 570         if (bitcnt < 1)
381           return(0);
382 570         if (SHA_LO32(s->lenll += bitcnt) < bitcnt)
383 0         if (SHA_LO32(++s->lenlh) == 0)
384 0         if (SHA_LO32(++s->lenhl) == 0)
385 0         s->lenhh++;
386 570         if (s->blockcnt == 0)
387 570         return(shadirect(bitstr, bitcnt, s));
388 0         else if (s->blockcnt % 8 == 0)
389 0         return(shabytes(bitstr, bitcnt, s));
390           else
391 0         return(shabits(bitstr, bitcnt, s));
392           }
393            
394           /* shafinish: pads remaining block(s) and computes final digest state */
395 90         static void shafinish(SHA *s)
396           {
397           UINT lenpos, lhpos, llpos;
398            
399 90         lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896;
400 90         lhpos = s->blocksize == SHA1_BLOCK_BITS ? 56 : 120;
401 90         llpos = s->blocksize == SHA1_BLOCK_BITS ? 60 : 124;
402 90         SETBIT(s->block, s->blockcnt), s->blockcnt++;
403 628         while (s->blockcnt > lenpos)
404 448         if (s->blockcnt < s->blocksize)
405 436         CLRBIT(s->block, s->blockcnt), s->blockcnt++;
406           else
407 12         s->sha(s, s->block), s->blockcnt = 0;
408 23116         while (s->blockcnt < lenpos)
409 23026         CLRBIT(s->block, s->blockcnt), s->blockcnt++;
410 90         if (s->blocksize > SHA1_BLOCK_BITS) {
411 0         w32mem(s->block + 112, s->lenhh);
412 0         w32mem(s->block + 116, s->lenhl);
413           }
414 90         w32mem(s->block + lhpos, s->lenlh);
415 90         w32mem(s->block + llpos, s->lenll);
416 90         s->sha(s, s->block);
417 90         }
418            
419           /* shadigest: returns pointer to current digest (binary) */
420           static UCHR *shadigest(SHA *s)
421           {
422 0         digcpy(s);
423           return(s->digest);
424           }
425            
426           /* shahex: returns pointer to current digest (hexadecimal) */
427 90         static char *shahex(SHA *s)
428           {
429           int i;
430            
431 90         digcpy(s);
432 90         s->hex[0] = '\0';
433 90         if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex))
434 0         return(s->hex);
435 2184         for (i = 0; i < s->digestlen; i++)
436 2184         sprintf(s->hex+i*2, "%02x", s->digest[i]);
437 90         return(s->hex);
438           }
439            
440           /* map: translation map for Base 64 encoding */
441           static char map[] =
442           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
443            
444           /* encbase64: encodes input (0 to 3 bytes) into Base 64 */
445 0         static void encbase64(UCHR *in, int n, char *out)
446           {
447 0         UCHR byte[3] = {0, 0, 0};
448            
449 0         out[0] = '\0';
450 0         if (n < 1 || n > 3)
451 0         return;
452 0         memcpy(byte, in, n);
453 0         out[0] = map[byte[0] >> 2];
454 0         out[1] = map[((byte[0] & 0x03) << 4) | (byte[1] >> 4)];
455 0         out[2] = map[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)];
456 0         out[3] = map[byte[2] & 0x3f];
457 0         out[n+1] = '\0';
458           }
459            
460           /* shabase64: returns pointer to current digest (Base 64) */
461 0         static char *shabase64(SHA *s)
462           {
463           int n;
464           UCHR *q;
465           char out[5];
466            
467 0         digcpy(s);
468 0         s->base64[0] = '\0';
469 0         if (B64LEN((size_t) s->digestlen) >= sizeof(s->base64))
470 0         return(s->base64);
471 0         for (n = s->digestlen, q = s->digest; n > 3; n -= 3, q += 3) {
472 0         encbase64(q, 3, out);
473 0         strcat(s->base64, out);
474           }
475 0         encbase64(q, n, out);
476 0         strcat(s->base64, out);
477 0         return(s->base64);
478           }
479            
480           /* shadsize: returns length of digest in bytes */
481 0         static int shadsize(SHA *s)
482           {
483 0         return(s->digestlen);
484           }
485            
486           /* shaalg: returns which SHA algorithm is being used */
487 0         static int shaalg(SHA *s)
488           {
489 0         return(s->alg);
490           }
491            
492           /* shadup: duplicates current digest object */
493           static SHA *shadup(SHA *s)
494           {
495           SHA *p;
496            
497 0         SHA_new(0, p, 1, SHA);
498 0         if (p == NULL)
499           return(NULL);
500 0         memcpy(p, s, sizeof(SHA));
501           return(p);
502           }
503            
504           /* shadump: dumps digest object to a human-readable ASCII file */
505 0         static int shadump(char *file, SHA *s)
506           {
507           int i, j;
508           SHA_FILE *f;
509 0         UCHR *p = shadigest(s);
510            
511 0         if (file == NULL || strlen(file) == 0)
512 0         f = SHA_stdout();
513 0         else if ((f = SHA_open(file, "w")) == NULL)
514           return(0);
515 0         SHA_fprintf(f, "alg:%d\nH", s->alg);
516 0         for (i = 0; i < 8; i++)
517 0         for (j = 0; j < (s->alg <= 256 ? 4 : 8); j++)
518 0         SHA_fprintf(f, "%s%02x", j==0 ? ":" : "", *p++);
519 0         SHA_fprintf(f, "\nblock");
520 0         for (i = 0; i < (int) (s->blocksize >> 3); i++)
521 0         SHA_fprintf(f, ":%02x", s->block[i]);
522 0         SHA_fprintf(f, "\nblockcnt:%u\n", s->blockcnt);
523 0         SHA_fprintf(f, "lenhh:%lu\nlenhl:%lu\nlenlh:%lu\nlenll:%lu\n",
524 0         (ULNG) LO32(s->lenhh), (ULNG) LO32(s->lenhl),
525 0         (ULNG) LO32(s->lenlh), (ULNG) LO32(s->lenll));
526 0         if (f != SHA_stdout())
527 0         SHA_close(f);
528           return(1);
529           }
530            
531           /* fgetstr: reads (and returns pointer to) next line of file */
532           static char *fgetstr(char *line, UINT maxsize, SHA_FILE *f)
533           {
534           char *p;
535            
536 0         if (SHA_feof(f) || maxsize == 0)
537           return(NULL);
538 0         for (p = line; !SHA_feof(f) && maxsize > 1; maxsize--)
539 0         if ((*p++ = SHA_getc(f)) == '\n')
540           break;
541 0         *p = '\0';
542           return(line);
543           }
544            
545           /* empty: returns true if line contains only whitespace characters */
546           static int empty(char *line)
547           {
548           char *p;
549            
550 0         for (p = line; *p; p++)
551 0         if (!isspace(*p))
552           return(0);
553           return(1);
554           }
555            
556           /* getval: null-terminates field value, and sets pointer to rest of line */
557 0         static char *getval(char *line, char **pprest)
558           {
559           char *p, *v;
560            
561 0         for (v = line; *v == ':' || isspace(*v); v++)
562           ;
563 0         for (p = v; *p; p++) {
564 0         if (*p == ':' || isspace(*p)) {
565 0         *p++ = '\0';
566 0         break;
567           }
568           }
569 0         *pprest = p;
570 0         return(p == v ? NULL : v);
571           }
572            
573           /* types of values present in dump file */
574           #define T_C 1 /* character */
575           #define T_I 2 /* normal integer */
576           #define T_L 3 /* 32-bit value */
577           #define T_Q 4 /* 64-bit value */
578            
579           /* ldvals: checks next line in dump file against tag, and loads values */
580 0         static int ldvals(
581           SHA_FILE *f,
582           const char *tag,
583           int type,
584           void *pval,
585           int reps,
586           int base)
587           {
588           char *p, *pr, line[512];
589           UCHR *pc = (UCHR *) pval; UINT *pi = (UINT *) pval;
590           W32 *pl = (W32 *) pval; W64 *pq = (W64 *) pval;
591            
592 0         while ((p = fgetstr(line, sizeof(line), f)) != NULL)
593 0         if (line[0] != '#' && !empty(line))
594           break;
595 0         if (p == NULL || strcmp(getval(line, &pr), tag) != 0)
596           return(0);
597 0         while (reps-- > 0) {
598 0         if ((p = getval(pr, &pr)) == NULL)
599           return(1);
600 0         switch (type) {
601 0         case T_C: *pc++ = (UCHR) strtoul(p, NULL, base); break;
602 0         case T_I: *pi++ = (UINT) strtoul(p, NULL, base); break;
603 0         case T_L: *pl++ = (W32 ) strtoul(p, NULL, base); break;
604 0         case T_Q: *pq++ = (W64 ) strto64(p ); break;
605           }
606           }
607           return(1);
608           }
609            
610           /* closeall: closes dump file and de-allocates digest object */
611           static SHA *closeall(SHA_FILE *f, SHA *s)
612           {
613 0         if (f != NULL && f != SHA_stdin())
614 0         SHA_close(f);
615 0         if (s != NULL)
616 0         shaclose(s);
617           return(NULL);
618           }
619            
620           /* shaload: creates digest object corresponding to contents of dump file */
621 0         static SHA *shaload(char *file)
622           {
623           int alg;
624           SHA *s = NULL;
625           SHA_FILE *f;
626            
627 0         if (file == NULL || strlen(file) == 0)
628 0         f = SHA_stdin();
629 0         else if ((f = SHA_open(file, "r")) == NULL)
630           return(NULL);
631 0         if (
632           /* avoid parens by exploiting precedence of (type)&-> */
633 0         !ldvals(f,"alg",T_I,(VP)&alg,1,10) ||
634 0         ((s = shaopen(alg)) == NULL) ||
635 0         !ldvals(f,"H",alg<=SHA256?T_L:T_Q,(VP)s->H,8,16) ||
636 0         !ldvals(f,"block",T_C,(VP)s->block,s->blocksize/8,16) ||
637 0         !ldvals(f,"blockcnt",T_I,(VP)&s->blockcnt,1,10) ||
638 0         (alg <= SHA256 && s->blockcnt >= SHA1_BLOCK_BITS) ||
639 0         (alg >= SHA384 && s->blockcnt >= SHA384_BLOCK_BITS) ||
640 0         !ldvals(f,"lenhh",T_L,(VP)&s->lenhh,1,10) ||
641 0         !ldvals(f,"lenhl",T_L,(VP)&s->lenhl,1,10) ||
642 0         !ldvals(f,"lenlh",T_L,(VP)&s->lenlh,1,10) ||
643 0         !ldvals(f,"lenll",T_L,(VP)&s->lenll,1,10)
644           )
645           return(closeall(f, s));
646 0         if (f != SHA_stdin())
647 0         SHA_close(f);
648           return(s);
649           }
650            
651           /* hmacopen: creates a new HMAC-SHA digest object */
652 0         static HMAC *hmacopen(int alg, UCHR *key, UINT keylen)
653           {
654           UINT i;
655           HMAC *h;
656            
657 0         SHA_newz(0, h, 1, HMAC);
658 0         if (h == NULL)
659           return(NULL);
660 0         if ((h->isha = shaopen(alg)) == NULL) {
661 0         SHA_free(h);
662 0         return(NULL);
663           }
664 0         if ((h->osha = shaopen(alg)) == NULL) {
665 0         shaclose(h->isha);
666 0         SHA_free(h);
667 0         return(NULL);
668           }
669 0         if (keylen <= h->osha->blocksize / 8)
670 0         memcpy(h->key, key, keylen);
671           else {
672 0         if ((h->ksha = shaopen(alg)) == NULL) {
673 0         shaclose(h->isha);
674 0         shaclose(h->osha);
675 0         SHA_free(h);
676 0         return(NULL);
677           }
678 0         shawrite(key, keylen * 8, h->ksha);
679 0         shafinish(h->ksha);
680 0         memcpy(h->key, shadigest(h->ksha), h->ksha->digestlen);
681 0         shaclose(h->ksha);
682           }
683 0         for (i = 0; i < h->osha->blocksize / 8; i++)
684 0         h->key[i] ^= 0x5c;
685 0         shawrite(h->key, h->osha->blocksize, h->osha);
686 0         for (i = 0; i < h->isha->blocksize / 8; i++)
687 0         h->key[i] ^= (0x5c ^ 0x36);
688 0         shawrite(h->key, h->isha->blocksize, h->isha);
689 0         memset(h->key, 0, sizeof(h->key));
690 0         return(h);
691           }
692            
693           /* hmacwrite: triggers a state update using data in bitstr/bitcnt */
694 0         static ULNG hmacwrite(UCHR *bitstr, ULNG bitcnt, HMAC *h)
695           {
696 0         return(shawrite(bitstr, bitcnt, h->isha));
697           }
698            
699           /* hmacfinish: computes final digest state */
700 0         static void hmacfinish(HMAC *h)
701           {
702 0         shafinish(h->isha);
703 0         shawrite(shadigest(h->isha), h->isha->digestlen * 8, h->osha);
704 0         shaclose(h->isha);
705 0         shafinish(h->osha);
706 0         }
707            
708           /* hmacdigest: returns pointer to digest (binary) */
709 0         static UCHR *hmacdigest(HMAC *h)
710           {
711 0         return(shadigest(h->osha));
712           }
713            
714           /* hmachex: returns pointer to digest (hexadecimal) */
715 0         static char *hmachex(HMAC *h)
716           {
717 0         return(shahex(h->osha));
718           }
719            
720           /* hmacbase64: returns pointer to digest (Base 64) */
721 0         static char *hmacbase64(HMAC *h)
722           {
723 0         return(shabase64(h->osha));
724           }
725            
726           /* hmacclose: de-allocates digest object */
727           static int hmacclose(HMAC *h)
728           {
729 0         if (h != NULL) {
730 0         shaclose(h->osha);
731           memset(h, 0, sizeof(HMAC));
732 0         SHA_free(h);
733           }
734           return(0);
735           }