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