1b39c5158Smillert /* 2b39c5158Smillert * sha.c: routines to compute SHA-1/224/256/384/512 digests 3b39c5158Smillert * 46fb12b70Safresh1 * Ref: NIST FIPS PUB 180-4 Secure Hash Standard 5b39c5158Smillert * 6*9f11ffb7Safresh1 * Copyright (C) 2003-2017 Mark Shelor, All Rights Reserved 7b39c5158Smillert * 8*9f11ffb7Safresh1 * Version: 6.01 9*9f11ffb7Safresh1 * Mon Dec 25 00:08:08 MST 2017 10b39c5158Smillert * 11b39c5158Smillert */ 12b39c5158Smillert 13b39c5158Smillert #include <stdio.h> 14b39c5158Smillert #include <stdlib.h> 15b39c5158Smillert #include <stddef.h> 16b39c5158Smillert #include <string.h> 17b39c5158Smillert #include <ctype.h> 18b39c5158Smillert #include "sha.h" 19b39c5158Smillert #include "sha64bit.h" 20b39c5158Smillert 21b39c5158Smillert #define W32 SHA32 /* useful abbreviations */ 22b39c5158Smillert #define C32 SHA32_CONST 23b39c5158Smillert #define SR32 SHA32_SHR 24b39c5158Smillert #define SL32 SHA32_SHL 25b39c5158Smillert #define LO32 SHA_LO32 26b39c5158Smillert #define UCHR unsigned char 27b39c5158Smillert #define UINT unsigned int 28b39c5158Smillert #define ULNG unsigned long 29b39c5158Smillert #define VP void * 30b39c5158Smillert 31b39c5158Smillert #define ROTR(x, n) (SR32(x, n) | SL32(x, 32-(n))) 32b39c5158Smillert #define ROTL(x, n) (SL32(x, n) | SR32(x, 32-(n))) 33b39c5158Smillert 34b39c5158Smillert #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 35b39c5158Smillert #define Pa(x, y, z) ((x) ^ (y) ^ (z)) 36b39c5158Smillert #define Ma(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) 37b39c5158Smillert 38b39c5158Smillert #define SIGMA0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) 39b39c5158Smillert #define SIGMA1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) 40b39c5158Smillert #define sigma0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SR32(x, 3)) 41b39c5158Smillert #define sigma1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SR32(x, 10)) 42b39c5158Smillert 43b39c5158Smillert #define K1 C32(0x5a827999) /* SHA-1 constants */ 44b39c5158Smillert #define K2 C32(0x6ed9eba1) 45b39c5158Smillert #define K3 C32(0x8f1bbcdc) 46b39c5158Smillert #define K4 C32(0xca62c1d6) 47b39c5158Smillert 48b8851fccSafresh1 static const W32 K256[64] = /* SHA-224/256 constants */ 49b39c5158Smillert { 50b39c5158Smillert C32(0x428a2f98), C32(0x71374491), C32(0xb5c0fbcf), C32(0xe9b5dba5), 51b39c5158Smillert C32(0x3956c25b), C32(0x59f111f1), C32(0x923f82a4), C32(0xab1c5ed5), 52b39c5158Smillert C32(0xd807aa98), C32(0x12835b01), C32(0x243185be), C32(0x550c7dc3), 53b39c5158Smillert C32(0x72be5d74), C32(0x80deb1fe), C32(0x9bdc06a7), C32(0xc19bf174), 54b39c5158Smillert C32(0xe49b69c1), C32(0xefbe4786), C32(0x0fc19dc6), C32(0x240ca1cc), 55b39c5158Smillert C32(0x2de92c6f), C32(0x4a7484aa), C32(0x5cb0a9dc), C32(0x76f988da), 56b39c5158Smillert C32(0x983e5152), C32(0xa831c66d), C32(0xb00327c8), C32(0xbf597fc7), 57b39c5158Smillert C32(0xc6e00bf3), C32(0xd5a79147), C32(0x06ca6351), C32(0x14292967), 58b39c5158Smillert C32(0x27b70a85), C32(0x2e1b2138), C32(0x4d2c6dfc), C32(0x53380d13), 59b39c5158Smillert C32(0x650a7354), C32(0x766a0abb), C32(0x81c2c92e), C32(0x92722c85), 60b39c5158Smillert C32(0xa2bfe8a1), C32(0xa81a664b), C32(0xc24b8b70), C32(0xc76c51a3), 61b39c5158Smillert C32(0xd192e819), C32(0xd6990624), C32(0xf40e3585), C32(0x106aa070), 62b39c5158Smillert C32(0x19a4c116), C32(0x1e376c08), C32(0x2748774c), C32(0x34b0bcb5), 63b39c5158Smillert C32(0x391c0cb3), C32(0x4ed8aa4a), C32(0x5b9cca4f), C32(0x682e6ff3), 64b39c5158Smillert C32(0x748f82ee), C32(0x78a5636f), C32(0x84c87814), C32(0x8cc70208), 65b39c5158Smillert C32(0x90befffa), C32(0xa4506ceb), C32(0xbef9a3f7), C32(0xc67178f2) 66b39c5158Smillert }; 67b39c5158Smillert 68b8851fccSafresh1 static const W32 H01[8] = /* SHA-1 initial hash value */ 69b39c5158Smillert { 70b8851fccSafresh1 C32(0x67452301), C32(0xefcdab89), C32(0x98badcfe), C32(0x10325476), 71b8851fccSafresh1 C32(0xc3d2e1f0), C32(0x00000000), C32(0x00000000), C32(0x00000000) 72b39c5158Smillert }; 73b39c5158Smillert 74b8851fccSafresh1 static const W32 H0224[8] = /* SHA-224 initial hash value */ 75b39c5158Smillert { 76b39c5158Smillert C32(0xc1059ed8), C32(0x367cd507), C32(0x3070dd17), C32(0xf70e5939), 77b39c5158Smillert C32(0xffc00b31), C32(0x68581511), C32(0x64f98fa7), C32(0xbefa4fa4) 78b39c5158Smillert }; 79b39c5158Smillert 80b8851fccSafresh1 static const W32 H0256[8] = /* SHA-256 initial hash value */ 81b39c5158Smillert { 82b39c5158Smillert C32(0x6a09e667), C32(0xbb67ae85), C32(0x3c6ef372), C32(0xa54ff53a), 83b39c5158Smillert C32(0x510e527f), C32(0x9b05688c), C32(0x1f83d9ab), C32(0x5be0cd19) 84b39c5158Smillert }; 85b39c5158Smillert 86b39c5158Smillert static void sha1(SHA *s, UCHR *block) /* SHA-1 transform */ 87b39c5158Smillert { 88b39c5158Smillert W32 a, b, c, d, e; 8991f110e0Safresh1 W32 W[16]; 90b39c5158Smillert W32 *wp = W; 91b8851fccSafresh1 W32 *H = s->H32; 92b39c5158Smillert 93b39c5158Smillert SHA32_SCHED(W, block); 94b39c5158Smillert 95b39c5158Smillert /* 966fb12b70Safresh1 * Use SHA-1 alternate method from FIPS PUB 180-4 (ref. 6.1.3) 97b39c5158Smillert * 98b39c5158Smillert * To improve performance, unroll the loop and consolidate assignments 99b39c5158Smillert * by changing the roles of variables "a" through "e" at each step. 100b39c5158Smillert * Note that the variable "T" is no longer needed. 101b39c5158Smillert */ 102b39c5158Smillert 103b39c5158Smillert #define M1(a, b, c, d, e, f, k, w) \ 104b39c5158Smillert e += ROTL(a, 5) + f(b, c, d) + k + w; \ 105b39c5158Smillert b = ROTL(b, 30) 106b39c5158Smillert 107b39c5158Smillert #define M11(f, k, w) M1(a, b, c, d, e, f, k, w); 108b39c5158Smillert #define M12(f, k, w) M1(e, a, b, c, d, f, k, w); 109b39c5158Smillert #define M13(f, k, w) M1(d, e, a, b, c, f, k, w); 110b39c5158Smillert #define M14(f, k, w) M1(c, d, e, a, b, f, k, w); 111b39c5158Smillert #define M15(f, k, w) M1(b, c, d, e, a, f, k, w); 112b39c5158Smillert 113b39c5158Smillert #define W11(s) W[(s+ 0) & 0xf] 114b39c5158Smillert #define W12(s) W[(s+13) & 0xf] 115b39c5158Smillert #define W13(s) W[(s+ 8) & 0xf] 116b39c5158Smillert #define W14(s) W[(s+ 2) & 0xf] 117b39c5158Smillert 118b39c5158Smillert #define A1(s) (W11(s) = ROTL(W11(s) ^ W12(s) ^ W13(s) ^ W14(s), 1)) 119b39c5158Smillert 120b39c5158Smillert a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; 121b39c5158Smillert 122b39c5158Smillert M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); 123b39c5158Smillert M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); 124b39c5158Smillert M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); 125b39c5158Smillert M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); 126b39c5158Smillert M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); 127b39c5158Smillert M11(Ch, K1, *wp ); M12(Ch, K1, A1( 0)); M13(Ch, K1, A1( 1)); 128b39c5158Smillert M14(Ch, K1, A1( 2)); M15(Ch, K1, A1( 3)); M11(Pa, K2, A1( 4)); 129b39c5158Smillert M12(Pa, K2, A1( 5)); M13(Pa, K2, A1( 6)); M14(Pa, K2, A1( 7)); 130b39c5158Smillert M15(Pa, K2, A1( 8)); M11(Pa, K2, A1( 9)); M12(Pa, K2, A1(10)); 131b39c5158Smillert M13(Pa, K2, A1(11)); M14(Pa, K2, A1(12)); M15(Pa, K2, A1(13)); 132b39c5158Smillert M11(Pa, K2, A1(14)); M12(Pa, K2, A1(15)); M13(Pa, K2, A1( 0)); 133b39c5158Smillert M14(Pa, K2, A1( 1)); M15(Pa, K2, A1( 2)); M11(Pa, K2, A1( 3)); 134b39c5158Smillert M12(Pa, K2, A1( 4)); M13(Pa, K2, A1( 5)); M14(Pa, K2, A1( 6)); 135b39c5158Smillert M15(Pa, K2, A1( 7)); M11(Ma, K3, A1( 8)); M12(Ma, K3, A1( 9)); 136b39c5158Smillert M13(Ma, K3, A1(10)); M14(Ma, K3, A1(11)); M15(Ma, K3, A1(12)); 137b39c5158Smillert M11(Ma, K3, A1(13)); M12(Ma, K3, A1(14)); M13(Ma, K3, A1(15)); 138b39c5158Smillert M14(Ma, K3, A1( 0)); M15(Ma, K3, A1( 1)); M11(Ma, K3, A1( 2)); 139b39c5158Smillert M12(Ma, K3, A1( 3)); M13(Ma, K3, A1( 4)); M14(Ma, K3, A1( 5)); 140b39c5158Smillert M15(Ma, K3, A1( 6)); M11(Ma, K3, A1( 7)); M12(Ma, K3, A1( 8)); 141b39c5158Smillert M13(Ma, K3, A1( 9)); M14(Ma, K3, A1(10)); M15(Ma, K3, A1(11)); 142b39c5158Smillert M11(Pa, K4, A1(12)); M12(Pa, K4, A1(13)); M13(Pa, K4, A1(14)); 143b39c5158Smillert M14(Pa, K4, A1(15)); M15(Pa, K4, A1( 0)); M11(Pa, K4, A1( 1)); 144b39c5158Smillert M12(Pa, K4, A1( 2)); M13(Pa, K4, A1( 3)); M14(Pa, K4, A1( 4)); 145b39c5158Smillert M15(Pa, K4, A1( 5)); M11(Pa, K4, A1( 6)); M12(Pa, K4, A1( 7)); 146b39c5158Smillert M13(Pa, K4, A1( 8)); M14(Pa, K4, A1( 9)); M15(Pa, K4, A1(10)); 147b39c5158Smillert M11(Pa, K4, A1(11)); M12(Pa, K4, A1(12)); M13(Pa, K4, A1(13)); 148b39c5158Smillert M14(Pa, K4, A1(14)); M15(Pa, K4, A1(15)); 149b39c5158Smillert 150b39c5158Smillert H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; 151b39c5158Smillert } 152b39c5158Smillert 153b39c5158Smillert static void sha256(SHA *s, UCHR *block) /* SHA-224/256 transform */ 154b39c5158Smillert { 155b39c5158Smillert W32 a, b, c, d, e, f, g, h, T1; 15691f110e0Safresh1 W32 W[16]; 157b8851fccSafresh1 const W32 *kp = K256; 158b39c5158Smillert W32 *wp = W; 159b8851fccSafresh1 W32 *H = s->H32; 160b39c5158Smillert 161b39c5158Smillert SHA32_SCHED(W, block); 162b39c5158Smillert 163b39c5158Smillert /* 164b39c5158Smillert * Use same technique as in sha1() 165b39c5158Smillert * 166b39c5158Smillert * To improve performance, unroll the loop and consolidate assignments 167b39c5158Smillert * by changing the roles of variables "a" through "h" at each step. 168b39c5158Smillert * Note that the variable "T2" is no longer needed. 169b39c5158Smillert */ 170b39c5158Smillert 171b39c5158Smillert #define M2(a, b, c, d, e, f, g, h, w) \ 172b39c5158Smillert T1 = h + SIGMA1(e) + Ch(e, f, g) + (*kp++) + w; \ 173b39c5158Smillert h = T1 + SIGMA0(a) + Ma(a, b, c); d += T1; 174b39c5158Smillert 175b39c5158Smillert #define W21(s) W[(s+ 0) & 0xf] 176b39c5158Smillert #define W22(s) W[(s+14) & 0xf] 177b39c5158Smillert #define W23(s) W[(s+ 9) & 0xf] 178b39c5158Smillert #define W24(s) W[(s+ 1) & 0xf] 179b39c5158Smillert 180b39c5158Smillert #define A2(s) (W21(s) += sigma1(W22(s)) + W23(s) + sigma0(W24(s))) 181b39c5158Smillert 182b39c5158Smillert #define M21(w) M2(a, b, c, d, e, f, g, h, w) 183b39c5158Smillert #define M22(w) M2(h, a, b, c, d, e, f, g, w) 184b39c5158Smillert #define M23(w) M2(g, h, a, b, c, d, e, f, w) 185b39c5158Smillert #define M24(w) M2(f, g, h, a, b, c, d, e, w) 186b39c5158Smillert #define M25(w) M2(e, f, g, h, a, b, c, d, w) 187b39c5158Smillert #define M26(w) M2(d, e, f, g, h, a, b, c, w) 188b39c5158Smillert #define M27(w) M2(c, d, e, f, g, h, a, b, w) 189b39c5158Smillert #define M28(w) M2(b, c, d, e, f, g, h, a, w) 190b39c5158Smillert 191b39c5158Smillert a = H[0]; b = H[1]; c = H[2]; d = H[3]; 192b39c5158Smillert e = H[4]; f = H[5]; g = H[6]; h = H[7]; 193b39c5158Smillert 194b39c5158Smillert M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); 195b39c5158Smillert M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++); 196b39c5158Smillert M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); 197b39c5158Smillert M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp ); 198b39c5158Smillert M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); 199b39c5158Smillert M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); 200b39c5158Smillert M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); 201b39c5158Smillert M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); 202b39c5158Smillert M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); 203b39c5158Smillert M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); 204b39c5158Smillert M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); 205b39c5158Smillert M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); 206b39c5158Smillert M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); 207b39c5158Smillert M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); 208b39c5158Smillert M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); 209b39c5158Smillert M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); 210b39c5158Smillert 211b39c5158Smillert H[0] += a; H[1] += b; H[2] += c; H[3] += d; 212b39c5158Smillert H[4] += e; H[5] += f; H[6] += g; H[7] += h; 213b39c5158Smillert } 214b39c5158Smillert 215b39c5158Smillert #include "sha64bit.c" 216b39c5158Smillert 217b8851fccSafresh1 #define BITSET(s, pos) s[(pos) >> 3] & (UCHR) (0x01 << (7 - (pos) % 8)) 218b8851fccSafresh1 #define SETBIT(s, pos) s[(pos) >> 3] |= (UCHR) (0x01 << (7 - (pos) % 8)) 219b8851fccSafresh1 #define CLRBIT(s, pos) s[(pos) >> 3] &= (UCHR) ~(0x01 << (7 - (pos) % 8)) 22091f110e0Safresh1 #define NBYTES(nbits) (((nbits) + 7) >> 3) 221b39c5158Smillert #define HEXLEN(nbytes) ((nbytes) << 1) 222b39c5158Smillert #define B64LEN(nbytes) (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \ 223b39c5158Smillert : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1) 224b39c5158Smillert 225b39c5158Smillert /* w32mem: writes 32-bit word to memory in big-endian order */ 2266fb12b70Safresh1 static UCHR *w32mem(UCHR *mem, W32 w32) 227b39c5158Smillert { 228b39c5158Smillert int i; 229b39c5158Smillert 230b39c5158Smillert for (i = 0; i < 4; i++) 231b39c5158Smillert *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff); 2326fb12b70Safresh1 return(mem); 2336fb12b70Safresh1 } 2346fb12b70Safresh1 2356fb12b70Safresh1 /* memw32: returns 32-bit word from memory written in big-endian order */ 2366fb12b70Safresh1 static W32 memw32(UCHR *mem) 2376fb12b70Safresh1 { 2386fb12b70Safresh1 int i; 2396fb12b70Safresh1 W32 w = 0; 2406fb12b70Safresh1 2416fb12b70Safresh1 for (i = 0; i < 4; i++) 2426fb12b70Safresh1 w = (w << 8) + *mem++; 2436fb12b70Safresh1 return(w); 244b39c5158Smillert } 245b39c5158Smillert 246b39c5158Smillert /* digcpy: writes current state to digest buffer */ 2476fb12b70Safresh1 static UCHR *digcpy(SHA *s) 248b39c5158Smillert { 2496fb12b70Safresh1 int i; 250b39c5158Smillert UCHR *d = s->digest; 251b8851fccSafresh1 W32 *p32 = s->H32; 252b8851fccSafresh1 W64 *p64 = s->H64; 253b39c5158Smillert 254b39c5158Smillert if (s->alg <= SHA256) 255b39c5158Smillert for (i = 0; i < 8; i++, d += 4) 256b39c5158Smillert w32mem(d, *p32++); 257b39c5158Smillert else 258b39c5158Smillert for (i = 0; i < 8; i++, d += 8) { 259b39c5158Smillert w32mem(d, (W32) ((*p64 >> 16) >> 16)); 260b39c5158Smillert w32mem(d+4, (W32) (*p64++ & SHA32_MAX)); 261b39c5158Smillert } 2626fb12b70Safresh1 return(s->digest); 2636fb12b70Safresh1 } 2646fb12b70Safresh1 2656fb12b70Safresh1 /* statecpy: writes buffer to current state (opposite of digcpy) */ 2666fb12b70Safresh1 static UCHR *statecpy(SHA *s, UCHR *buf) 2676fb12b70Safresh1 { 2686fb12b70Safresh1 int i; 269b8851fccSafresh1 W32 *p32 = s->H32; 270b8851fccSafresh1 W64 *p64 = s->H64; 2716fb12b70Safresh1 2726fb12b70Safresh1 if (s->alg <= SHA256) 2736fb12b70Safresh1 for (i = 0; i < 8; i++, buf += 4) 2746fb12b70Safresh1 *p32++ = memw32(buf); 2756fb12b70Safresh1 else 2766fb12b70Safresh1 for (i = 0; i < 8; i++, buf += 8) 277b8851fccSafresh1 *p64++ = (((W64)memw32(buf) << 16) << 16) + 2786fb12b70Safresh1 memw32(buf+4); 2796fb12b70Safresh1 return(buf); 280b39c5158Smillert } 281b39c5158Smillert 282b8851fccSafresh1 #define SHA_INIT(s, algo, transform) \ 283b39c5158Smillert do { \ 284b8851fccSafresh1 Zero(s, 1, SHA); \ 285b39c5158Smillert s->alg = algo; s->sha = sha ## transform; \ 286b8851fccSafresh1 if (s->alg <= SHA256) \ 287b8851fccSafresh1 Copy(H0 ## algo, s->H32, 8, SHA32); \ 288b8851fccSafresh1 else \ 289b8851fccSafresh1 Copy(H0 ## algo, s->H64, 8, SHA64); \ 290b39c5158Smillert s->blocksize = SHA ## algo ## _BLOCK_BITS; \ 291b39c5158Smillert s->digestlen = SHA ## algo ## _DIGEST_BITS >> 3; \ 292b39c5158Smillert } while (0) 293b39c5158Smillert 294b8851fccSafresh1 /* sharewind: resets digest object */ 29591f110e0Safresh1 static void sharewind(SHA *s) 296b39c5158Smillert { 297b8851fccSafresh1 if (s->alg == SHA1) SHA_INIT(s, 1, 1); 298b8851fccSafresh1 else if (s->alg == SHA224) SHA_INIT(s, 224, 256); 299b8851fccSafresh1 else if (s->alg == SHA256) SHA_INIT(s, 256, 256); 300b8851fccSafresh1 else if (s->alg == SHA384) SHA_INIT(s, 384, 512); 301b8851fccSafresh1 else if (s->alg == SHA512) SHA_INIT(s, 512, 512); 302b8851fccSafresh1 else if (s->alg == SHA512224) SHA_INIT(s, 512224, 512); 303b8851fccSafresh1 else if (s->alg == SHA512256) SHA_INIT(s, 512256, 512); 304b39c5158Smillert } 305b39c5158Smillert 306b8851fccSafresh1 /* shainit: initializes digest object */ 307b8851fccSafresh1 static int shainit(SHA *s, int alg) 308b39c5158Smillert { 309b8851fccSafresh1 if (alg >= SHA384 && !sha_384_512) 310b8851fccSafresh1 return 0; 311b39c5158Smillert if (alg != SHA1 && alg != SHA224 && alg != SHA256 && 312898184e3Ssthen alg != SHA384 && alg != SHA512 && 313898184e3Ssthen alg != SHA512224 && alg != SHA512256) 314b8851fccSafresh1 return 0; 315b39c5158Smillert s->alg = alg; 316b39c5158Smillert sharewind(s); 317b8851fccSafresh1 return 1; 31891f110e0Safresh1 } 31991f110e0Safresh1 320b39c5158Smillert /* shadirect: updates state directly (w/o going through s->block) */ 321b39c5158Smillert static ULNG shadirect(UCHR *bitstr, ULNG bitcnt, SHA *s) 322b39c5158Smillert { 323b39c5158Smillert ULNG savecnt = bitcnt; 324b39c5158Smillert 325b39c5158Smillert while (bitcnt >= s->blocksize) { 326b39c5158Smillert s->sha(s, bitstr); 327b39c5158Smillert bitstr += (s->blocksize >> 3); 328b39c5158Smillert bitcnt -= s->blocksize; 329b39c5158Smillert } 330b39c5158Smillert if (bitcnt > 0) { 331b8851fccSafresh1 Copy(bitstr, s->block, NBYTES(bitcnt), char); 332b39c5158Smillert s->blockcnt = bitcnt; 333b39c5158Smillert } 334b39c5158Smillert return(savecnt); 335b39c5158Smillert } 336b39c5158Smillert 337b8851fccSafresh1 /* shabytes: updates state for byte-aligned data in s->block */ 338b39c5158Smillert static ULNG shabytes(UCHR *bitstr, ULNG bitcnt, SHA *s) 339b39c5158Smillert { 340b39c5158Smillert UINT offset; 341b39c5158Smillert UINT nbits; 342b39c5158Smillert ULNG savecnt = bitcnt; 343b39c5158Smillert 344b39c5158Smillert offset = s->blockcnt >> 3; 345b39c5158Smillert if (s->blockcnt + bitcnt >= s->blocksize) { 346b39c5158Smillert nbits = s->blocksize - s->blockcnt; 347b8851fccSafresh1 Copy(bitstr, s->block+offset, nbits>>3, char); 348b39c5158Smillert bitcnt -= nbits; 349b39c5158Smillert bitstr += (nbits >> 3); 350b39c5158Smillert s->sha(s, s->block), s->blockcnt = 0; 351b39c5158Smillert shadirect(bitstr, bitcnt, s); 352b39c5158Smillert } 353b39c5158Smillert else { 354b8851fccSafresh1 Copy(bitstr, s->block+offset, NBYTES(bitcnt), char); 355b39c5158Smillert s->blockcnt += bitcnt; 356b39c5158Smillert } 357b39c5158Smillert return(savecnt); 358b39c5158Smillert } 359b39c5158Smillert 360b8851fccSafresh1 /* shabits: updates state for bit-aligned data in s->block */ 361b39c5158Smillert static ULNG shabits(UCHR *bitstr, ULNG bitcnt, SHA *s) 362b39c5158Smillert { 363b8851fccSafresh1 ULNG i; 364b39c5158Smillert 365b8851fccSafresh1 for (i = 0UL; i < bitcnt; i++) { 366b8851fccSafresh1 if (BITSET(bitstr, i)) 367*9f11ffb7Safresh1 SETBIT(s->block, s->blockcnt); 368b8851fccSafresh1 else 369*9f11ffb7Safresh1 CLRBIT(s->block, s->blockcnt); 370*9f11ffb7Safresh1 if (++s->blockcnt == s->blocksize) 371b39c5158Smillert s->sha(s, s->block), s->blockcnt = 0; 372b39c5158Smillert } 373b8851fccSafresh1 return(bitcnt); 374b39c5158Smillert } 375b39c5158Smillert 376b39c5158Smillert /* shawrite: triggers a state update using data in bitstr/bitcnt */ 37791f110e0Safresh1 static ULNG shawrite(UCHR *bitstr, ULNG bitcnt, SHA *s) 378b39c5158Smillert { 379b8851fccSafresh1 if (!bitcnt) 380b39c5158Smillert return(0); 381b39c5158Smillert if (SHA_LO32(s->lenll += bitcnt) < bitcnt) 382b39c5158Smillert if (SHA_LO32(++s->lenlh) == 0) 383b39c5158Smillert if (SHA_LO32(++s->lenhl) == 0) 384b39c5158Smillert s->lenhh++; 385b39c5158Smillert if (s->blockcnt == 0) 386b39c5158Smillert return(shadirect(bitstr, bitcnt, s)); 387b39c5158Smillert else if (s->blockcnt % 8 == 0) 388b39c5158Smillert return(shabytes(bitstr, bitcnt, s)); 389b39c5158Smillert else 390b39c5158Smillert return(shabits(bitstr, bitcnt, s)); 391b39c5158Smillert } 392b39c5158Smillert 393b39c5158Smillert /* shafinish: pads remaining block(s) and computes final digest state */ 39491f110e0Safresh1 static void shafinish(SHA *s) 395b39c5158Smillert { 396b39c5158Smillert UINT lenpos, lhpos, llpos; 397b39c5158Smillert 398b39c5158Smillert lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896; 399b39c5158Smillert lhpos = s->blocksize == SHA1_BLOCK_BITS ? 56 : 120; 400b39c5158Smillert llpos = s->blocksize == SHA1_BLOCK_BITS ? 60 : 124; 401b39c5158Smillert SETBIT(s->block, s->blockcnt), s->blockcnt++; 402b39c5158Smillert while (s->blockcnt > lenpos) 403b39c5158Smillert if (s->blockcnt < s->blocksize) 404b39c5158Smillert CLRBIT(s->block, s->blockcnt), s->blockcnt++; 405b39c5158Smillert else 406b39c5158Smillert s->sha(s, s->block), s->blockcnt = 0; 407b39c5158Smillert while (s->blockcnt < lenpos) 408b39c5158Smillert CLRBIT(s->block, s->blockcnt), s->blockcnt++; 409b39c5158Smillert if (s->blocksize > SHA1_BLOCK_BITS) { 410b39c5158Smillert w32mem(s->block + 112, s->lenhh); 411b39c5158Smillert w32mem(s->block + 116, s->lenhl); 412b39c5158Smillert } 413b39c5158Smillert w32mem(s->block + lhpos, s->lenlh); 414b39c5158Smillert w32mem(s->block + llpos, s->lenll); 415b39c5158Smillert s->sha(s, s->block); 416b39c5158Smillert } 417b39c5158Smillert 418b8851fccSafresh1 #define shadigest(state) digcpy(state) 419b8851fccSafresh1 4206fb12b70Safresh1 /* xmap: translation map for hexadecimal encoding */ 421b8851fccSafresh1 static const char xmap[] = 4226fb12b70Safresh1 "0123456789abcdef"; 423b39c5158Smillert 424b39c5158Smillert /* shahex: returns pointer to current digest (hexadecimal) */ 42591f110e0Safresh1 static char *shahex(SHA *s) 426b39c5158Smillert { 427b8851fccSafresh1 UINT i; 4286fb12b70Safresh1 char *h; 4296fb12b70Safresh1 UCHR *d; 430b39c5158Smillert 4316fb12b70Safresh1 d = digcpy(s); 432b39c5158Smillert s->hex[0] = '\0'; 433b39c5158Smillert if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex)) 434b39c5158Smillert return(s->hex); 4356fb12b70Safresh1 for (i = 0, h = s->hex; i < s->digestlen; i++) { 4366fb12b70Safresh1 *h++ = xmap[(*d >> 4) & 0x0f]; 4376fb12b70Safresh1 *h++ = xmap[(*d++ ) & 0x0f]; 4386fb12b70Safresh1 } 4396fb12b70Safresh1 *h = '\0'; 440b39c5158Smillert return(s->hex); 441b39c5158Smillert } 442b39c5158Smillert 4436fb12b70Safresh1 /* bmap: translation map for Base 64 encoding */ 444b8851fccSafresh1 static const char bmap[] = 445b39c5158Smillert "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 446b39c5158Smillert 447b39c5158Smillert /* encbase64: encodes input (0 to 3 bytes) into Base 64 */ 448b8851fccSafresh1 static void encbase64(UCHR *in, UINT n, char *out) 449b39c5158Smillert { 450b39c5158Smillert UCHR byte[3] = {0, 0, 0}; 451b39c5158Smillert 452b39c5158Smillert out[0] = '\0'; 453b39c5158Smillert if (n < 1 || n > 3) 454b39c5158Smillert return; 455b8851fccSafresh1 Copy(in, byte, n, UCHR); 4566fb12b70Safresh1 out[0] = bmap[byte[0] >> 2]; 4576fb12b70Safresh1 out[1] = bmap[((byte[0] & 0x03) << 4) | (byte[1] >> 4)]; 4586fb12b70Safresh1 out[2] = bmap[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)]; 4596fb12b70Safresh1 out[3] = bmap[byte[2] & 0x3f]; 460b39c5158Smillert out[n+1] = '\0'; 461b39c5158Smillert } 462b39c5158Smillert 463b39c5158Smillert /* shabase64: returns pointer to current digest (Base 64) */ 46491f110e0Safresh1 static char *shabase64(SHA *s) 465b39c5158Smillert { 466b8851fccSafresh1 UINT n; 467b39c5158Smillert UCHR *q; 468b39c5158Smillert char out[5]; 469b39c5158Smillert 4706fb12b70Safresh1 q = digcpy(s); 471b39c5158Smillert s->base64[0] = '\0'; 47291f110e0Safresh1 if (B64LEN((size_t) s->digestlen) >= sizeof(s->base64)) 473b39c5158Smillert return(s->base64); 4746fb12b70Safresh1 for (n = s->digestlen; n > 3; n -= 3, q += 3) { 475b39c5158Smillert encbase64(q, 3, out); 476b39c5158Smillert strcat(s->base64, out); 477b39c5158Smillert } 478b39c5158Smillert encbase64(q, n, out); 479b39c5158Smillert strcat(s->base64, out); 480b39c5158Smillert return(s->base64); 481b39c5158Smillert } 482b39c5158Smillert 483b8851fccSafresh1 /* hmacinit: initializes HMAC-SHA digest object */ 484b8851fccSafresh1 static HMAC *hmacinit(HMAC *h, int alg, UCHR *key, UINT keylen) 485b39c5158Smillert { 48691f110e0Safresh1 UINT i; 487b8851fccSafresh1 SHA ksha; 48891f110e0Safresh1 489b8851fccSafresh1 Zero(h, 1, HMAC); 490b8851fccSafresh1 if (!shainit(&h->isha, alg)) 49191f110e0Safresh1 return(NULL); 492b8851fccSafresh1 if (!shainit(&h->osha, alg)) 49391f110e0Safresh1 return(NULL); 494b8851fccSafresh1 if (keylen <= h->osha.blocksize / 8) 495b8851fccSafresh1 Copy(key, h->key, keylen, char); 49691f110e0Safresh1 else { 497b8851fccSafresh1 if (!shainit(&ksha, alg)) 49891f110e0Safresh1 return(NULL); 499b8851fccSafresh1 shawrite(key, keylen * 8, &ksha); 500b8851fccSafresh1 shafinish(&ksha); 501b8851fccSafresh1 Copy(digcpy(&ksha), h->key, ksha.digestlen, char); 50291f110e0Safresh1 } 503b8851fccSafresh1 h->digestlen = h->osha.digestlen; 504b8851fccSafresh1 for (i = 0; i < h->osha.blocksize / 8; i++) 50591f110e0Safresh1 h->key[i] ^= 0x5c; 506b8851fccSafresh1 shawrite(h->key, h->osha.blocksize, &h->osha); 507b8851fccSafresh1 for (i = 0; i < h->isha.blocksize / 8; i++) 50891f110e0Safresh1 h->key[i] ^= (0x5c ^ 0x36); 509b8851fccSafresh1 shawrite(h->key, h->isha.blocksize, &h->isha); 510b8851fccSafresh1 Zero(h->key, sizeof(h->key), char); 51191f110e0Safresh1 return(h); 51291f110e0Safresh1 } 51391f110e0Safresh1 51491f110e0Safresh1 /* hmacwrite: triggers a state update using data in bitstr/bitcnt */ 51591f110e0Safresh1 static ULNG hmacwrite(UCHR *bitstr, ULNG bitcnt, HMAC *h) 51691f110e0Safresh1 { 517b8851fccSafresh1 return(shawrite(bitstr, bitcnt, &h->isha)); 51891f110e0Safresh1 } 51991f110e0Safresh1 52091f110e0Safresh1 /* hmacfinish: computes final digest state */ 52191f110e0Safresh1 static void hmacfinish(HMAC *h) 52291f110e0Safresh1 { 523b8851fccSafresh1 shafinish(&h->isha); 524b8851fccSafresh1 shawrite(digcpy(&h->isha), h->isha.digestlen * 8, &h->osha); 525b8851fccSafresh1 shafinish(&h->osha); 52691f110e0Safresh1 } 52791f110e0Safresh1 528b8851fccSafresh1 #define hmacdigest(h) digcpy(&(h)->osha) 529b8851fccSafresh1 53091f110e0Safresh1 /* hmachex: returns pointer to digest (hexadecimal) */ 53191f110e0Safresh1 static char *hmachex(HMAC *h) 53291f110e0Safresh1 { 533b8851fccSafresh1 return(shahex(&h->osha)); 53491f110e0Safresh1 } 53591f110e0Safresh1 53691f110e0Safresh1 /* hmacbase64: returns pointer to digest (Base 64) */ 53791f110e0Safresh1 static char *hmacbase64(HMAC *h) 53891f110e0Safresh1 { 539b8851fccSafresh1 return(shabase64(&h->osha)); 540b39c5158Smillert } 541