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
|
|
|
|
|
|
} |