Bumping gaia.json for 3 gaia revision(s) a=gaia-bump
[gecko.git] / ipc / app / sha256.c
blob951dd35e8e7b5e720037ee13d1479d3ca5864536
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.
8 #include "sha256.h"
9 #include "string.h"
10 #include "prcpucfg.h"
11 #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
12 #define NOUNROLL512 1
13 #undef HAVE_LONG_LONG
14 #endif
16 #define SHA256_BLOCK_LENGTH 64 /* bytes */
18 typedef enum _SECStatus {
19 SECWouldBlock = -2,
20 SECFailure = -1,
21 SECSuccess = 0
22 } SECStatus;
24 /* ============= Common constants and defines ======================= */
26 #define W ctx->u.w
27 #define B ctx->u.b
28 #define H ctx->h
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)
72 #include <stdlib.h>
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)
77 #ifndef FORCEINLINE
78 #if (_MSC_VER >= 1200)
79 #define FORCEINLINE __forceinline
80 #else
81 #define FORCEINLINE __inline
82 #endif
83 #endif
84 #define FASTCALL __fastcall
86 static FORCEINLINE PRUint32 FASTCALL
87 swap4b(PRUint32 dwd)
89 __asm {
90 mov eax,dwd
91 bswap eax
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));
102 return (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)
120 PRUint32 ret;
121 __asm__("rev %0, %1" : "=r" (ret) : "r"(value));
122 return ret;
124 #define SHA_HTONL(x) swap4b(x)
125 #define BYTESWAP4(x) x = SHA_HTONL(x)
127 #else
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)
132 #endif
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)
138 #else
139 #define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
140 #define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
141 #endif
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))
149 void
150 SHA256_Begin(SHA256Context *ctx)
152 memset(ctx, 0, sizeof *ctx);
153 memcpy(H, H256, sizeof H256);
156 static void
157 SHA256_Compress(SHA256Context *ctx)
160 register PRUint32 t1, t2;
162 #if defined(IS_LITTLE_ENDIAN)
163 BYTESWAP4(W[0]);
164 BYTESWAP4(W[1]);
165 BYTESWAP4(W[2]);
166 BYTESWAP4(W[3]);
167 BYTESWAP4(W[4]);
168 BYTESWAP4(W[5]);
169 BYTESWAP4(W[6]);
170 BYTESWAP4(W[7]);
171 BYTESWAP4(W[8]);
172 BYTESWAP4(W[9]);
173 BYTESWAP4(W[10]);
174 BYTESWAP4(W[11]);
175 BYTESWAP4(W[12]);
176 BYTESWAP4(W[13]);
177 BYTESWAP4(W[14]);
178 BYTESWAP4(W[15]);
179 #endif
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" */
184 #ifdef NOUNROLL256
186 int t;
187 for (t = 16; t < 64; ++t) {
188 INITW(t);
191 #else
192 INITW(16);
193 INITW(17);
194 INITW(18);
195 INITW(19);
197 INITW(20);
198 INITW(21);
199 INITW(22);
200 INITW(23);
201 INITW(24);
202 INITW(25);
203 INITW(26);
204 INITW(27);
205 INITW(28);
206 INITW(29);
208 INITW(30);
209 INITW(31);
210 INITW(32);
211 INITW(33);
212 INITW(34);
213 INITW(35);
214 INITW(36);
215 INITW(37);
216 INITW(38);
217 INITW(39);
219 INITW(40);
220 INITW(41);
221 INITW(42);
222 INITW(43);
223 INITW(44);
224 INITW(45);
225 INITW(46);
226 INITW(47);
227 INITW(48);
228 INITW(49);
230 INITW(50);
231 INITW(51);
232 INITW(52);
233 INITW(53);
234 INITW(54);
235 INITW(55);
236 INITW(56);
237 INITW(57);
238 INITW(58);
239 INITW(59);
241 INITW(60);
242 INITW(61);
243 INITW(62);
244 INITW(63);
246 #endif
247 #undef INITW
250 PRUint32 a, b, c, d, e, f, g, h;
252 a = H[0];
253 b = H[1];
254 c = H[2];
255 d = H[3];
256 e = H[4];
257 f = H[5];
258 g = H[6];
259 h = H[7];
261 #define ROUND(n,a,b,c,d,e,f,g,h) \
262 h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
263 d += h; \
264 h += S0(a) + Maj(a,b,c);
266 #ifdef NOUNROLL256
268 int t;
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)
280 #else
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)
352 #endif
354 H[0] += a;
355 H[1] += b;
356 H[2] += c;
357 H[3] += d;
358 H[4] += e;
359 H[5] += f;
360 H[6] += g;
361 H[7] += h;
363 #undef ROUND
366 #undef s0
367 #undef s1
368 #undef S0
369 #undef S1
371 void
372 SHA256_Update(SHA256Context *ctx, const unsigned char *input,
373 unsigned int inputLen)
375 unsigned int inBuf = ctx->sizeLo & 0x3f;
376 if (!inputLen)
377 return;
379 /* Add inputLen into the count of bytes processed, before processing */
380 if ((ctx->sizeLo += inputLen) < inputLen)
381 ctx->sizeHi++;
383 /* if data already in buffer, attemp to fill rest of buffer */
384 if (inBuf) {
385 unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
386 if (inputLen < todo)
387 todo = inputLen;
388 memcpy(B + inBuf, input, todo);
389 input += todo;
390 inputLen -= 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 */
403 if (inputLen)
404 memcpy(B, input, inputLen);
407 void
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);
413 PRUint32 hi, lo;
414 #ifdef SWAP4MASK
415 PRUint32 t1;
416 #endif
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);
426 #else
427 W[14] = hi;
428 W[15] = lo;
429 #endif
430 SHA256_Compress(ctx);
432 /* now output the answer */
433 #if defined(IS_LITTLE_ENDIAN)
434 BYTESWAP4(H[0]);
435 BYTESWAP4(H[1]);
436 BYTESWAP4(H[2]);
437 BYTESWAP4(H[3]);
438 BYTESWAP4(H[4]);
439 BYTESWAP4(H[5]);
440 BYTESWAP4(H[6]);
441 BYTESWAP4(H[7]);
442 #endif
443 padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
444 memcpy(digest, H, padLen);
445 if (digestLen)
446 *digestLen = padLen;
449 void
450 SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
451 unsigned int *digestLen, unsigned int maxDigestLen)
453 PRUint32 h[8];
454 unsigned int len;
455 #ifdef SWAP4MASK
456 PRUint32 t1;
457 #endif
459 memcpy(h, ctx->h, sizeof(h));
461 #if defined(IS_LITTLE_ENDIAN)
462 BYTESWAP4(h[0]);
463 BYTESWAP4(h[1]);
464 BYTESWAP4(h[2]);
465 BYTESWAP4(h[3]);
466 BYTESWAP4(h[4]);
467 BYTESWAP4(h[5]);
468 BYTESWAP4(h[6]);
469 BYTESWAP4(h[7]);
470 #endif
472 len = PR_MIN(SHA256_LENGTH, maxDigestLen);
473 memcpy(digest, h, len);
474 if (digestLen)
475 *digestLen = len;
478 SECStatus
479 SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
480 PRUint32 src_length)
482 SHA256Context ctx;
483 unsigned int outLen;
485 SHA256_Begin(&ctx);
486 SHA256_Update(&ctx, src, src_length);
487 SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
488 memset(&ctx, 0, sizeof ctx);
490 return SECSuccess;