1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // Stripped down version of security/nss/lib/freebl/sha512.c
6 // and related headers.
11 #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
16 #define SHA256_BLOCK_LENGTH 64 /* bytes */
18 typedef enum _SECStatus
{
24 /* ============= Common constants and defines ======================= */
30 #define SHR(x,n) (x >> n)
31 #define SHL(x,n) (x << n)
32 #define Ch(x,y,z) ((x & y) ^ (~x & z))
33 #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
34 #define SHA_MIN(a,b) (a < b ? a : b)
36 /* Padding used with all flavors of SHA */
37 static const PRUint8 pad
[240] = {
38 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,
39 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
40 /* compiler will fill the rest in with zeros */
43 /* ============= SHA256 implementation ================================== */
45 /* SHA-256 constants, K256. */
46 static const PRUint32 K256
[64] = {
47 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
48 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
49 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
50 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
51 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
52 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
53 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
54 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
55 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
56 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
57 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
58 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
59 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
60 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
61 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
62 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
65 /* SHA-256 initial hash values */
66 static const PRUint32 H256
[8] = {
67 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
68 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
71 #if (_MSC_VER >= 1300)
73 #pragma intrinsic(_byteswap_ulong)
74 #define SHA_HTONL(x) _byteswap_ulong(x)
75 #define BYTESWAP4(x) x = SHA_HTONL(x)
76 #elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
78 #if (_MSC_VER >= 1200)
79 #define FORCEINLINE __forceinline
81 #define FORCEINLINE __inline
84 #define FASTCALL __fastcall
86 static FORCEINLINE PRUint32 FASTCALL
95 #define SHA_HTONL(x) swap4b(x)
96 #define BYTESWAP4(x) x = SHA_HTONL(x)
98 #elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
99 static __inline__ PRUint32
swap4b(PRUint32 value
)
101 __asm__("bswap %0" : "+r" (value
));
104 #define SHA_HTONL(x) swap4b(x)
105 #define BYTESWAP4(x) x = SHA_HTONL(x)
107 #elif defined(__GNUC__) && (defined(__thumb2__) || \
108 (!defined(__thumb__) && \
109 (defined(__ARM_ARCH_6__) || \
110 defined(__ARM_ARCH_6J__) || \
111 defined(__ARM_ARCH_6K__) || \
112 defined(__ARM_ARCH_6Z__) || \
113 defined(__ARM_ARCH_6ZK__) || \
114 defined(__ARM_ARCH_6T2__) || \
115 defined(__ARM_ARCH_7__) || \
116 defined(__ARM_ARCH_7A__) || \
117 defined(__ARM_ARCH_7R__))))
118 static __inline__ PRUint32
swap4b(PRUint32 value
)
121 __asm__("rev %0, %1" : "=r" (ret
) : "r"(value
));
124 #define SHA_HTONL(x) swap4b(x)
125 #define BYTESWAP4(x) x = SHA_HTONL(x)
128 #define SWAP4MASK 0x00FF00FF
129 #define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
130 ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
131 #define BYTESWAP4(x) x = SHA_HTONL(x)
134 #if defined(_MSC_VER)
135 #pragma intrinsic (_lrotr, _lrotl)
136 #define ROTR32(x,n) _lrotr(x,n)
137 #define ROTL32(x,n) _lrotl(x,n)
139 #define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
140 #define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
143 /* Capitol Sigma and lower case sigma functions */
144 #define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22))
145 #define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25))
146 #define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3))
147 #define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10))
150 SHA256_Begin(SHA256Context
*ctx
)
152 memset(ctx
, 0, sizeof *ctx
);
153 memcpy(H
, H256
, sizeof H256
);
157 SHA256_Compress(SHA256Context
*ctx
)
160 register PRUint32 t1
, t2
;
162 #if defined(IS_LITTLE_ENDIAN)
181 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
183 /* prepare the "message schedule" */
187 for (t
= 16; t
< 64; ++t
) {
250 PRUint32 a
, b
, c
, d
, e
, f
, g
, h
;
261 #define ROUND(n,a,b,c,d,e,f,g,h) \
262 h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
264 h += S0(a) + Maj(a,b,c);
269 for (t
= 0; t
< 64; t
+= 8) {
270 ROUND(t
+0,a
,b
,c
,d
,e
,f
,g
,h
)
271 ROUND(t
+1,h
,a
,b
,c
,d
,e
,f
,g
)
272 ROUND(t
+2,g
,h
,a
,b
,c
,d
,e
,f
)
273 ROUND(t
+3,f
,g
,h
,a
,b
,c
,d
,e
)
274 ROUND(t
+4,e
,f
,g
,h
,a
,b
,c
,d
)
275 ROUND(t
+5,d
,e
,f
,g
,h
,a
,b
,c
)
276 ROUND(t
+6,c
,d
,e
,f
,g
,h
,a
,b
)
277 ROUND(t
+7,b
,c
,d
,e
,f
,g
,h
,a
)
281 ROUND( 0,a
,b
,c
,d
,e
,f
,g
,h
)
282 ROUND( 1,h
,a
,b
,c
,d
,e
,f
,g
)
283 ROUND( 2,g
,h
,a
,b
,c
,d
,e
,f
)
284 ROUND( 3,f
,g
,h
,a
,b
,c
,d
,e
)
285 ROUND( 4,e
,f
,g
,h
,a
,b
,c
,d
)
286 ROUND( 5,d
,e
,f
,g
,h
,a
,b
,c
)
287 ROUND( 6,c
,d
,e
,f
,g
,h
,a
,b
)
288 ROUND( 7,b
,c
,d
,e
,f
,g
,h
,a
)
290 ROUND( 8,a
,b
,c
,d
,e
,f
,g
,h
)
291 ROUND( 9,h
,a
,b
,c
,d
,e
,f
,g
)
292 ROUND(10,g
,h
,a
,b
,c
,d
,e
,f
)
293 ROUND(11,f
,g
,h
,a
,b
,c
,d
,e
)
294 ROUND(12,e
,f
,g
,h
,a
,b
,c
,d
)
295 ROUND(13,d
,e
,f
,g
,h
,a
,b
,c
)
296 ROUND(14,c
,d
,e
,f
,g
,h
,a
,b
)
297 ROUND(15,b
,c
,d
,e
,f
,g
,h
,a
)
299 ROUND(16,a
,b
,c
,d
,e
,f
,g
,h
)
300 ROUND(17,h
,a
,b
,c
,d
,e
,f
,g
)
301 ROUND(18,g
,h
,a
,b
,c
,d
,e
,f
)
302 ROUND(19,f
,g
,h
,a
,b
,c
,d
,e
)
303 ROUND(20,e
,f
,g
,h
,a
,b
,c
,d
)
304 ROUND(21,d
,e
,f
,g
,h
,a
,b
,c
)
305 ROUND(22,c
,d
,e
,f
,g
,h
,a
,b
)
306 ROUND(23,b
,c
,d
,e
,f
,g
,h
,a
)
308 ROUND(24,a
,b
,c
,d
,e
,f
,g
,h
)
309 ROUND(25,h
,a
,b
,c
,d
,e
,f
,g
)
310 ROUND(26,g
,h
,a
,b
,c
,d
,e
,f
)
311 ROUND(27,f
,g
,h
,a
,b
,c
,d
,e
)
312 ROUND(28,e
,f
,g
,h
,a
,b
,c
,d
)
313 ROUND(29,d
,e
,f
,g
,h
,a
,b
,c
)
314 ROUND(30,c
,d
,e
,f
,g
,h
,a
,b
)
315 ROUND(31,b
,c
,d
,e
,f
,g
,h
,a
)
317 ROUND(32,a
,b
,c
,d
,e
,f
,g
,h
)
318 ROUND(33,h
,a
,b
,c
,d
,e
,f
,g
)
319 ROUND(34,g
,h
,a
,b
,c
,d
,e
,f
)
320 ROUND(35,f
,g
,h
,a
,b
,c
,d
,e
)
321 ROUND(36,e
,f
,g
,h
,a
,b
,c
,d
)
322 ROUND(37,d
,e
,f
,g
,h
,a
,b
,c
)
323 ROUND(38,c
,d
,e
,f
,g
,h
,a
,b
)
324 ROUND(39,b
,c
,d
,e
,f
,g
,h
,a
)
326 ROUND(40,a
,b
,c
,d
,e
,f
,g
,h
)
327 ROUND(41,h
,a
,b
,c
,d
,e
,f
,g
)
328 ROUND(42,g
,h
,a
,b
,c
,d
,e
,f
)
329 ROUND(43,f
,g
,h
,a
,b
,c
,d
,e
)
330 ROUND(44,e
,f
,g
,h
,a
,b
,c
,d
)
331 ROUND(45,d
,e
,f
,g
,h
,a
,b
,c
)
332 ROUND(46,c
,d
,e
,f
,g
,h
,a
,b
)
333 ROUND(47,b
,c
,d
,e
,f
,g
,h
,a
)
335 ROUND(48,a
,b
,c
,d
,e
,f
,g
,h
)
336 ROUND(49,h
,a
,b
,c
,d
,e
,f
,g
)
337 ROUND(50,g
,h
,a
,b
,c
,d
,e
,f
)
338 ROUND(51,f
,g
,h
,a
,b
,c
,d
,e
)
339 ROUND(52,e
,f
,g
,h
,a
,b
,c
,d
)
340 ROUND(53,d
,e
,f
,g
,h
,a
,b
,c
)
341 ROUND(54,c
,d
,e
,f
,g
,h
,a
,b
)
342 ROUND(55,b
,c
,d
,e
,f
,g
,h
,a
)
344 ROUND(56,a
,b
,c
,d
,e
,f
,g
,h
)
345 ROUND(57,h
,a
,b
,c
,d
,e
,f
,g
)
346 ROUND(58,g
,h
,a
,b
,c
,d
,e
,f
)
347 ROUND(59,f
,g
,h
,a
,b
,c
,d
,e
)
348 ROUND(60,e
,f
,g
,h
,a
,b
,c
,d
)
349 ROUND(61,d
,e
,f
,g
,h
,a
,b
,c
)
350 ROUND(62,c
,d
,e
,f
,g
,h
,a
,b
)
351 ROUND(63,b
,c
,d
,e
,f
,g
,h
,a
)
372 SHA256_Update(SHA256Context
*ctx
, const unsigned char *input
,
373 unsigned int inputLen
)
375 unsigned int inBuf
= ctx
->sizeLo
& 0x3f;
379 /* Add inputLen into the count of bytes processed, before processing */
380 if ((ctx
->sizeLo
+= inputLen
) < inputLen
)
383 /* if data already in buffer, attemp to fill rest of buffer */
385 unsigned int todo
= SHA256_BLOCK_LENGTH
- inBuf
;
388 memcpy(B
+ inBuf
, input
, todo
);
391 if (inBuf
+ todo
== SHA256_BLOCK_LENGTH
)
392 SHA256_Compress(ctx
);
395 /* if enough data to fill one or more whole buffers, process them. */
396 while (inputLen
>= SHA256_BLOCK_LENGTH
) {
397 memcpy(B
, input
, SHA256_BLOCK_LENGTH
);
398 input
+= SHA256_BLOCK_LENGTH
;
399 inputLen
-= SHA256_BLOCK_LENGTH
;
400 SHA256_Compress(ctx
);
402 /* if data left over, fill it into buffer */
404 memcpy(B
, input
, inputLen
);
408 SHA256_End(SHA256Context
*ctx
, unsigned char *digest
,
409 unsigned int *digestLen
, unsigned int maxDigestLen
)
411 unsigned int inBuf
= ctx
->sizeLo
& 0x3f;
412 unsigned int padLen
= (inBuf
< 56) ? (56 - inBuf
) : (56 + 64 - inBuf
);
418 hi
= (ctx
->sizeHi
<< 3) | (ctx
->sizeLo
>> 29);
419 lo
= (ctx
->sizeLo
<< 3);
421 SHA256_Update(ctx
, pad
, padLen
);
423 #if defined(IS_LITTLE_ENDIAN)
424 W
[14] = SHA_HTONL(hi
);
425 W
[15] = SHA_HTONL(lo
);
430 SHA256_Compress(ctx
);
432 /* now output the answer */
433 #if defined(IS_LITTLE_ENDIAN)
443 padLen
= PR_MIN(SHA256_LENGTH
, maxDigestLen
);
444 memcpy(digest
, H
, padLen
);
450 SHA256_EndRaw(SHA256Context
*ctx
, unsigned char *digest
,
451 unsigned int *digestLen
, unsigned int maxDigestLen
)
459 memcpy(h
, ctx
->h
, sizeof(h
));
461 #if defined(IS_LITTLE_ENDIAN)
472 len
= PR_MIN(SHA256_LENGTH
, maxDigestLen
);
473 memcpy(digest
, h
, len
);
479 SHA256_HashBuf(unsigned char *dest
, const unsigned char *src
,
486 SHA256_Update(&ctx
, src
, src_length
);
487 SHA256_End(&ctx
, dest
, &outLen
, SHA256_LENGTH
);
488 memset(&ctx
, 0, sizeof ctx
);