This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Digest-SHA to CPAN version 5.97
[perl5.git] / cpan / Digest-SHA / src / sha.c
CommitLineData
05128928
NC
1/*
2 * sha.c: routines to compute SHA-1/224/256/384/512 digests
3 *
626ec6d7 4 * Ref: NIST FIPS PUB 180-4 Secure Hash Standard
05128928 5 *
f4f12f2f 6 * Copyright (C) 2003-2017 Mark Shelor, All Rights Reserved
05128928 7 *
f4f12f2f
CBW
8 * Version: 5.97
9 * Wed Sep 6 02:23:02 MST 2017
05128928
NC
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
24278fc4 48static const W32 K256[64] = /* SHA-224/256 constants */
05128928
NC
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
24278fc4 68static const W32 H01[8] = /* SHA-1 initial hash value */
05128928 69{
03c6205f
CBW
70 C32(0x67452301), C32(0xefcdab89), C32(0x98badcfe), C32(0x10325476),
71 C32(0xc3d2e1f0), C32(0x00000000), C32(0x00000000), C32(0x00000000)
05128928
NC
72};
73
24278fc4 74static const W32 H0224[8] = /* SHA-224 initial hash value */
05128928
NC
75{
76 C32(0xc1059ed8), C32(0x367cd507), C32(0x3070dd17), C32(0xf70e5939),
77 C32(0xffc00b31), C32(0x68581511), C32(0x64f98fa7), C32(0xbefa4fa4)
78};
79
24278fc4 80static const W32 H0256[8] = /* SHA-256 initial hash value */
05128928
NC
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
NC
87{
88 W32 a, b, c, d, e;
7720cfb2 89 W32 W[16];
05128928 90 W32 *wp = W;
03c6205f 91 W32 *H = s->H32;
05128928
NC
92
93 SHA32_SCHED(W, block);
94
95/*
626ec6d7 96 * Use SHA-1 alternate method from FIPS PUB 180-4 (ref. 6.1.3)
05128928
NC
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
NC
154{
155 W32 a, b, c, d, e, f, g, h, T1;
7720cfb2 156 W32 W[16];
24278fc4 157 const W32 *kp = K256;
05128928 158 W32 *wp = W;
03c6205f 159 W32 *H = s->H32;
05128928
NC
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
24278fc4 217#define BITSET(s, pos) s[(pos) >> 3] & (UCHR) (0x01 << (7 - (pos) % 8))
03c6205f
CBW
218#define SETBIT(s, pos) s[(pos) >> 3] |= (UCHR) (0x01 << (7 - (pos) % 8))
219#define CLRBIT(s, pos) s[(pos) >> 3] &= (UCHR) ~(0x01 << (7 - (pos) % 8))
2ff8a1ae 220#define NBYTES(nbits) (((nbits) + 7) >> 3)
05128928
NC
221#define HEXLEN(nbytes) ((nbytes) << 1)
222#define B64LEN(nbytes) (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \
223 : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1)
224
225/* w32mem: writes 32-bit word to memory in big-endian order */
7123ec76 226static UCHR *w32mem(UCHR *mem, W32 w32)
05128928
NC
227{
228 int i;
229
230 for (i = 0; i < 4; i++)
231 *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff);
7123ec76
SH
232 return(mem);
233}
234
235/* memw32: returns 32-bit word from memory written in big-endian order */
236static W32 memw32(UCHR *mem)
237{
238 int i;
239 W32 w = 0;
240
241 for (i = 0; i < 4; i++)
242 w = (w << 8) + *mem++;
243 return(w);
05128928
NC
244}
245
246/* digcpy: writes current state to digest buffer */
7123ec76 247static UCHR *digcpy(SHA *s)
05128928 248{
7123ec76 249 int i;
05128928 250 UCHR *d = s->digest;
03c6205f
CBW
251 W32 *p32 = s->H32;
252 W64 *p64 = s->H64;
05128928
NC
253
254 if (s->alg <= SHA256)
255 for (i = 0; i < 8; i++, d += 4)
256 w32mem(d, *p32++);
257 else
258 for (i = 0; i < 8; i++, d += 8) {
259 w32mem(d, (W32) ((*p64 >> 16) >> 16));
260 w32mem(d+4, (W32) (*p64++ & SHA32_MAX));
261 }
7123ec76
SH
262 return(s->digest);
263}
264
265/* statecpy: writes buffer to current state (opposite of digcpy) */
266static UCHR *statecpy(SHA *s, UCHR *buf)
267{
268 int i;
03c6205f
CBW
269 W32 *p32 = s->H32;
270 W64 *p64 = s->H64;
7123ec76
SH
271
272 if (s->alg <= SHA256)
273 for (i = 0; i < 8; i++, buf += 4)
274 *p32++ = memw32(buf);
275 else
276 for (i = 0; i < 8; i++, buf += 8)
207902b1 277 *p64++ = (((W64)memw32(buf) << 16) << 16) +
7123ec76
SH
278 memw32(buf+4);
279 return(buf);
05128928
NC
280}
281
207902b1 282#define SHA_INIT(s, algo, transform) \
05128928 283 do { \
207902b1 284 Zero(s, 1, SHA); \
05128928 285 s->alg = algo; s->sha = sha ## transform; \
03c6205f
CBW
286 if (s->alg <= SHA256) \
287 Copy(H0 ## algo, s->H32, 8, SHA32); \
288 else \
289 Copy(H0 ## algo, s->H64, 8, SHA64); \
05128928
NC
290 s->blocksize = SHA ## algo ## _BLOCK_BITS; \
291 s->digestlen = SHA ## algo ## _DIGEST_BITS >> 3; \
292 } while (0)
293
207902b1 294/* sharewind: resets digest object */
a5b310e3 295static void sharewind(SHA *s)
05128928 296{
207902b1
CBW
297 if (s->alg == SHA1) SHA_INIT(s, 1, 1);
298 else if (s->alg == SHA224) SHA_INIT(s, 224, 256);
299 else if (s->alg == SHA256) SHA_INIT(s, 256, 256);
300 else if (s->alg == SHA384) SHA_INIT(s, 384, 512);
301 else if (s->alg == SHA512) SHA_INIT(s, 512, 512);
302 else if (s->alg == SHA512224) SHA_INIT(s, 512224, 512);
303 else if (s->alg == SHA512256) SHA_INIT(s, 512256, 512);
05128928
NC
304}
305
207902b1
CBW
306/* shainit: initializes digest object */
307static int shainit(SHA *s, int alg)
05128928 308{
207902b1
CBW
309 if (alg >= SHA384 && !sha_384_512)
310 return 0;
05128928 311 if (alg != SHA1 && alg != SHA224 && alg != SHA256 &&
65484cb9
CBW
312 alg != SHA384 && alg != SHA512 &&
313 alg != SHA512224 && alg != SHA512256)
207902b1 314 return 0;
05128928
NC
315 s->alg = alg;
316 sharewind(s);
207902b1 317 return 1;
a5b310e3
CBW
318}
319
05128928 320/* shadirect: updates state directly (w/o going through s->block) */
44e8b72c 321static ULNG shadirect(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928
NC
322{
323 ULNG savecnt = bitcnt;
324
325 while (bitcnt >= s->blocksize) {
326 s->sha(s, bitstr);
327 bitstr += (s->blocksize >> 3);
328 bitcnt -= s->blocksize;
329 }
330 if (bitcnt > 0) {
207902b1 331 Copy(bitstr, s->block, NBYTES(bitcnt), char);
05128928
NC
332 s->blockcnt = bitcnt;
333 }
334 return(savecnt);
335}
336
207902b1 337/* shabytes: updates state for byte-aligned data in s->block */
44e8b72c 338static ULNG shabytes(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928
NC
339{
340 UINT offset;
341 UINT nbits;
342 ULNG savecnt = bitcnt;
343
344 offset = s->blockcnt >> 3;
345 if (s->blockcnt + bitcnt >= s->blocksize) {
346 nbits = s->blocksize - s->blockcnt;
207902b1 347 Copy(bitstr, s->block+offset, nbits>>3, char);
05128928
NC
348 bitcnt -= nbits;
349 bitstr += (nbits >> 3);
350 s->sha(s, s->block), s->blockcnt = 0;
351 shadirect(bitstr, bitcnt, s);
352 }
353 else {
207902b1 354 Copy(bitstr, s->block+offset, NBYTES(bitcnt), char);
05128928
NC
355 s->blockcnt += bitcnt;
356 }
357 return(savecnt);
358}
359
207902b1 360/* shabits: updates state for bit-aligned data in s->block */
44e8b72c 361static ULNG shabits(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 362{
24278fc4 363 ULNG i;
05128928 364
24278fc4
CBW
365 for (i = 0UL; i < bitcnt; i++) {
366 if (BITSET(bitstr, i))
e05a9d74 367 SETBIT(s->block, s->blockcnt);
24278fc4 368 else
e05a9d74
SH
369 CLRBIT(s->block, s->blockcnt);
370 if (++s->blockcnt == s->blocksize)
24278fc4 371 s->sha(s, s->block), s->blockcnt = 0;
05128928 372 }
24278fc4 373 return(bitcnt);
05128928
NC
374}
375
376/* shawrite: triggers a state update using data in bitstr/bitcnt */
a5b310e3 377static ULNG shawrite(UCHR *bitstr, ULNG bitcnt, SHA *s)
05128928 378{
24278fc4 379 if (!bitcnt)
05128928
NC
380 return(0);
381 if (SHA_LO32(s->lenll += bitcnt) < bitcnt)
382 if (SHA_LO32(++s->lenlh) == 0)
383 if (SHA_LO32(++s->lenhl) == 0)
384 s->lenhh++;
385 if (s->blockcnt == 0)
386 return(shadirect(bitstr, bitcnt, s));
387 else if (s->blockcnt % 8 == 0)
388 return(shabytes(bitstr, bitcnt, s));
389 else
390 return(shabits(bitstr, bitcnt, s));
391}
392
393/* shafinish: pads remaining block(s) and computes final digest state */
a5b310e3 394static void shafinish(SHA *s)
05128928
NC
395{
396 UINT lenpos, lhpos, llpos;
397
398 lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896;
399 lhpos = s->blocksize == SHA1_BLOCK_BITS ? 56 : 120;
400 llpos = s->blocksize == SHA1_BLOCK_BITS ? 60 : 124;
401 SETBIT(s->block, s->blockcnt), s->blockcnt++;
402 while (s->blockcnt > lenpos)
403 if (s->blockcnt < s->blocksize)
404 CLRBIT(s->block, s->blockcnt), s->blockcnt++;
405 else
406 s->sha(s, s->block), s->blockcnt = 0;
407 while (s->blockcnt < lenpos)
408 CLRBIT(s->block, s->blockcnt), s->blockcnt++;
409 if (s->blocksize > SHA1_BLOCK_BITS) {
410 w32mem(s->block + 112, s->lenhh);
411 w32mem(s->block + 116, s->lenhl);
412 }
413 w32mem(s->block + lhpos, s->lenlh);
414 w32mem(s->block + llpos, s->lenll);
415 s->sha(s, s->block);
416}
417
207902b1
CBW
418#define shadigest(state) digcpy(state)
419
e80e3195 420/* xmap: translation map for hexadecimal encoding */
24278fc4 421static const char xmap[] =
e80e3195
CBW
422 "0123456789abcdef";
423
05128928 424/* shahex: returns pointer to current digest (hexadecimal) */
a5b310e3 425static char *shahex(SHA *s)
05128928 426{
03c6205f 427 UINT i;
e80e3195
CBW
428 char *h;
429 UCHR *d;
05128928 430
7123ec76 431 d = digcpy(s);
05128928
NC
432 s->hex[0] = '\0';
433 if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex))
434 return(s->hex);
7123ec76 435 for (i = 0, h = s->hex; i < s->digestlen; i++) {
e80e3195
CBW
436 *h++ = xmap[(*d >> 4) & 0x0f];
437 *h++ = xmap[(*d++ ) & 0x0f];
438 }
439 *h = '\0';
05128928
NC
440 return(s->hex);
441}
442
e80e3195 443/* bmap: translation map for Base 64 encoding */
24278fc4 444static const char bmap[] =
05128928
NC
445 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
446
447/* encbase64: encodes input (0 to 3 bytes) into Base 64 */
03c6205f 448static void encbase64(UCHR *in, UINT n, char *out)
05128928
NC
449{
450 UCHR byte[3] = {0, 0, 0};
451
452 out[0] = '\0';
453 if (n < 1 || n > 3)
454 return;
207902b1 455 Copy(in, byte, n, UCHR);
e80e3195
CBW
456 out[0] = bmap[byte[0] >> 2];
457 out[1] = bmap[((byte[0] & 0x03) << 4) | (byte[1] >> 4)];
458 out[2] = bmap[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)];
459 out[3] = bmap[byte[2] & 0x3f];
05128928
NC
460 out[n+1] = '\0';
461}
462
463/* shabase64: returns pointer to current digest (Base 64) */
a5b310e3 464static char *shabase64(SHA *s)
05128928 465{
03c6205f 466 UINT n;
05128928
NC
467 UCHR *q;
468 char out[5];
469
7123ec76 470 q = digcpy(s);
05128928 471 s->base64[0] = '\0';
a21a75c8 472 if (B64LEN((size_t) s->digestlen) >= sizeof(s->base64))
05128928 473 return(s->base64);
7123ec76 474 for (n = s->digestlen; n > 3; n -= 3, q += 3) {
05128928
NC
475 encbase64(q, 3, out);
476 strcat(s->base64, out);
477 }
478 encbase64(q, n, out);
479 strcat(s->base64, out);
480 return(s->base64);
481}
482
207902b1
CBW
483/* hmacinit: initializes HMAC-SHA digest object */
484static HMAC *hmacinit(HMAC *h, int alg, UCHR *key, UINT keylen)
05128928 485{
a5b310e3 486 UINT i;
207902b1 487 SHA ksha;
a5b310e3 488
207902b1
CBW
489 Zero(h, 1, HMAC);
490 if (!shainit(&h->isha, alg))
a5b310e3 491 return(NULL);
207902b1 492 if (!shainit(&h->osha, alg))
a5b310e3 493 return(NULL);
207902b1
CBW
494 if (keylen <= h->osha.blocksize / 8)
495 Copy(key, h->key, keylen, char);
a5b310e3 496 else {
207902b1 497 if (!shainit(&ksha, alg))
a5b310e3 498 return(NULL);
207902b1
CBW
499 shawrite(key, keylen * 8, &ksha);
500 shafinish(&ksha);
501 Copy(digcpy(&ksha), h->key, ksha.digestlen, char);
a5b310e3 502 }
207902b1
CBW
503 h->digestlen = h->osha.digestlen;
504 for (i = 0; i < h->osha.blocksize / 8; i++)
a5b310e3 505 h->key[i] ^= 0x5c;
207902b1
CBW
506 shawrite(h->key, h->osha.blocksize, &h->osha);
507 for (i = 0; i < h->isha.blocksize / 8; i++)
a5b310e3 508 h->key[i] ^= (0x5c ^ 0x36);
207902b1
CBW
509 shawrite(h->key, h->isha.blocksize, &h->isha);
510 Zero(h->key, sizeof(h->key), char);
a5b310e3
CBW
511 return(h);
512}
513
514/* hmacwrite: triggers a state update using data in bitstr/bitcnt */
515static ULNG hmacwrite(UCHR *bitstr, ULNG bitcnt, HMAC *h)
516{
207902b1 517 return(shawrite(bitstr, bitcnt, &h->isha));
a5b310e3
CBW
518}
519
520/* hmacfinish: computes final digest state */
521static void hmacfinish(HMAC *h)
522{
207902b1
CBW
523 shafinish(&h->isha);
524 shawrite(digcpy(&h->isha), h->isha.digestlen * 8, &h->osha);
525 shafinish(&h->osha);
a5b310e3
CBW
526}
527
207902b1
CBW
528#define hmacdigest(h) digcpy(&(h)->osha)
529
a5b310e3
CBW
530/* hmachex: returns pointer to digest (hexadecimal) */
531static char *hmachex(HMAC *h)
532{
207902b1 533 return(shahex(&h->osha));
a5b310e3
CBW
534}
535
536/* hmacbase64: returns pointer to digest (Base 64) */
537static char *hmacbase64(HMAC *h)
538{
207902b1 539 return(shabase64(&h->osha));
05128928 540}