/src/nss-nspr/nss/lib/freebl/sha512.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512 |
3 | | * |
4 | | * This Source Code Form is subject to the terms of the Mozilla Public |
5 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | | |
8 | | #ifdef FREEBL_NO_DEPEND |
9 | | #include "stubs.h" |
10 | | #endif |
11 | | |
12 | | #include "prcpucfg.h" |
13 | | #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG) |
14 | | #define NOUNROLL512 1 |
15 | | #undef HAVE_LONG_LONG |
16 | | #endif |
17 | | #include "prtypes.h" /* for PRUintXX */ |
18 | | #include "prlong.h" |
19 | | #include "secport.h" /* for PORT_XXX */ |
20 | | #include "blapi.h" |
21 | | #include "blapii.h" |
22 | | #include "secerr.h" |
23 | | #include "sha256.h" /* for struct SHA256ContextStr */ |
24 | | #include "crypto_primitives.h" |
25 | | #include "ppc-crypto.h" /* for USE_PPC_CRYPTO */ |
26 | | |
27 | | /* ============= Common constants and defines ======================= */ |
28 | | |
29 | 31.0M | #define W ctx->u.w |
30 | 125k | #define B ctx->u.b |
31 | 929k | #define H ctx->h |
32 | | |
33 | 14.6M | #define SHR(x, n) (x >> n) |
34 | | #define SHL(x, n) (x << n) |
35 | 9.13M | #define Ch(x, y, z) ((x & y) ^ (~x & z)) |
36 | 9.13M | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |
37 | 3.45k | #define SHA_MIN(a, b) (a < b ? a : b) |
38 | | |
39 | | /* Padding used with all flavors of SHA */ |
40 | | static const PRUint8 pad[240] = { |
41 | | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
42 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
43 | | /* compiler will fill the rest in with zeros */ |
44 | | }; |
45 | | |
46 | | /* ============= SHA256 implementation ================================== */ |
47 | | |
48 | | /* SHA-256 constants, K256. */ |
49 | | pre_align static const PRUint32 K256[64] post_align = { |
50 | | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
51 | | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
52 | | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
53 | | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
54 | | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, |
55 | | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
56 | | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, |
57 | | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
58 | | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
59 | | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
60 | | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, |
61 | | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
62 | | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, |
63 | | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
64 | | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
65 | | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
66 | | }; |
67 | | |
68 | | /* SHA-256 initial hash values */ |
69 | | static const PRUint32 H256[8] = { |
70 | | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, |
71 | | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 |
72 | | }; |
73 | | |
74 | | #if defined(IS_LITTLE_ENDIAN) |
75 | | #if (_MSC_VER >= 1300) |
76 | | #include <stdlib.h> |
77 | | #pragma intrinsic(_byteswap_ulong) |
78 | | #define SHA_HTONL(x) _byteswap_ulong(x) |
79 | | #elif defined(_MSC_VER) && defined(NSS_X86_OR_X64) |
80 | | #ifndef FORCEINLINE |
81 | | #if (_MSC_VER >= 1200) |
82 | | #define FORCEINLINE __forceinline |
83 | | #else |
84 | | #define FORCEINLINE __inline |
85 | | #endif |
86 | | #endif |
87 | | #define FASTCALL __fastcall |
88 | | |
89 | | static FORCEINLINE PRUint32 FASTCALL |
90 | | swap4b(PRUint32 dwd) |
91 | | { |
92 | | __asm { |
93 | | mov eax,dwd |
94 | | bswap eax |
95 | | } |
96 | | } |
97 | | |
98 | | #define SHA_HTONL(x) swap4b(x) |
99 | | |
100 | | #elif defined(__GNUC__) && defined(NSS_X86_OR_X64) |
101 | | static __inline__ PRUint32 |
102 | | swap4b(PRUint32 value) |
103 | 23.1k | { |
104 | 23.1k | __asm__("bswap %0" |
105 | 23.1k | : "+r"(value)); |
106 | 23.1k | return (value); |
107 | 23.1k | } |
108 | 23.1k | #define SHA_HTONL(x) swap4b(x) |
109 | | |
110 | | #elif defined(__GNUC__) && (defined(__thumb2__) || \ |
111 | | (!defined(__thumb__) && \ |
112 | | (defined(__ARM_ARCH_6__) || \ |
113 | | defined(__ARM_ARCH_6J__) || \ |
114 | | defined(__ARM_ARCH_6K__) || \ |
115 | | defined(__ARM_ARCH_6Z__) || \ |
116 | | defined(__ARM_ARCH_6ZK__) || \ |
117 | | defined(__ARM_ARCH_6T2__) || \ |
118 | | defined(__ARM_ARCH_7__) || \ |
119 | | defined(__ARM_ARCH_7A__) || \ |
120 | | defined(__ARM_ARCH_7R__)))) |
121 | | static __inline__ PRUint32 |
122 | | swap4b(PRUint32 value) |
123 | | { |
124 | | PRUint32 ret; |
125 | | __asm__("rev %0, %1" |
126 | | : "=r"(ret) |
127 | | : "r"(value)); |
128 | | return ret; |
129 | | } |
130 | | #define SHA_HTONL(x) swap4b(x) |
131 | | |
132 | | #else |
133 | | #define SWAP4MASK 0x00FF00FF |
134 | | static PRUint32 |
135 | | swap4b(PRUint32 value) |
136 | | { |
137 | | PRUint32 t1 = (value << 16) | (value >> 16); |
138 | | return ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK); |
139 | | } |
140 | | #define SHA_HTONL(x) swap4b(x) |
141 | | #endif |
142 | 18.4k | #define BYTESWAP4(x) x = SHA_HTONL(x) |
143 | | #endif /* defined(IS_LITTLE_ENDIAN) */ |
144 | | |
145 | | #if defined(_MSC_VER) |
146 | | #pragma intrinsic(_lrotr, _lrotl) |
147 | | #define ROTR32(x, n) _lrotr(x, n) |
148 | | #define ROTL32(x, n) _lrotl(x, n) |
149 | | #else |
150 | 0 | #define ROTR32(x, n) ((x >> n) | (x << ((8 * sizeof x) - n))) |
151 | | #define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n))) |
152 | | #endif |
153 | | |
154 | | /* Capitol Sigma and lower case sigma functions */ |
155 | 0 | #define S0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22)) |
156 | 0 | #define S1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25)) |
157 | 0 | #define s0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3)) |
158 | 0 | #define s1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10)) |
159 | | |
160 | | void SHA256_Compress_Native(SHA256Context *ctx); |
161 | | void SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input, unsigned int inputLen); |
162 | | |
163 | | static void SHA256_Compress_Generic(SHA256Context *ctx); |
164 | | static void SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input, |
165 | | unsigned int inputLen); |
166 | | |
167 | | #if !defined(USE_HW_SHA2) |
168 | | void |
169 | | SHA256_Compress_Native(SHA256Context *ctx) |
170 | | { |
171 | | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
172 | | PORT_Assert(0); |
173 | | } |
174 | | |
175 | | void |
176 | | SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input, |
177 | | unsigned int inputLen) |
178 | | { |
179 | | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
180 | | PORT_Assert(0); |
181 | | } |
182 | | #endif |
183 | | |
184 | | SHA256Context * |
185 | | SHA256_NewContext(void) |
186 | 136 | { |
187 | 136 | SHA256Context *ctx = PORT_New(SHA256Context); |
188 | 136 | return ctx; |
189 | 136 | } |
190 | | |
191 | | void |
192 | | SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit) |
193 | 136 | { |
194 | 136 | memset(ctx, 0, sizeof *ctx); |
195 | 136 | if (freeit) { |
196 | 136 | PORT_Free(ctx); |
197 | 136 | } |
198 | 136 | } |
199 | | |
200 | | void |
201 | | SHA256_Begin(SHA256Context *ctx) |
202 | 1.98k | { |
203 | 1.98k | PRBool use_hw_sha2 = PR_FALSE; |
204 | | |
205 | 1.98k | memset(ctx, 0, sizeof *ctx); |
206 | 1.98k | memcpy(H, H256, sizeof H256); |
207 | | |
208 | 1.98k | #if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN) |
209 | | /* arm's implementation is tested on little endian only */ |
210 | 1.98k | use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support()); |
211 | 1.98k | #endif |
212 | | |
213 | 1.98k | if (use_hw_sha2) { |
214 | 1.98k | ctx->compress = SHA256_Compress_Native; |
215 | 1.98k | ctx->update = SHA256_Update_Native; |
216 | 1.98k | } else { |
217 | 0 | ctx->compress = SHA256_Compress_Generic; |
218 | 0 | ctx->update = SHA256_Update_Generic; |
219 | 0 | } |
220 | 1.98k | } |
221 | | |
222 | | #if defined(USE_PPC_CRYPTO) |
223 | | |
224 | | #define ROUND(n, a, b, c, d, e, f, g, h) \ |
225 | | s0 = __builtin_crypto_vshasigmaw(e, 1, 0xf); \ |
226 | | h += s0 + vec_sel(g, f, e) + w[n / 4]; \ |
227 | | d += h; \ |
228 | | s0 = __builtin_crypto_vshasigmaw(a, 1, 0); \ |
229 | | h += s0 + vec_sel(b, c, vec_xor(a, b)); \ |
230 | | if (n % 4 != 3) \ |
231 | | w[n / 4] = vec_sro(w[n / 4], rshift); |
232 | | |
233 | | #else |
234 | | |
235 | | #define ROUND(n, a, b, c, d, e, f, g, h) \ |
236 | 0 | h += S1(e) + Ch(e, f, g) + K256[n] + W[n]; \ |
237 | 0 | d += h; \ |
238 | 0 | h += S0(a) + Maj(a, b, c); |
239 | | |
240 | | #endif |
241 | | |
242 | | #define SHA256_UNROLLED_ROUNDS \ |
243 | 0 | ROUND(0, a, b, c, d, e, f, g, h) \ |
244 | 0 | ROUND(1, h, a, b, c, d, e, f, g) \ |
245 | 0 | ROUND(2, g, h, a, b, c, d, e, f) \ |
246 | 0 | ROUND(3, f, g, h, a, b, c, d, e) \ |
247 | 0 | ROUND(4, e, f, g, h, a, b, c, d) \ |
248 | 0 | ROUND(5, d, e, f, g, h, a, b, c) \ |
249 | 0 | ROUND(6, c, d, e, f, g, h, a, b) \ |
250 | 0 | ROUND(7, b, c, d, e, f, g, h, a) \ |
251 | 0 | \ |
252 | 0 | ROUND(8, a, b, c, d, e, f, g, h) \ |
253 | 0 | ROUND(9, h, a, b, c, d, e, f, g) \ |
254 | 0 | ROUND(10, g, h, a, b, c, d, e, f) \ |
255 | 0 | ROUND(11, f, g, h, a, b, c, d, e) \ |
256 | 0 | ROUND(12, e, f, g, h, a, b, c, d) \ |
257 | 0 | ROUND(13, d, e, f, g, h, a, b, c) \ |
258 | 0 | ROUND(14, c, d, e, f, g, h, a, b) \ |
259 | 0 | ROUND(15, b, c, d, e, f, g, h, a) \ |
260 | 0 | \ |
261 | 0 | ROUND(16, a, b, c, d, e, f, g, h) \ |
262 | 0 | ROUND(17, h, a, b, c, d, e, f, g) \ |
263 | 0 | ROUND(18, g, h, a, b, c, d, e, f) \ |
264 | 0 | ROUND(19, f, g, h, a, b, c, d, e) \ |
265 | 0 | ROUND(20, e, f, g, h, a, b, c, d) \ |
266 | 0 | ROUND(21, d, e, f, g, h, a, b, c) \ |
267 | 0 | ROUND(22, c, d, e, f, g, h, a, b) \ |
268 | 0 | ROUND(23, b, c, d, e, f, g, h, a) \ |
269 | 0 | \ |
270 | 0 | ROUND(24, a, b, c, d, e, f, g, h) \ |
271 | 0 | ROUND(25, h, a, b, c, d, e, f, g) \ |
272 | 0 | ROUND(26, g, h, a, b, c, d, e, f) \ |
273 | 0 | ROUND(27, f, g, h, a, b, c, d, e) \ |
274 | 0 | ROUND(28, e, f, g, h, a, b, c, d) \ |
275 | 0 | ROUND(29, d, e, f, g, h, a, b, c) \ |
276 | 0 | ROUND(30, c, d, e, f, g, h, a, b) \ |
277 | 0 | ROUND(31, b, c, d, e, f, g, h, a) \ |
278 | 0 | \ |
279 | 0 | ROUND(32, a, b, c, d, e, f, g, h) \ |
280 | 0 | ROUND(33, h, a, b, c, d, e, f, g) \ |
281 | 0 | ROUND(34, g, h, a, b, c, d, e, f) \ |
282 | 0 | ROUND(35, f, g, h, a, b, c, d, e) \ |
283 | 0 | ROUND(36, e, f, g, h, a, b, c, d) \ |
284 | 0 | ROUND(37, d, e, f, g, h, a, b, c) \ |
285 | 0 | ROUND(38, c, d, e, f, g, h, a, b) \ |
286 | 0 | ROUND(39, b, c, d, e, f, g, h, a) \ |
287 | 0 | \ |
288 | 0 | ROUND(40, a, b, c, d, e, f, g, h) \ |
289 | 0 | ROUND(41, h, a, b, c, d, e, f, g) \ |
290 | 0 | ROUND(42, g, h, a, b, c, d, e, f) \ |
291 | 0 | ROUND(43, f, g, h, a, b, c, d, e) \ |
292 | 0 | ROUND(44, e, f, g, h, a, b, c, d) \ |
293 | 0 | ROUND(45, d, e, f, g, h, a, b, c) \ |
294 | 0 | ROUND(46, c, d, e, f, g, h, a, b) \ |
295 | 0 | ROUND(47, b, c, d, e, f, g, h, a) \ |
296 | 0 | \ |
297 | 0 | ROUND(48, a, b, c, d, e, f, g, h) \ |
298 | 0 | ROUND(49, h, a, b, c, d, e, f, g) \ |
299 | 0 | ROUND(50, g, h, a, b, c, d, e, f) \ |
300 | 0 | ROUND(51, f, g, h, a, b, c, d, e) \ |
301 | 0 | ROUND(52, e, f, g, h, a, b, c, d) \ |
302 | 0 | ROUND(53, d, e, f, g, h, a, b, c) \ |
303 | 0 | ROUND(54, c, d, e, f, g, h, a, b) \ |
304 | 0 | ROUND(55, b, c, d, e, f, g, h, a) \ |
305 | 0 | \ |
306 | 0 | ROUND(56, a, b, c, d, e, f, g, h) \ |
307 | 0 | ROUND(57, h, a, b, c, d, e, f, g) \ |
308 | 0 | ROUND(58, g, h, a, b, c, d, e, f) \ |
309 | 0 | ROUND(59, f, g, h, a, b, c, d, e) \ |
310 | 0 | ROUND(60, e, f, g, h, a, b, c, d) \ |
311 | 0 | ROUND(61, d, e, f, g, h, a, b, c) \ |
312 | 0 | ROUND(62, c, d, e, f, g, h, a, b) \ |
313 | 0 | ROUND(63, b, c, d, e, f, g, h, a) |
314 | | |
315 | | static void |
316 | | SHA256_Compress_Generic(SHA256Context *ctx) |
317 | 0 | { |
318 | | #if defined(USE_PPC_CRYPTO) |
319 | | vec_u32 w[16], s0, s1; |
320 | | const vec_u8 rshift = (vec_u8)vec_splats(4 << 3); |
321 | | const vec_u8 shifthalf = (vec_u8)vec_splats(8 << 3); |
322 | | const vec_u8 bswap4 = (vec_u8){ |
323 | | 3, 2, 1, 0, 7, 6, 5, 4, 11, |
324 | | 10, 9, 8, 15, 14, 13, 12 |
325 | | }; |
326 | | unsigned i; |
327 | | |
328 | | for (i = 0; i < 4; i++) { |
329 | | w[i] = vec_vsx_ld(0, &W[i * 4]); |
330 | | w[i] = vec_perm(w[i], w[i], bswap4); |
331 | | } |
332 | | |
333 | | /* prepare the message schedule */ |
334 | | for (i = 4; i < 16; i++) { |
335 | | vec_u32 off1 = vec_sld(w[i - 3], w[i - 4], 12); |
336 | | vec_u32 off2 = vec_sld(w[i - 1], w[i - 2], 12); |
337 | | s0 = __builtin_crypto_vshasigmaw(off1, 0, 0); |
338 | | /* first half, s1 depends on two prior ints */ |
339 | | s1 = __builtin_crypto_vshasigmaw(w[i - 1], 0, 0xf); |
340 | | s1 = vec_sro(s1, shifthalf); |
341 | | w[i] = w[i - 4] + s0 + off2 + s1; |
342 | | |
343 | | /* second half s1 */ |
344 | | s1 = __builtin_crypto_vshasigmaw(w[i], 0, 0xf); |
345 | | s1 = vec_slo(s1, shifthalf); |
346 | | w[i] += s1; |
347 | | } |
348 | | |
349 | | for (i = 0; i < 16; i++) { |
350 | | w[i] += vec_ld(0, &K256[i * 4]); |
351 | | } |
352 | | |
353 | | vec_u32 a, b, c, d, e, f, g, h; |
354 | | a = vec_splats(H[0]); |
355 | | b = vec_splats(H[1]); |
356 | | c = vec_splats(H[2]); |
357 | | d = vec_splats(H[3]); |
358 | | e = vec_splats(H[4]); |
359 | | f = vec_splats(H[5]); |
360 | | g = vec_splats(H[6]); |
361 | | h = vec_splats(H[7]); |
362 | | |
363 | | SHA256_UNROLLED_ROUNDS; |
364 | | |
365 | | H[0] += a[0]; |
366 | | H[1] += b[0]; |
367 | | H[2] += c[0]; |
368 | | H[3] += d[0]; |
369 | | H[4] += e[0]; |
370 | | H[5] += f[0]; |
371 | | H[6] += g[0]; |
372 | | H[7] += h[0]; |
373 | | |
374 | | #undef ROUND |
375 | | |
376 | | #else /* USE_PPC_CRYPTO*/ |
377 | |
|
378 | 0 | { |
379 | 0 | #if defined(IS_LITTLE_ENDIAN) |
380 | 0 | BYTESWAP4(W[0]); |
381 | 0 | BYTESWAP4(W[1]); |
382 | 0 | BYTESWAP4(W[2]); |
383 | 0 | BYTESWAP4(W[3]); |
384 | 0 | BYTESWAP4(W[4]); |
385 | 0 | BYTESWAP4(W[5]); |
386 | 0 | BYTESWAP4(W[6]); |
387 | 0 | BYTESWAP4(W[7]); |
388 | 0 | BYTESWAP4(W[8]); |
389 | 0 | BYTESWAP4(W[9]); |
390 | 0 | BYTESWAP4(W[10]); |
391 | 0 | BYTESWAP4(W[11]); |
392 | 0 | BYTESWAP4(W[12]); |
393 | 0 | BYTESWAP4(W[13]); |
394 | 0 | BYTESWAP4(W[14]); |
395 | 0 | BYTESWAP4(W[15]); |
396 | 0 | #endif |
397 | |
|
398 | 0 | #define INITW(t) W[t] = (s1(W[t - 2]) + W[t - 7] + s0(W[t - 15]) + W[t - 16]) |
399 | | |
400 | | /* prepare the "message schedule" */ |
401 | | #ifdef NOUNROLL256 |
402 | | { |
403 | | int t; |
404 | | for (t = 16; t < 64; ++t) { |
405 | | INITW(t); |
406 | | } |
407 | | } |
408 | | #else |
409 | 0 | INITW(16); |
410 | 0 | INITW(17); |
411 | 0 | INITW(18); |
412 | 0 | INITW(19); |
413 | |
|
414 | 0 | INITW(20); |
415 | 0 | INITW(21); |
416 | 0 | INITW(22); |
417 | 0 | INITW(23); |
418 | 0 | INITW(24); |
419 | 0 | INITW(25); |
420 | 0 | INITW(26); |
421 | 0 | INITW(27); |
422 | 0 | INITW(28); |
423 | 0 | INITW(29); |
424 | |
|
425 | 0 | INITW(30); |
426 | 0 | INITW(31); |
427 | 0 | INITW(32); |
428 | 0 | INITW(33); |
429 | 0 | INITW(34); |
430 | 0 | INITW(35); |
431 | 0 | INITW(36); |
432 | 0 | INITW(37); |
433 | 0 | INITW(38); |
434 | 0 | INITW(39); |
435 | |
|
436 | 0 | INITW(40); |
437 | 0 | INITW(41); |
438 | 0 | INITW(42); |
439 | 0 | INITW(43); |
440 | 0 | INITW(44); |
441 | 0 | INITW(45); |
442 | 0 | INITW(46); |
443 | 0 | INITW(47); |
444 | 0 | INITW(48); |
445 | 0 | INITW(49); |
446 | |
|
447 | 0 | INITW(50); |
448 | 0 | INITW(51); |
449 | 0 | INITW(52); |
450 | 0 | INITW(53); |
451 | 0 | INITW(54); |
452 | 0 | INITW(55); |
453 | 0 | INITW(56); |
454 | 0 | INITW(57); |
455 | 0 | INITW(58); |
456 | 0 | INITW(59); |
457 | |
|
458 | 0 | INITW(60); |
459 | 0 | INITW(61); |
460 | 0 | INITW(62); |
461 | 0 | INITW(63); |
462 | |
|
463 | 0 | #endif |
464 | 0 | #undef INITW |
465 | 0 | } |
466 | 0 | { |
467 | 0 | PRUint32 a, b, c, d, e, f, g, h; |
468 | |
|
469 | 0 | a = H[0]; |
470 | 0 | b = H[1]; |
471 | 0 | c = H[2]; |
472 | 0 | d = H[3]; |
473 | 0 | e = H[4]; |
474 | 0 | f = H[5]; |
475 | 0 | g = H[6]; |
476 | 0 | h = H[7]; |
477 | |
|
478 | | #ifdef NOUNROLL256 |
479 | | { |
480 | | int t; |
481 | | for (t = 0; t < 64; t += 8) { |
482 | | ROUND(t + 0, a, b, c, d, e, f, g, h) |
483 | | ROUND(t + 1, h, a, b, c, d, e, f, g) |
484 | | ROUND(t + 2, g, h, a, b, c, d, e, f) |
485 | | ROUND(t + 3, f, g, h, a, b, c, d, e) |
486 | | ROUND(t + 4, e, f, g, h, a, b, c, d) |
487 | | ROUND(t + 5, d, e, f, g, h, a, b, c) |
488 | | ROUND(t + 6, c, d, e, f, g, h, a, b) |
489 | | ROUND(t + 7, b, c, d, e, f, g, h, a) |
490 | | } |
491 | | } |
492 | | #else |
493 | 0 | SHA256_UNROLLED_ROUNDS; |
494 | 0 | #endif |
495 | |
|
496 | 0 | H[0] += a; |
497 | 0 | H[1] += b; |
498 | 0 | H[2] += c; |
499 | 0 | H[3] += d; |
500 | 0 | H[4] += e; |
501 | 0 | H[5] += f; |
502 | 0 | H[6] += g; |
503 | 0 | H[7] += h; |
504 | 0 | } |
505 | 0 | #undef ROUND |
506 | 0 | #endif /* !USE_PPC_CRYPTO */ |
507 | 0 | } |
508 | | |
509 | | #undef s0 |
510 | | #undef s1 |
511 | | #undef S0 |
512 | | #undef S1 |
513 | | |
514 | | void |
515 | | SHA256_Update(SHA256Context *ctx, const unsigned char *input, |
516 | | unsigned int inputLen) |
517 | 5.93k | { |
518 | 5.93k | ctx->update(ctx, input, inputLen); |
519 | 5.93k | } |
520 | | |
521 | | static void |
522 | | SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input, |
523 | | unsigned int inputLen) |
524 | 0 | { |
525 | 0 | unsigned int inBuf = ctx->sizeLo & 0x3f; |
526 | 0 | if (!inputLen) |
527 | 0 | return; |
528 | | |
529 | | /* Add inputLen into the count of bytes processed, before processing */ |
530 | 0 | if ((ctx->sizeLo += inputLen) < inputLen) |
531 | 0 | ctx->sizeHi++; |
532 | | |
533 | | /* if data already in buffer, attemp to fill rest of buffer */ |
534 | 0 | if (inBuf) { |
535 | 0 | unsigned int todo = SHA256_BLOCK_LENGTH - inBuf; |
536 | 0 | if (inputLen < todo) |
537 | 0 | todo = inputLen; |
538 | 0 | memcpy(B + inBuf, input, todo); |
539 | 0 | input += todo; |
540 | 0 | inputLen -= todo; |
541 | 0 | if (inBuf + todo == SHA256_BLOCK_LENGTH) |
542 | 0 | SHA256_Compress_Generic(ctx); |
543 | 0 | } |
544 | | |
545 | | /* if enough data to fill one or more whole buffers, process them. */ |
546 | 0 | while (inputLen >= SHA256_BLOCK_LENGTH) { |
547 | 0 | memcpy(B, input, SHA256_BLOCK_LENGTH); |
548 | 0 | input += SHA256_BLOCK_LENGTH; |
549 | 0 | inputLen -= SHA256_BLOCK_LENGTH; |
550 | 0 | SHA256_Compress_Generic(ctx); |
551 | 0 | } |
552 | | /* if data left over, fill it into buffer */ |
553 | 0 | if (inputLen) |
554 | 0 | memcpy(B, input, inputLen); |
555 | 0 | } |
556 | | |
557 | | void |
558 | | SHA256_End(SHA256Context *ctx, unsigned char *digest, |
559 | | unsigned int *digestLen, unsigned int maxDigestLen) |
560 | 2.31k | { |
561 | 2.31k | unsigned int inBuf = ctx->sizeLo & 0x3f; |
562 | 2.31k | unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf); |
563 | 2.31k | PRUint32 hi, lo; |
564 | | |
565 | 2.31k | hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29); |
566 | 2.31k | lo = (ctx->sizeLo << 3); |
567 | | |
568 | 2.31k | ctx->update(ctx, pad, padLen); |
569 | | |
570 | 2.31k | #if defined(IS_LITTLE_ENDIAN) |
571 | 2.31k | W[14] = SHA_HTONL(hi); |
572 | 2.31k | W[15] = SHA_HTONL(lo); |
573 | | #else |
574 | | W[14] = hi; |
575 | | W[15] = lo; |
576 | | #endif |
577 | 2.31k | ctx->compress(ctx); |
578 | | |
579 | | /* now output the answer */ |
580 | 2.31k | #if defined(IS_LITTLE_ENDIAN) |
581 | 2.31k | BYTESWAP4(H[0]); |
582 | 2.31k | BYTESWAP4(H[1]); |
583 | 2.31k | BYTESWAP4(H[2]); |
584 | 2.31k | BYTESWAP4(H[3]); |
585 | 2.31k | BYTESWAP4(H[4]); |
586 | 2.31k | BYTESWAP4(H[5]); |
587 | 2.31k | BYTESWAP4(H[6]); |
588 | 2.31k | BYTESWAP4(H[7]); |
589 | 2.31k | #endif |
590 | 2.31k | padLen = PR_MIN(SHA256_LENGTH, maxDigestLen); |
591 | 2.31k | memcpy(digest, H, padLen); |
592 | 2.31k | if (digestLen) |
593 | 2.31k | *digestLen = padLen; |
594 | 2.31k | } |
595 | | |
596 | | void |
597 | | SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest, |
598 | | unsigned int *digestLen, unsigned int maxDigestLen) |
599 | 0 | { |
600 | 0 | PRUint32 h[8]; |
601 | 0 | unsigned int len; |
602 | |
|
603 | 0 | memcpy(h, ctx->h, sizeof(h)); |
604 | |
|
605 | 0 | #if defined(IS_LITTLE_ENDIAN) |
606 | 0 | BYTESWAP4(h[0]); |
607 | 0 | BYTESWAP4(h[1]); |
608 | 0 | BYTESWAP4(h[2]); |
609 | 0 | BYTESWAP4(h[3]); |
610 | 0 | BYTESWAP4(h[4]); |
611 | 0 | BYTESWAP4(h[5]); |
612 | 0 | BYTESWAP4(h[6]); |
613 | 0 | BYTESWAP4(h[7]); |
614 | 0 | #endif |
615 | |
|
616 | 0 | len = PR_MIN(SHA256_LENGTH, maxDigestLen); |
617 | 0 | memcpy(digest, h, len); |
618 | 0 | if (digestLen) |
619 | 0 | *digestLen = len; |
620 | 0 | } |
621 | | |
622 | | SECStatus |
623 | | SHA256_HashBuf(unsigned char *dest, const unsigned char *src, |
624 | | PRUint32 src_length) |
625 | 4 | { |
626 | 4 | SHA256Context ctx; |
627 | 4 | unsigned int outLen; |
628 | | |
629 | 4 | SHA256_Begin(&ctx); |
630 | 4 | SHA256_Update(&ctx, src, src_length); |
631 | 4 | SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH); |
632 | 4 | memset(&ctx, 0, sizeof ctx); |
633 | | |
634 | 4 | return SECSuccess; |
635 | 4 | } |
636 | | |
637 | | SECStatus |
638 | | SHA256_Hash(unsigned char *dest, const char *src) |
639 | 0 | { |
640 | 0 | return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
641 | 0 | } |
642 | | |
643 | | void |
644 | | SHA256_TraceState(SHA256Context *ctx) |
645 | 0 | { |
646 | 0 | } |
647 | | |
648 | | unsigned int |
649 | | SHA256_FlattenSize(SHA256Context *ctx) |
650 | 25 | { |
651 | 25 | return sizeof *ctx; |
652 | 25 | } |
653 | | |
654 | | SECStatus |
655 | | SHA256_Flatten(SHA256Context *ctx, unsigned char *space) |
656 | 0 | { |
657 | 0 | PORT_Memcpy(space, ctx, sizeof *ctx); |
658 | 0 | return SECSuccess; |
659 | 0 | } |
660 | | |
661 | | SHA256Context * |
662 | | SHA256_Resurrect(unsigned char *space, void *arg) |
663 | 0 | { |
664 | 0 | SHA256Context *ctx = SHA256_NewContext(); |
665 | 0 | if (ctx) |
666 | 0 | PORT_Memcpy(ctx, space, sizeof *ctx); |
667 | 0 | return ctx; |
668 | 0 | } |
669 | | |
670 | | void |
671 | | SHA256_Clone(SHA256Context *dest, SHA256Context *src) |
672 | 0 | { |
673 | 0 | memcpy(dest, src, sizeof *dest); |
674 | 0 | } |
675 | | |
676 | | /* ============= SHA224 implementation ================================== */ |
677 | | |
678 | | /* SHA-224 initial hash values */ |
679 | | static const PRUint32 H224[8] = { |
680 | | 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, |
681 | | 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 |
682 | | }; |
683 | | |
684 | | SHA224Context * |
685 | | SHA224_NewContext(void) |
686 | 64 | { |
687 | 64 | return SHA256_NewContext(); |
688 | 64 | } |
689 | | |
690 | | void |
691 | | SHA224_DestroyContext(SHA224Context *ctx, PRBool freeit) |
692 | 64 | { |
693 | 64 | SHA256_DestroyContext(ctx, freeit); |
694 | 64 | } |
695 | | |
696 | | void |
697 | | SHA224_Begin(SHA224Context *ctx) |
698 | 323 | { |
699 | 323 | PRBool use_hw_sha2; |
700 | | |
701 | 323 | memset(ctx, 0, sizeof *ctx); |
702 | 323 | memcpy(H, H224, sizeof H224); |
703 | | |
704 | 323 | #if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN) |
705 | | /* arm's implementation is tested on little endian only */ |
706 | 323 | use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support()); |
707 | | #else |
708 | | use_hw_sha2 = PR_FALSE; |
709 | | #endif |
710 | | |
711 | 323 | if (use_hw_sha2) { |
712 | 323 | ctx->compress = SHA256_Compress_Native; |
713 | 323 | ctx->update = SHA256_Update_Native; |
714 | 323 | } else { |
715 | 0 | ctx->compress = SHA256_Compress_Generic; |
716 | 0 | ctx->update = SHA256_Update_Generic; |
717 | 0 | } |
718 | 323 | } |
719 | | |
720 | | void |
721 | | SHA224_Update(SHA224Context *ctx, const unsigned char *input, |
722 | | unsigned int inputLen) |
723 | 695 | { |
724 | 695 | ctx->update(ctx, input, inputLen); |
725 | 695 | } |
726 | | |
727 | | void |
728 | | SHA224_End(SHA256Context *ctx, unsigned char *digest, |
729 | | unsigned int *digestLen, unsigned int maxDigestLen) |
730 | 321 | { |
731 | 321 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH); |
732 | 321 | SHA256_End(ctx, digest, digestLen, maxLen); |
733 | 321 | } |
734 | | |
735 | | void |
736 | | SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest, |
737 | | unsigned int *digestLen, unsigned int maxDigestLen) |
738 | 0 | { |
739 | 0 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH); |
740 | 0 | SHA256_EndRaw(ctx, digest, digestLen, maxLen); |
741 | 0 | } |
742 | | |
743 | | SECStatus |
744 | | SHA224_HashBuf(unsigned char *dest, const unsigned char *src, |
745 | | PRUint32 src_length) |
746 | 2 | { |
747 | 2 | SHA256Context ctx; |
748 | 2 | unsigned int outLen; |
749 | | |
750 | 2 | SHA224_Begin(&ctx); |
751 | 2 | SHA256_Update(&ctx, src, src_length); |
752 | 2 | SHA256_End(&ctx, dest, &outLen, SHA224_LENGTH); |
753 | 2 | memset(&ctx, 0, sizeof ctx); |
754 | | |
755 | 2 | return SECSuccess; |
756 | 2 | } |
757 | | |
758 | | SECStatus |
759 | | SHA224_Hash(unsigned char *dest, const char *src) |
760 | 0 | { |
761 | 0 | return SHA224_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
762 | 0 | } |
763 | | |
764 | | void |
765 | | SHA224_TraceState(SHA224Context *ctx) |
766 | 0 | { |
767 | 0 | } |
768 | | |
769 | | unsigned int |
770 | | SHA224_FlattenSize(SHA224Context *ctx) |
771 | 5 | { |
772 | 5 | return SHA256_FlattenSize(ctx); |
773 | 5 | } |
774 | | |
775 | | SECStatus |
776 | | SHA224_Flatten(SHA224Context *ctx, unsigned char *space) |
777 | 0 | { |
778 | 0 | return SHA256_Flatten(ctx, space); |
779 | 0 | } |
780 | | |
781 | | SHA224Context * |
782 | | SHA224_Resurrect(unsigned char *space, void *arg) |
783 | 0 | { |
784 | 0 | return SHA256_Resurrect(space, arg); |
785 | 0 | } |
786 | | |
787 | | void |
788 | | SHA224_Clone(SHA224Context *dest, SHA224Context *src) |
789 | 0 | { |
790 | 0 | SHA256_Clone(dest, src); |
791 | 0 | } |
792 | | |
793 | | /* ======= SHA512 and SHA384 common constants and defines ================= */ |
794 | | |
795 | | /* common #defines for SHA512 and SHA384 */ |
796 | | #if defined(HAVE_LONG_LONG) |
797 | 9.13M | #define S0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39)) |
798 | 9.13M | #define S1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41)) |
799 | 7.30M | #define s0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR(x, 7)) |
800 | 7.30M | #define s1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ SHR(x, 6)) |
801 | | |
802 | | #if PR_BYTES_PER_LONG == 8 |
803 | | #define ULLC(hi, lo) 0x##hi##lo##UL |
804 | | #elif defined(_MSC_VER) |
805 | | #define ULLC(hi, lo) 0x##hi##lo##ui64 |
806 | | #else |
807 | | #define ULLC(hi, lo) 0x##hi##lo##ULL |
808 | | #endif |
809 | | |
810 | 1.87M | #define BYTESWAP8(x) x = FREEBL_HTONLL(x) |
811 | | |
812 | | #else /* no long long */ |
813 | | |
814 | | #if defined(IS_LITTLE_ENDIAN) |
815 | | #define ULLC(hi, lo) \ |
816 | | { \ |
817 | | 0x##lo##U, 0x##hi##U \ |
818 | | } |
819 | | #define FREEBL_HTONLL(x) (BYTESWAP4(x.lo), BYTESWAP4(x.hi), \ |
820 | | x.hi ^= x.lo ^= x.hi ^= x.lo, x) |
821 | | #define BYTESWAP8(x) \ |
822 | | do { \ |
823 | | PRUint32 tmp; \ |
824 | | BYTESWAP4(x.lo); \ |
825 | | BYTESWAP4(x.hi); \ |
826 | | tmp = x.lo; \ |
827 | | x.lo = x.hi; \ |
828 | | x.hi = tmp; \ |
829 | | } while (0) |
830 | | #else |
831 | | #define ULLC(hi, lo) \ |
832 | | { \ |
833 | | 0x##hi##U, 0x##lo##U \ |
834 | | } |
835 | | #endif |
836 | | |
837 | | #endif |
838 | | |
839 | | #if defined(USE_PPC_CRYPTO) |
840 | | void sha512_block_p8(void *ctx, const void *inp, size_t len); |
841 | | |
842 | | #else /* USE_PPC_CRYPTO */ |
843 | | |
844 | | /* SHA-384 and SHA-512 constants, K512. */ |
845 | | static const PRUint64 K512[80] = { |
846 | | #if PR_BYTES_PER_LONG == 8 |
847 | | 0x428a2f98d728ae22UL, 0x7137449123ef65cdUL, |
848 | | 0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL, |
849 | | 0x3956c25bf348b538UL, 0x59f111f1b605d019UL, |
850 | | 0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL, |
851 | | 0xd807aa98a3030242UL, 0x12835b0145706fbeUL, |
852 | | 0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL, |
853 | | 0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL, |
854 | | 0x9bdc06a725c71235UL, 0xc19bf174cf692694UL, |
855 | | 0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL, |
856 | | 0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL, |
857 | | 0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL, |
858 | | 0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL, |
859 | | 0x983e5152ee66dfabUL, 0xa831c66d2db43210UL, |
860 | | 0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL, |
861 | | 0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL, |
862 | | 0x06ca6351e003826fUL, 0x142929670a0e6e70UL, |
863 | | 0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL, |
864 | | 0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL, |
865 | | 0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL, |
866 | | 0x81c2c92e47edaee6UL, 0x92722c851482353bUL, |
867 | | 0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL, |
868 | | 0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL, |
869 | | 0xd192e819d6ef5218UL, 0xd69906245565a910UL, |
870 | | 0xf40e35855771202aUL, 0x106aa07032bbd1b8UL, |
871 | | 0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL, |
872 | | 0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL, |
873 | | 0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL, |
874 | | 0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL, |
875 | | 0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL, |
876 | | 0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL, |
877 | | 0x90befffa23631e28UL, 0xa4506cebde82bde9UL, |
878 | | 0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL, |
879 | | 0xca273eceea26619cUL, 0xd186b8c721c0c207UL, |
880 | | 0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL, |
881 | | 0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL, |
882 | | 0x113f9804bef90daeUL, 0x1b710b35131c471bUL, |
883 | | 0x28db77f523047d84UL, 0x32caab7b40c72493UL, |
884 | | 0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL, |
885 | | 0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL, |
886 | | 0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL |
887 | | #else |
888 | | ULLC(428a2f98, d728ae22), ULLC(71374491, 23ef65cd), |
889 | | ULLC(b5c0fbcf, ec4d3b2f), ULLC(e9b5dba5, 8189dbbc), |
890 | | ULLC(3956c25b, f348b538), ULLC(59f111f1, b605d019), |
891 | | ULLC(923f82a4, af194f9b), ULLC(ab1c5ed5, da6d8118), |
892 | | ULLC(d807aa98, a3030242), ULLC(12835b01, 45706fbe), |
893 | | ULLC(243185be, 4ee4b28c), ULLC(550c7dc3, d5ffb4e2), |
894 | | ULLC(72be5d74, f27b896f), ULLC(80deb1fe, 3b1696b1), |
895 | | ULLC(9bdc06a7, 25c71235), ULLC(c19bf174, cf692694), |
896 | | ULLC(e49b69c1, 9ef14ad2), ULLC(efbe4786, 384f25e3), |
897 | | ULLC(0fc19dc6, 8b8cd5b5), ULLC(240ca1cc, 77ac9c65), |
898 | | ULLC(2de92c6f, 592b0275), ULLC(4a7484aa, 6ea6e483), |
899 | | ULLC(5cb0a9dc, bd41fbd4), ULLC(76f988da, 831153b5), |
900 | | ULLC(983e5152, ee66dfab), ULLC(a831c66d, 2db43210), |
901 | | ULLC(b00327c8, 98fb213f), ULLC(bf597fc7, beef0ee4), |
902 | | ULLC(c6e00bf3, 3da88fc2), ULLC(d5a79147, 930aa725), |
903 | | ULLC(06ca6351, e003826f), ULLC(14292967, 0a0e6e70), |
904 | | ULLC(27b70a85, 46d22ffc), ULLC(2e1b2138, 5c26c926), |
905 | | ULLC(4d2c6dfc, 5ac42aed), ULLC(53380d13, 9d95b3df), |
906 | | ULLC(650a7354, 8baf63de), ULLC(766a0abb, 3c77b2a8), |
907 | | ULLC(81c2c92e, 47edaee6), ULLC(92722c85, 1482353b), |
908 | | ULLC(a2bfe8a1, 4cf10364), ULLC(a81a664b, bc423001), |
909 | | ULLC(c24b8b70, d0f89791), ULLC(c76c51a3, 0654be30), |
910 | | ULLC(d192e819, d6ef5218), ULLC(d6990624, 5565a910), |
911 | | ULLC(f40e3585, 5771202a), ULLC(106aa070, 32bbd1b8), |
912 | | ULLC(19a4c116, b8d2d0c8), ULLC(1e376c08, 5141ab53), |
913 | | ULLC(2748774c, df8eeb99), ULLC(34b0bcb5, e19b48a8), |
914 | | ULLC(391c0cb3, c5c95a63), ULLC(4ed8aa4a, e3418acb), |
915 | | ULLC(5b9cca4f, 7763e373), ULLC(682e6ff3, d6b2b8a3), |
916 | | ULLC(748f82ee, 5defb2fc), ULLC(78a5636f, 43172f60), |
917 | | ULLC(84c87814, a1f0ab72), ULLC(8cc70208, 1a6439ec), |
918 | | ULLC(90befffa, 23631e28), ULLC(a4506ceb, de82bde9), |
919 | | ULLC(bef9a3f7, b2c67915), ULLC(c67178f2, e372532b), |
920 | | ULLC(ca273ece, ea26619c), ULLC(d186b8c7, 21c0c207), |
921 | | ULLC(eada7dd6, cde0eb1e), ULLC(f57d4f7f, ee6ed178), |
922 | | ULLC(06f067aa, 72176fba), ULLC(0a637dc5, a2c898a6), |
923 | | ULLC(113f9804, bef90dae), ULLC(1b710b35, 131c471b), |
924 | | ULLC(28db77f5, 23047d84), ULLC(32caab7b, 40c72493), |
925 | | ULLC(3c9ebe0a, 15c9bebc), ULLC(431d67c4, 9c100d4c), |
926 | | ULLC(4cc5d4be, cb3e42b6), ULLC(597f299c, fc657e2a), |
927 | | ULLC(5fcb6fab, 3ad6faec), ULLC(6c44198c, 4a475817) |
928 | | #endif |
929 | | }; |
930 | | |
931 | | #endif /* !USE_PPC_CRYPTO */ |
932 | | |
933 | | struct SHA512ContextStr { |
934 | | union { |
935 | | PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */ |
936 | | PRUint32 l[160]; |
937 | | PRUint8 b[640]; |
938 | | } u; |
939 | | PRUint64 h[8]; /* 8 state variables */ |
940 | | PRUint64 sizeLo; /* 64-bit count of hashed bytes. */ |
941 | | }; |
942 | | |
943 | | /* =========== SHA512 implementation ===================================== */ |
944 | | |
945 | | /* SHA-512 initial hash values */ |
946 | | static const PRUint64 H512[8] = { |
947 | | #if PR_BYTES_PER_LONG == 8 |
948 | | 0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL, |
949 | | 0x3c6ef372fe94f82bUL, 0xa54ff53a5f1d36f1UL, |
950 | | 0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL, |
951 | | 0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL |
952 | | #else |
953 | | ULLC(6a09e667, f3bcc908), ULLC(bb67ae85, 84caa73b), |
954 | | ULLC(3c6ef372, fe94f82b), ULLC(a54ff53a, 5f1d36f1), |
955 | | ULLC(510e527f, ade682d1), ULLC(9b05688c, 2b3e6c1f), |
956 | | ULLC(1f83d9ab, fb41bd6b), ULLC(5be0cd19, 137e2179) |
957 | | #endif |
958 | | }; |
959 | | |
960 | | SHA512Context * |
961 | | SHA512_NewContext(void) |
962 | 131 | { |
963 | 131 | SHA512Context *ctx = PORT_New(SHA512Context); |
964 | 131 | return ctx; |
965 | 131 | } |
966 | | |
967 | | void |
968 | | SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit) |
969 | 131 | { |
970 | 131 | memset(ctx, 0, sizeof *ctx); |
971 | 131 | if (freeit) { |
972 | 131 | PORT_Free(ctx); |
973 | 131 | } |
974 | 131 | } |
975 | | |
976 | | void |
977 | | SHA512_Begin(SHA512Context *ctx) |
978 | 2.50k | { |
979 | 2.50k | memset(ctx, 0, sizeof *ctx); |
980 | 2.50k | memcpy(H, H512, sizeof H512); |
981 | 2.50k | } |
982 | | |
983 | | #if defined(SHA512_TRACE) |
984 | | #if defined(HAVE_LONG_LONG) |
985 | | #define DUMP(n, a, d, e, h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \ |
986 | | n, #e, d, #a, h); |
987 | | #else |
988 | | #define DUMP(n, a, d, e, h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \ |
989 | | n, #e, d.hi, d.lo, #a, h.hi, h.lo); |
990 | | #endif |
991 | | #else |
992 | | #define DUMP(n, a, d, e, h) |
993 | | #endif |
994 | | |
995 | | #if defined(HAVE_LONG_LONG) |
996 | | |
997 | 913k | #define ADDTO(x, y) y += x |
998 | | |
999 | 7.30M | #define INITW(t) W[t] = (s1(W[t - 2]) + W[t - 7] + s0(W[t - 15]) + W[t - 16]) |
1000 | | |
1001 | | #define ROUND(n, a, b, c, d, e, f, g, h) \ |
1002 | 9.13M | h += S1(e) + Ch(e, f, g) + K512[n] + W[n]; \ |
1003 | 9.13M | d += h; \ |
1004 | 9.13M | h += S0(a) + Maj(a, b, c); \ |
1005 | 9.13M | DUMP(n, a, d, e, h) |
1006 | | |
1007 | | #else /* use only 32-bit variables, and don't unroll loops */ |
1008 | | |
1009 | | #undef NOUNROLL512 |
1010 | | #define NOUNROLL512 1 |
1011 | | |
1012 | | #define ADDTO(x, y) \ |
1013 | | y.lo += x.lo; \ |
1014 | | y.hi += x.hi + (x.lo > y.lo) |
1015 | | |
1016 | | #define ROTR64a(x, n, lo, hi) (x.lo >> n | x.hi << (32 - n)) |
1017 | | #define ROTR64A(x, n, lo, hi) (x.lo << (64 - n) | x.hi >> (n - 32)) |
1018 | | #define SHR64a(x, n, lo, hi) (x.lo >> n | x.hi << (32 - n)) |
1019 | | |
1020 | | /* Capitol Sigma and lower case sigma functions */ |
1021 | | #define s0lo(x) (ROTR64a(x, 1, lo, hi) ^ ROTR64a(x, 8, lo, hi) ^ SHR64a(x, 7, lo, hi)) |
1022 | | #define s0hi(x) (ROTR64a(x, 1, hi, lo) ^ ROTR64a(x, 8, hi, lo) ^ (x.hi >> 7)) |
1023 | | |
1024 | | #define s1lo(x) (ROTR64a(x, 19, lo, hi) ^ ROTR64A(x, 61, lo, hi) ^ SHR64a(x, 6, lo, hi)) |
1025 | | #define s1hi(x) (ROTR64a(x, 19, hi, lo) ^ ROTR64A(x, 61, hi, lo) ^ (x.hi >> 6)) |
1026 | | |
1027 | | #define S0lo(x) (ROTR64a(x, 28, lo, hi) ^ ROTR64A(x, 34, lo, hi) ^ ROTR64A(x, 39, lo, hi)) |
1028 | | #define S0hi(x) (ROTR64a(x, 28, hi, lo) ^ ROTR64A(x, 34, hi, lo) ^ ROTR64A(x, 39, hi, lo)) |
1029 | | |
1030 | | #define S1lo(x) (ROTR64a(x, 14, lo, hi) ^ ROTR64a(x, 18, lo, hi) ^ ROTR64A(x, 41, lo, hi)) |
1031 | | #define S1hi(x) (ROTR64a(x, 14, hi, lo) ^ ROTR64a(x, 18, hi, lo) ^ ROTR64A(x, 41, hi, lo)) |
1032 | | |
1033 | | /* 32-bit versions of Ch and Maj */ |
1034 | | #define Chxx(x, y, z, lo) ((x.lo & y.lo) ^ (~x.lo & z.lo)) |
1035 | | #define Majx(x, y, z, lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo)) |
1036 | | |
1037 | | #define INITW(t) \ |
1038 | | do { \ |
1039 | | PRUint32 lo, tm; \ |
1040 | | PRUint32 cy = 0; \ |
1041 | | lo = s1lo(W[t - 2]); \ |
1042 | | lo += (tm = W[t - 7].lo); \ |
1043 | | if (lo < tm) \ |
1044 | | cy++; \ |
1045 | | lo += (tm = s0lo(W[t - 15])); \ |
1046 | | if (lo < tm) \ |
1047 | | cy++; \ |
1048 | | lo += (tm = W[t - 16].lo); \ |
1049 | | if (lo < tm) \ |
1050 | | cy++; \ |
1051 | | W[t].lo = lo; \ |
1052 | | W[t].hi = cy + s1hi(W[t - 2]) + W[t - 7].hi + s0hi(W[t - 15]) + W[t - 16].hi; \ |
1053 | | } while (0) |
1054 | | |
1055 | | #define ROUND(n, a, b, c, d, e, f, g, h) \ |
1056 | | { \ |
1057 | | PRUint32 lo, tm, cy; \ |
1058 | | lo = S1lo(e); \ |
1059 | | lo += (tm = Chxx(e, f, g, lo)); \ |
1060 | | cy = (lo < tm); \ |
1061 | | lo += (tm = K512[n].lo); \ |
1062 | | if (lo < tm) \ |
1063 | | cy++; \ |
1064 | | lo += (tm = W[n].lo); \ |
1065 | | if (lo < tm) \ |
1066 | | cy++; \ |
1067 | | h.lo += lo; \ |
1068 | | if (h.lo < lo) \ |
1069 | | cy++; \ |
1070 | | h.hi += cy + S1hi(e) + Chxx(e, f, g, hi) + K512[n].hi + W[n].hi; \ |
1071 | | d.lo += h.lo; \ |
1072 | | d.hi += h.hi + (d.lo < h.lo); \ |
1073 | | lo = S0lo(a); \ |
1074 | | lo += (tm = Majx(a, b, c, lo)); \ |
1075 | | cy = (lo < tm); \ |
1076 | | h.lo += lo; \ |
1077 | | if (h.lo < lo) \ |
1078 | | cy++; \ |
1079 | | h.hi += cy + S0hi(a) + Majx(a, b, c, hi); \ |
1080 | | DUMP(n, a, d, e, h) \ |
1081 | | } |
1082 | | #endif |
1083 | | |
1084 | | static void |
1085 | | SHA512_Compress(SHA512Context *ctx) |
1086 | 114k | { |
1087 | | #if defined(USE_PPC_CRYPTO) |
1088 | | sha512_block_p8(&H[0], &W[0], 1); |
1089 | | #else /* USE_PPC_CRYPTO */ |
1090 | | |
1091 | 114k | #if defined(IS_LITTLE_ENDIAN) |
1092 | 114k | { |
1093 | 114k | BYTESWAP8(W[0]); |
1094 | 114k | BYTESWAP8(W[1]); |
1095 | 114k | BYTESWAP8(W[2]); |
1096 | 114k | BYTESWAP8(W[3]); |
1097 | 114k | BYTESWAP8(W[4]); |
1098 | 114k | BYTESWAP8(W[5]); |
1099 | 114k | BYTESWAP8(W[6]); |
1100 | 114k | BYTESWAP8(W[7]); |
1101 | 114k | BYTESWAP8(W[8]); |
1102 | 114k | BYTESWAP8(W[9]); |
1103 | 114k | BYTESWAP8(W[10]); |
1104 | 114k | BYTESWAP8(W[11]); |
1105 | 114k | BYTESWAP8(W[12]); |
1106 | 114k | BYTESWAP8(W[13]); |
1107 | 114k | BYTESWAP8(W[14]); |
1108 | 114k | BYTESWAP8(W[15]); |
1109 | 114k | } |
1110 | 114k | #endif |
1111 | | |
1112 | 114k | { |
1113 | | #ifdef NOUNROLL512 |
1114 | | { |
1115 | | /* prepare the "message schedule" */ |
1116 | | int t; |
1117 | | for (t = 16; t < 80; ++t) { |
1118 | | INITW(t); |
1119 | | } |
1120 | | } |
1121 | | #else |
1122 | 114k | INITW(16); |
1123 | 114k | INITW(17); |
1124 | 114k | INITW(18); |
1125 | 114k | INITW(19); |
1126 | | |
1127 | 114k | INITW(20); |
1128 | 114k | INITW(21); |
1129 | 114k | INITW(22); |
1130 | 114k | INITW(23); |
1131 | 114k | INITW(24); |
1132 | 114k | INITW(25); |
1133 | 114k | INITW(26); |
1134 | 114k | INITW(27); |
1135 | 114k | INITW(28); |
1136 | 114k | INITW(29); |
1137 | | |
1138 | 114k | INITW(30); |
1139 | 114k | INITW(31); |
1140 | 114k | INITW(32); |
1141 | 114k | INITW(33); |
1142 | 114k | INITW(34); |
1143 | 114k | INITW(35); |
1144 | 114k | INITW(36); |
1145 | 114k | INITW(37); |
1146 | 114k | INITW(38); |
1147 | 114k | INITW(39); |
1148 | | |
1149 | 114k | INITW(40); |
1150 | 114k | INITW(41); |
1151 | 114k | INITW(42); |
1152 | 114k | INITW(43); |
1153 | 114k | INITW(44); |
1154 | 114k | INITW(45); |
1155 | 114k | INITW(46); |
1156 | 114k | INITW(47); |
1157 | 114k | INITW(48); |
1158 | 114k | INITW(49); |
1159 | | |
1160 | 114k | INITW(50); |
1161 | 114k | INITW(51); |
1162 | 114k | INITW(52); |
1163 | 114k | INITW(53); |
1164 | 114k | INITW(54); |
1165 | 114k | INITW(55); |
1166 | 114k | INITW(56); |
1167 | 114k | INITW(57); |
1168 | 114k | INITW(58); |
1169 | 114k | INITW(59); |
1170 | | |
1171 | 114k | INITW(60); |
1172 | 114k | INITW(61); |
1173 | 114k | INITW(62); |
1174 | 114k | INITW(63); |
1175 | 114k | INITW(64); |
1176 | 114k | INITW(65); |
1177 | 114k | INITW(66); |
1178 | 114k | INITW(67); |
1179 | 114k | INITW(68); |
1180 | 114k | INITW(69); |
1181 | | |
1182 | 114k | INITW(70); |
1183 | 114k | INITW(71); |
1184 | 114k | INITW(72); |
1185 | 114k | INITW(73); |
1186 | 114k | INITW(74); |
1187 | 114k | INITW(75); |
1188 | 114k | INITW(76); |
1189 | 114k | INITW(77); |
1190 | 114k | INITW(78); |
1191 | 114k | INITW(79); |
1192 | 114k | #endif |
1193 | 114k | } |
1194 | | #ifdef SHA512_TRACE |
1195 | | { |
1196 | | int i; |
1197 | | for (i = 0; i < 80; ++i) { |
1198 | | #ifdef HAVE_LONG_LONG |
1199 | | printf("W[%2d] = %016lx\n", i, W[i]); |
1200 | | #else |
1201 | | printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo); |
1202 | | #endif |
1203 | | } |
1204 | | } |
1205 | | #endif |
1206 | 114k | { |
1207 | 114k | PRUint64 a, b, c, d, e, f, g, h; |
1208 | | |
1209 | 114k | a = H[0]; |
1210 | 114k | b = H[1]; |
1211 | 114k | c = H[2]; |
1212 | 114k | d = H[3]; |
1213 | 114k | e = H[4]; |
1214 | 114k | f = H[5]; |
1215 | 114k | g = H[6]; |
1216 | 114k | h = H[7]; |
1217 | | |
1218 | | #ifdef NOUNROLL512 |
1219 | | { |
1220 | | int t; |
1221 | | for (t = 0; t < 80; t += 8) { |
1222 | | ROUND(t + 0, a, b, c, d, e, f, g, h) |
1223 | | ROUND(t + 1, h, a, b, c, d, e, f, g) |
1224 | | ROUND(t + 2, g, h, a, b, c, d, e, f) |
1225 | | ROUND(t + 3, f, g, h, a, b, c, d, e) |
1226 | | ROUND(t + 4, e, f, g, h, a, b, c, d) |
1227 | | ROUND(t + 5, d, e, f, g, h, a, b, c) |
1228 | | ROUND(t + 6, c, d, e, f, g, h, a, b) |
1229 | | ROUND(t + 7, b, c, d, e, f, g, h, a) |
1230 | | } |
1231 | | } |
1232 | | #else |
1233 | 114k | ROUND(0, a, b, c, d, e, f, g, h) |
1234 | 114k | ROUND(1, h, a, b, c, d, e, f, g) |
1235 | 114k | ROUND(2, g, h, a, b, c, d, e, f) |
1236 | 114k | ROUND(3, f, g, h, a, b, c, d, e) |
1237 | 114k | ROUND(4, e, f, g, h, a, b, c, d) |
1238 | 114k | ROUND(5, d, e, f, g, h, a, b, c) |
1239 | 114k | ROUND(6, c, d, e, f, g, h, a, b) |
1240 | 114k | ROUND(7, b, c, d, e, f, g, h, a) |
1241 | | |
1242 | 114k | ROUND(8, a, b, c, d, e, f, g, h) |
1243 | 114k | ROUND(9, h, a, b, c, d, e, f, g) |
1244 | 114k | ROUND(10, g, h, a, b, c, d, e, f) |
1245 | 114k | ROUND(11, f, g, h, a, b, c, d, e) |
1246 | 114k | ROUND(12, e, f, g, h, a, b, c, d) |
1247 | 114k | ROUND(13, d, e, f, g, h, a, b, c) |
1248 | 114k | ROUND(14, c, d, e, f, g, h, a, b) |
1249 | 114k | ROUND(15, b, c, d, e, f, g, h, a) |
1250 | | |
1251 | 114k | ROUND(16, a, b, c, d, e, f, g, h) |
1252 | 114k | ROUND(17, h, a, b, c, d, e, f, g) |
1253 | 114k | ROUND(18, g, h, a, b, c, d, e, f) |
1254 | 114k | ROUND(19, f, g, h, a, b, c, d, e) |
1255 | 114k | ROUND(20, e, f, g, h, a, b, c, d) |
1256 | 114k | ROUND(21, d, e, f, g, h, a, b, c) |
1257 | 114k | ROUND(22, c, d, e, f, g, h, a, b) |
1258 | 114k | ROUND(23, b, c, d, e, f, g, h, a) |
1259 | | |
1260 | 114k | ROUND(24, a, b, c, d, e, f, g, h) |
1261 | 114k | ROUND(25, h, a, b, c, d, e, f, g) |
1262 | 114k | ROUND(26, g, h, a, b, c, d, e, f) |
1263 | 114k | ROUND(27, f, g, h, a, b, c, d, e) |
1264 | 114k | ROUND(28, e, f, g, h, a, b, c, d) |
1265 | 114k | ROUND(29, d, e, f, g, h, a, b, c) |
1266 | 114k | ROUND(30, c, d, e, f, g, h, a, b) |
1267 | 114k | ROUND(31, b, c, d, e, f, g, h, a) |
1268 | | |
1269 | 114k | ROUND(32, a, b, c, d, e, f, g, h) |
1270 | 114k | ROUND(33, h, a, b, c, d, e, f, g) |
1271 | 114k | ROUND(34, g, h, a, b, c, d, e, f) |
1272 | 114k | ROUND(35, f, g, h, a, b, c, d, e) |
1273 | 114k | ROUND(36, e, f, g, h, a, b, c, d) |
1274 | 114k | ROUND(37, d, e, f, g, h, a, b, c) |
1275 | 114k | ROUND(38, c, d, e, f, g, h, a, b) |
1276 | 114k | ROUND(39, b, c, d, e, f, g, h, a) |
1277 | | |
1278 | 114k | ROUND(40, a, b, c, d, e, f, g, h) |
1279 | 114k | ROUND(41, h, a, b, c, d, e, f, g) |
1280 | 114k | ROUND(42, g, h, a, b, c, d, e, f) |
1281 | 114k | ROUND(43, f, g, h, a, b, c, d, e) |
1282 | 114k | ROUND(44, e, f, g, h, a, b, c, d) |
1283 | 114k | ROUND(45, d, e, f, g, h, a, b, c) |
1284 | 114k | ROUND(46, c, d, e, f, g, h, a, b) |
1285 | 114k | ROUND(47, b, c, d, e, f, g, h, a) |
1286 | | |
1287 | 114k | ROUND(48, a, b, c, d, e, f, g, h) |
1288 | 114k | ROUND(49, h, a, b, c, d, e, f, g) |
1289 | 114k | ROUND(50, g, h, a, b, c, d, e, f) |
1290 | 114k | ROUND(51, f, g, h, a, b, c, d, e) |
1291 | 114k | ROUND(52, e, f, g, h, a, b, c, d) |
1292 | 114k | ROUND(53, d, e, f, g, h, a, b, c) |
1293 | 114k | ROUND(54, c, d, e, f, g, h, a, b) |
1294 | 114k | ROUND(55, b, c, d, e, f, g, h, a) |
1295 | | |
1296 | 114k | ROUND(56, a, b, c, d, e, f, g, h) |
1297 | 114k | ROUND(57, h, a, b, c, d, e, f, g) |
1298 | 114k | ROUND(58, g, h, a, b, c, d, e, f) |
1299 | 114k | ROUND(59, f, g, h, a, b, c, d, e) |
1300 | 114k | ROUND(60, e, f, g, h, a, b, c, d) |
1301 | 114k | ROUND(61, d, e, f, g, h, a, b, c) |
1302 | 114k | ROUND(62, c, d, e, f, g, h, a, b) |
1303 | 114k | ROUND(63, b, c, d, e, f, g, h, a) |
1304 | | |
1305 | 114k | ROUND(64, a, b, c, d, e, f, g, h) |
1306 | 114k | ROUND(65, h, a, b, c, d, e, f, g) |
1307 | 114k | ROUND(66, g, h, a, b, c, d, e, f) |
1308 | 114k | ROUND(67, f, g, h, a, b, c, d, e) |
1309 | 114k | ROUND(68, e, f, g, h, a, b, c, d) |
1310 | 114k | ROUND(69, d, e, f, g, h, a, b, c) |
1311 | 114k | ROUND(70, c, d, e, f, g, h, a, b) |
1312 | 114k | ROUND(71, b, c, d, e, f, g, h, a) |
1313 | | |
1314 | 114k | ROUND(72, a, b, c, d, e, f, g, h) |
1315 | 114k | ROUND(73, h, a, b, c, d, e, f, g) |
1316 | 114k | ROUND(74, g, h, a, b, c, d, e, f) |
1317 | 114k | ROUND(75, f, g, h, a, b, c, d, e) |
1318 | 114k | ROUND(76, e, f, g, h, a, b, c, d) |
1319 | 114k | ROUND(77, d, e, f, g, h, a, b, c) |
1320 | 114k | ROUND(78, c, d, e, f, g, h, a, b) |
1321 | 114k | ROUND(79, b, c, d, e, f, g, h, a) |
1322 | 114k | #endif |
1323 | | |
1324 | 114k | ADDTO(a, H[0]); |
1325 | 114k | ADDTO(b, H[1]); |
1326 | 114k | ADDTO(c, H[2]); |
1327 | 114k | ADDTO(d, H[3]); |
1328 | 114k | ADDTO(e, H[4]); |
1329 | 114k | ADDTO(f, H[5]); |
1330 | 114k | ADDTO(g, H[6]); |
1331 | 114k | ADDTO(h, H[7]); |
1332 | 114k | } |
1333 | | |
1334 | 114k | #endif /* !USE_PPC_CRYPTO */ |
1335 | 114k | } |
1336 | | |
1337 | | void |
1338 | | SHA512_Update(SHA512Context *ctx, const unsigned char *input, |
1339 | | unsigned int inputLen) |
1340 | 22.4k | { |
1341 | 22.4k | unsigned int inBuf; |
1342 | 22.4k | if (!inputLen) |
1343 | 0 | return; |
1344 | | |
1345 | 22.4k | #if defined(HAVE_LONG_LONG) |
1346 | 22.4k | inBuf = (unsigned int)ctx->sizeLo & 0x7f; |
1347 | | /* Add inputLen into the count of bytes processed, before processing */ |
1348 | 22.4k | ctx->sizeLo += inputLen; |
1349 | | #else |
1350 | | inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; |
1351 | | ctx->sizeLo.lo += inputLen; |
1352 | | if (ctx->sizeLo.lo < inputLen) |
1353 | | ctx->sizeLo.hi++; |
1354 | | #endif |
1355 | | |
1356 | | /* if data already in buffer, attemp to fill rest of buffer */ |
1357 | 22.4k | if (inBuf) { |
1358 | 11.2k | unsigned int todo = SHA512_BLOCK_LENGTH - inBuf; |
1359 | 11.2k | if (inputLen < todo) |
1360 | 8.57k | todo = inputLen; |
1361 | 11.2k | memcpy(B + inBuf, input, todo); |
1362 | 11.2k | input += todo; |
1363 | 11.2k | inputLen -= todo; |
1364 | 11.2k | if (inBuf + todo == SHA512_BLOCK_LENGTH) |
1365 | 2.66k | SHA512_Compress(ctx); |
1366 | 11.2k | } |
1367 | | |
1368 | | /* if enough data to fill one or more whole buffers, process them. */ |
1369 | 128k | while (inputLen >= SHA512_BLOCK_LENGTH) { |
1370 | 105k | memcpy(B, input, SHA512_BLOCK_LENGTH); |
1371 | 105k | input += SHA512_BLOCK_LENGTH; |
1372 | 105k | inputLen -= SHA512_BLOCK_LENGTH; |
1373 | 105k | SHA512_Compress(ctx); |
1374 | 105k | } |
1375 | | /* if data left over, fill it into buffer */ |
1376 | 22.4k | if (inputLen) |
1377 | 8.30k | memcpy(B, input, inputLen); |
1378 | 22.4k | } |
1379 | | |
1380 | | void |
1381 | | SHA512_End(SHA512Context *ctx, unsigned char *digest, |
1382 | | unsigned int *digestLen, unsigned int maxDigestLen) |
1383 | 5.64k | { |
1384 | 5.64k | #if defined(HAVE_LONG_LONG) |
1385 | 5.64k | unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f; |
1386 | | #else |
1387 | | unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; |
1388 | | #endif |
1389 | 5.64k | unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf); |
1390 | 5.64k | PRUint64 lo; |
1391 | 5.64k | LL_SHL(lo, ctx->sizeLo, 3); |
1392 | | |
1393 | 5.64k | SHA512_Update(ctx, pad, padLen); |
1394 | | |
1395 | 5.64k | #if defined(HAVE_LONG_LONG) |
1396 | 5.64k | W[14] = 0; |
1397 | | #else |
1398 | | W[14].lo = 0; |
1399 | | W[14].hi = 0; |
1400 | | #endif |
1401 | | |
1402 | 5.64k | W[15] = lo; |
1403 | 5.64k | #if defined(IS_LITTLE_ENDIAN) |
1404 | 5.64k | BYTESWAP8(W[15]); |
1405 | 5.64k | #endif |
1406 | 5.64k | SHA512_Compress(ctx); |
1407 | | |
1408 | | /* now output the answer */ |
1409 | 5.64k | #if defined(IS_LITTLE_ENDIAN) |
1410 | 5.64k | BYTESWAP8(H[0]); |
1411 | 5.64k | BYTESWAP8(H[1]); |
1412 | 5.64k | BYTESWAP8(H[2]); |
1413 | 5.64k | BYTESWAP8(H[3]); |
1414 | 5.64k | BYTESWAP8(H[4]); |
1415 | 5.64k | BYTESWAP8(H[5]); |
1416 | 5.64k | BYTESWAP8(H[6]); |
1417 | 5.64k | BYTESWAP8(H[7]); |
1418 | 5.64k | #endif |
1419 | 5.64k | padLen = PR_MIN(SHA512_LENGTH, maxDigestLen); |
1420 | 5.64k | memcpy(digest, H, padLen); |
1421 | 5.64k | if (digestLen) |
1422 | 5.64k | *digestLen = padLen; |
1423 | 5.64k | } |
1424 | | |
1425 | | void |
1426 | | SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest, |
1427 | | unsigned int *digestLen, unsigned int maxDigestLen) |
1428 | 0 | { |
1429 | 0 | PRUint64 h[8]; |
1430 | 0 | unsigned int len; |
1431 | |
|
1432 | 0 | memcpy(h, ctx->h, sizeof(h)); |
1433 | |
|
1434 | 0 | #if defined(IS_LITTLE_ENDIAN) |
1435 | 0 | BYTESWAP8(h[0]); |
1436 | 0 | BYTESWAP8(h[1]); |
1437 | 0 | BYTESWAP8(h[2]); |
1438 | 0 | BYTESWAP8(h[3]); |
1439 | 0 | BYTESWAP8(h[4]); |
1440 | 0 | BYTESWAP8(h[5]); |
1441 | 0 | BYTESWAP8(h[6]); |
1442 | 0 | BYTESWAP8(h[7]); |
1443 | 0 | #endif |
1444 | 0 | len = PR_MIN(SHA512_LENGTH, maxDigestLen); |
1445 | 0 | memcpy(digest, h, len); |
1446 | 0 | if (digestLen) |
1447 | 0 | *digestLen = len; |
1448 | 0 | } |
1449 | | |
1450 | | SECStatus |
1451 | | SHA512_HashBuf(unsigned char *dest, const unsigned char *src, |
1452 | | PRUint32 src_length) |
1453 | 4 | { |
1454 | 4 | SHA512Context ctx; |
1455 | 4 | unsigned int outLen; |
1456 | | |
1457 | 4 | SHA512_Begin(&ctx); |
1458 | 4 | SHA512_Update(&ctx, src, src_length); |
1459 | 4 | SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH); |
1460 | 4 | memset(&ctx, 0, sizeof ctx); |
1461 | | |
1462 | 4 | return SECSuccess; |
1463 | 4 | } |
1464 | | |
1465 | | SECStatus |
1466 | | SHA512_Hash(unsigned char *dest, const char *src) |
1467 | 0 | { |
1468 | 0 | return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
1469 | 0 | } |
1470 | | |
1471 | | void |
1472 | | SHA512_TraceState(SHA512Context *ctx) |
1473 | 0 | { |
1474 | 0 | } |
1475 | | |
1476 | | unsigned int |
1477 | | SHA512_FlattenSize(SHA512Context *ctx) |
1478 | 10 | { |
1479 | 10 | return sizeof *ctx; |
1480 | 10 | } |
1481 | | |
1482 | | SECStatus |
1483 | | SHA512_Flatten(SHA512Context *ctx, unsigned char *space) |
1484 | 0 | { |
1485 | 0 | PORT_Memcpy(space, ctx, sizeof *ctx); |
1486 | 0 | return SECSuccess; |
1487 | 0 | } |
1488 | | |
1489 | | SHA512Context * |
1490 | | SHA512_Resurrect(unsigned char *space, void *arg) |
1491 | 0 | { |
1492 | 0 | SHA512Context *ctx = SHA512_NewContext(); |
1493 | 0 | if (ctx) |
1494 | 0 | PORT_Memcpy(ctx, space, sizeof *ctx); |
1495 | 0 | return ctx; |
1496 | 0 | } |
1497 | | |
1498 | | void |
1499 | | SHA512_Clone(SHA512Context *dest, SHA512Context *src) |
1500 | 0 | { |
1501 | 0 | memcpy(dest, src, sizeof *dest); |
1502 | 0 | } |
1503 | | |
1504 | | /* ======================================================================= */ |
1505 | | /* SHA384 uses a SHA512Context as the real context. |
1506 | | ** The only differences between SHA384 an SHA512 are: |
1507 | | ** a) the intialization values for the context, and |
1508 | | ** b) the number of bytes of data produced as output. |
1509 | | */ |
1510 | | |
1511 | | /* SHA-384 initial hash values */ |
1512 | | static const PRUint64 H384[8] = { |
1513 | | #if PR_BYTES_PER_LONG == 8 |
1514 | | 0xcbbb9d5dc1059ed8UL, 0x629a292a367cd507UL, |
1515 | | 0x9159015a3070dd17UL, 0x152fecd8f70e5939UL, |
1516 | | 0x67332667ffc00b31UL, 0x8eb44a8768581511UL, |
1517 | | 0xdb0c2e0d64f98fa7UL, 0x47b5481dbefa4fa4UL |
1518 | | #else |
1519 | | ULLC(cbbb9d5d, c1059ed8), ULLC(629a292a, 367cd507), |
1520 | | ULLC(9159015a, 3070dd17), ULLC(152fecd8, f70e5939), |
1521 | | ULLC(67332667, ffc00b31), ULLC(8eb44a87, 68581511), |
1522 | | ULLC(db0c2e0d, 64f98fa7), ULLC(47b5481d, befa4fa4) |
1523 | | #endif |
1524 | | }; |
1525 | | |
1526 | | SHA384Context * |
1527 | | SHA384_NewContext(void) |
1528 | 54 | { |
1529 | 54 | return SHA512_NewContext(); |
1530 | 54 | } |
1531 | | |
1532 | | void |
1533 | | SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit) |
1534 | 54 | { |
1535 | 54 | SHA512_DestroyContext(ctx, freeit); |
1536 | 54 | } |
1537 | | |
1538 | | void |
1539 | | SHA384_Begin(SHA384Context *ctx) |
1540 | 3.13k | { |
1541 | 3.13k | memset(ctx, 0, sizeof *ctx); |
1542 | 3.13k | memcpy(H, H384, sizeof H384); |
1543 | 3.13k | } |
1544 | | |
1545 | | void |
1546 | | SHA384_Update(SHA384Context *ctx, const unsigned char *input, |
1547 | | unsigned int inputLen) |
1548 | 9.35k | { |
1549 | 9.35k | SHA512_Update(ctx, input, inputLen); |
1550 | 9.35k | } |
1551 | | |
1552 | | void |
1553 | | SHA384_End(SHA384Context *ctx, unsigned char *digest, |
1554 | | unsigned int *digestLen, unsigned int maxDigestLen) |
1555 | 3.12k | { |
1556 | 3.12k | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH); |
1557 | 3.12k | SHA512_End(ctx, digest, digestLen, maxLen); |
1558 | 3.12k | } |
1559 | | |
1560 | | void |
1561 | | SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest, |
1562 | | unsigned int *digestLen, unsigned int maxDigestLen) |
1563 | 0 | { |
1564 | 0 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH); |
1565 | 0 | SHA512_EndRaw(ctx, digest, digestLen, maxLen); |
1566 | 0 | } |
1567 | | |
1568 | | SECStatus |
1569 | | SHA384_HashBuf(unsigned char *dest, const unsigned char *src, |
1570 | | PRUint32 src_length) |
1571 | 4 | { |
1572 | 4 | SHA512Context ctx; |
1573 | 4 | unsigned int outLen; |
1574 | | |
1575 | 4 | SHA384_Begin(&ctx); |
1576 | 4 | SHA512_Update(&ctx, src, src_length); |
1577 | 4 | SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); |
1578 | 4 | memset(&ctx, 0, sizeof ctx); |
1579 | | |
1580 | 4 | return SECSuccess; |
1581 | 4 | } |
1582 | | |
1583 | | SECStatus |
1584 | | SHA384_Hash(unsigned char *dest, const char *src) |
1585 | 0 | { |
1586 | 0 | return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
1587 | 0 | } |
1588 | | |
1589 | | void |
1590 | | SHA384_TraceState(SHA384Context *ctx) |
1591 | 0 | { |
1592 | 0 | } |
1593 | | |
1594 | | unsigned int |
1595 | | SHA384_FlattenSize(SHA384Context *ctx) |
1596 | 9 | { |
1597 | 9 | return sizeof(SHA384Context); |
1598 | 9 | } |
1599 | | |
1600 | | SECStatus |
1601 | | SHA384_Flatten(SHA384Context *ctx, unsigned char *space) |
1602 | 0 | { |
1603 | 0 | return SHA512_Flatten(ctx, space); |
1604 | 0 | } |
1605 | | |
1606 | | SHA384Context * |
1607 | | SHA384_Resurrect(unsigned char *space, void *arg) |
1608 | 0 | { |
1609 | 0 | return SHA512_Resurrect(space, arg); |
1610 | 0 | } |
1611 | | |
1612 | | void |
1613 | | SHA384_Clone(SHA384Context *dest, SHA384Context *src) |
1614 | 0 | { |
1615 | 0 | memcpy(dest, src, sizeof *dest); |
1616 | 0 | } |
1617 | | |
1618 | | /* ======================================================================= */ |
1619 | | #ifdef SELFTEST |
1620 | | #include <stdio.h> |
1621 | | |
1622 | | static const char abc[] = { "abc" }; |
1623 | | static const char abcdbc[] = { |
1624 | | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" |
1625 | | }; |
1626 | | static const char abcdef[] = { |
1627 | | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
1628 | | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" |
1629 | | }; |
1630 | | |
1631 | | void |
1632 | | dumpHash32(const unsigned char *buf, unsigned int bufLen) |
1633 | | { |
1634 | | unsigned int i; |
1635 | | for (i = 0; i < bufLen; i += 4) { |
1636 | | printf(" %02x%02x%02x%02x", buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); |
1637 | | } |
1638 | | printf("\n"); |
1639 | | } |
1640 | | |
1641 | | void |
1642 | | test256(void) |
1643 | | { |
1644 | | unsigned char outBuf[SHA256_LENGTH]; |
1645 | | |
1646 | | printf("SHA256, input = %s\n", abc); |
1647 | | SHA256_Hash(outBuf, abc); |
1648 | | dumpHash32(outBuf, sizeof outBuf); |
1649 | | |
1650 | | printf("SHA256, input = %s\n", abcdbc); |
1651 | | SHA256_Hash(outBuf, abcdbc); |
1652 | | dumpHash32(outBuf, sizeof outBuf); |
1653 | | } |
1654 | | |
1655 | | void |
1656 | | test224(void) |
1657 | | { |
1658 | | SHA224Context ctx; |
1659 | | unsigned char a1000times[1000]; |
1660 | | unsigned int outLen; |
1661 | | unsigned char outBuf[SHA224_LENGTH]; |
1662 | | int i; |
1663 | | |
1664 | | /* Test Vector 1 */ |
1665 | | printf("SHA224, input = %s\n", abc); |
1666 | | SHA224_Hash(outBuf, abc); |
1667 | | dumpHash32(outBuf, sizeof outBuf); |
1668 | | |
1669 | | /* Test Vector 2 */ |
1670 | | printf("SHA224, input = %s\n", abcdbc); |
1671 | | SHA224_Hash(outBuf, abcdbc); |
1672 | | dumpHash32(outBuf, sizeof outBuf); |
1673 | | |
1674 | | /* Test Vector 3 */ |
1675 | | |
1676 | | /* to hash one million 'a's perform 1000 |
1677 | | * sha224 updates on a buffer with 1000 'a's |
1678 | | */ |
1679 | | memset(a1000times, 'a', 1000); |
1680 | | printf("SHA224, input = %s\n", "a one million times"); |
1681 | | SHA224_Begin(&ctx); |
1682 | | for (i = 0; i < 1000; i++) |
1683 | | SHA224_Update(&ctx, a1000times, 1000); |
1684 | | SHA224_End(&ctx, outBuf, &outLen, SHA224_LENGTH); |
1685 | | dumpHash32(outBuf, sizeof outBuf); |
1686 | | } |
1687 | | |
1688 | | void |
1689 | | dumpHash64(const unsigned char *buf, unsigned int bufLen) |
1690 | | { |
1691 | | unsigned int i; |
1692 | | for (i = 0; i < bufLen; i += 8) { |
1693 | | if (i % 32 == 0) |
1694 | | printf("\n"); |
1695 | | printf(" %02x%02x%02x%02x%02x%02x%02x%02x", |
1696 | | buf[i], buf[i + 1], buf[i + 2], buf[i + 3], |
1697 | | buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); |
1698 | | } |
1699 | | printf("\n"); |
1700 | | } |
1701 | | |
1702 | | void |
1703 | | test512(void) |
1704 | | { |
1705 | | unsigned char outBuf[SHA512_LENGTH]; |
1706 | | |
1707 | | printf("SHA512, input = %s\n", abc); |
1708 | | SHA512_Hash(outBuf, abc); |
1709 | | dumpHash64(outBuf, sizeof outBuf); |
1710 | | |
1711 | | printf("SHA512, input = %s\n", abcdef); |
1712 | | SHA512_Hash(outBuf, abcdef); |
1713 | | dumpHash64(outBuf, sizeof outBuf); |
1714 | | } |
1715 | | |
1716 | | void |
1717 | | time512(void) |
1718 | | { |
1719 | | unsigned char outBuf[SHA512_LENGTH]; |
1720 | | |
1721 | | SHA512_Hash(outBuf, abc); |
1722 | | SHA512_Hash(outBuf, abcdef); |
1723 | | } |
1724 | | |
1725 | | void |
1726 | | test384(void) |
1727 | | { |
1728 | | unsigned char outBuf[SHA384_LENGTH]; |
1729 | | |
1730 | | printf("SHA384, input = %s\n", abc); |
1731 | | SHA384_Hash(outBuf, abc); |
1732 | | dumpHash64(outBuf, sizeof outBuf); |
1733 | | |
1734 | | printf("SHA384, input = %s\n", abcdef); |
1735 | | SHA384_Hash(outBuf, abcdef); |
1736 | | dumpHash64(outBuf, sizeof outBuf); |
1737 | | } |
1738 | | |
1739 | | int |
1740 | | main(int argc, char *argv[], char *envp[]) |
1741 | | { |
1742 | | int i = 1; |
1743 | | if (argc > 1) { |
1744 | | i = atoi(argv[1]); |
1745 | | } |
1746 | | if (i < 2) { |
1747 | | test224(); |
1748 | | test256(); |
1749 | | test384(); |
1750 | | test512(); |
1751 | | } else { |
1752 | | while (i-- > 0) { |
1753 | | time512(); |
1754 | | } |
1755 | | printf("done\n"); |
1756 | | } |
1757 | | return 0; |
1758 | | } |
1759 | | |
1760 | | void * |
1761 | | PORT_Alloc(size_t len) |
1762 | | { |
1763 | | return malloc(len); |
1764 | | } |
1765 | | void |
1766 | | PORT_Free(void *ptr) |
1767 | | { |
1768 | | free(ptr); |
1769 | | } |
1770 | | void |
1771 | | PORT_ZFree(void *ptr, size_t len) |
1772 | | { |
1773 | | memset(ptr, 0, len); |
1774 | | free(ptr); |
1775 | | } |
1776 | | #endif |