GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / bcmcrypto / sha256.c
blob8d956154390688f9fe9cfe68597a0f68f8f9d950
1 /* crypto/sha/sha256.c
2 * Code copied from openssl distribution and
3 * Modified just enough so that compiles and runs standalone
5 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * $Id: sha256.c 241182 2011-02-17 21:50:03Z $
21 /* ====================================================================
22 * Copyright (c) 2004 The OpenSSL Project. All rights reserved
23 * according to the OpenSSL license [found in ../../LICENSE].
24 * ====================================================================
26 #ifndef BCMDRIVER
27 #include <stdlib.h>
28 #include <string.h>
29 #endif
31 #include <typedefs.h>
32 #ifdef BCMDRIVER
33 #include <osl.h>
34 #else
35 #include <string.h>
36 #endif /* BCMDRIVER */
38 #include <bcmcrypto/sha256.h>
40 const char *SHA256_version = "SHA-256";
42 int SHA224_Init(SHA256_CTX *c)
44 c->h[0] = 0xc1059ed8UL; c->h[1] = 0x367cd507UL;
45 c->h[2] = 0x3070dd17UL; c->h[3] = 0xf70e5939UL;
46 c->h[4] = 0xffc00b31UL; c->h[5] = 0x68581511UL;
47 c->h[6] = 0x64f98fa7UL; c->h[7] = 0xbefa4fa4UL;
48 c->Nl = 0;
49 c->Nh = 0;
50 c->num = 0;
51 c->md_len = SHA224_DIGEST_LENGTH;
52 return 1;
55 int
56 SHA256_Init(SHA256_CTX *c)
58 c->h[0] = 0x6a09e667UL; c->h[1] = 0xbb67ae85UL;
59 c->h[2] = 0x3c6ef372UL; c->h[3] = 0xa54ff53aUL;
60 c->h[4] = 0x510e527fUL; c->h[5] = 0x9b05688cUL;
61 c->h[6] = 0x1f83d9abUL; c->h[7] = 0x5be0cd19UL;
62 c->Nl = 0;
63 c->Nh = 0;
64 c->num = 0;
65 c->md_len = SHA256_DIGEST_LENGTH;
66 return 1;
69 unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
71 SHA256_CTX c;
72 static unsigned char m[SHA224_DIGEST_LENGTH];
74 if (md == NULL)
75 md = m;
77 SHA224_Init(&c);
78 SHA256_Update(&c, d, n);
79 SHA256_Final(md, &c);
81 return (md);
84 unsigned char *SHA256(const unsigned char *key, size_t n, unsigned char *md)
86 SHA256_CTX c;
87 static unsigned char m[SHA256_DIGEST_LENGTH];
89 if (md == NULL)
90 md = m;
92 SHA256_Init(&c);
93 SHA256_Update(&c, key, n);
94 SHA256_Final(md, &c);
96 return (md);
99 #ifndef SHA_LONG_LOG2
100 #define SHA_LONG_LOG2 2 /* default to 32 bits */
101 #endif
103 #define DATA_ORDER_IS_BIG_ENDIAN
105 #define HASH_LONG SHA_LONG
106 #define HASH_LONG_LOG2 SHA_LONG_LOG2
107 #define HASH_CTX SHA256_CTX
108 #define HASH_CBLOCK SHA_CBLOCK
109 #define HASH_LBLOCK SHA_LBLOCK
112 * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
113 * default: case below covers for it. It's not clear however if it's
114 * permitted to truncate to amount of bytes not divisible by 4. I bet not,
115 * but if it is, then default: case shall be extended. For reference.
116 * Idea behind separate cases for pre-defined lenghts is to let the
117 * compiler decide if it's appropriate to unroll small loops.
119 #define HASH_MAKE_STRING(c, s) do { \
120 unsigned long ll; \
121 unsigned int n; \
122 switch ((c)->md_len) \
123 { case SHA224_DIGEST_LENGTH: \
124 for (n = 0; n < SHA224_DIGEST_LENGTH/4; n++) \
125 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
126 break; \
127 case SHA256_DIGEST_LENGTH: \
128 for (n = 0; n < SHA256_DIGEST_LENGTH/4; n++) \
129 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
130 break; \
131 default: \
132 if ((c)->md_len > SHA256_DIGEST_LENGTH) \
133 return 0; \
134 for (n = 0; n < (c)->md_len/4; n++) \
135 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
136 break; \
138 } while (0)
140 #define HASH_UPDATE SHA256_Update
141 #define HASH_TRANSFORM SHA256_Transform
142 #define HASH_FINAL SHA256_Final
143 #define HASH_BLOCK_HOST_ORDER sha256_block_host_order
144 #define HASH_BLOCK_DATA_ORDER sha256_block_data_order
146 void sha256_block_host_order(SHA256_CTX *ctx, const void *in, size_t num);
147 void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
149 #include <bcmcrypto/md32_common.h>
151 #ifdef SHA256_ASM
152 void sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host);
153 #else
154 static const SHA_LONG K256[64] = {
155 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
156 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
157 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
158 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
159 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
160 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
161 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
162 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
163 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
164 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
165 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
166 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
167 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
168 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
169 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
170 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL };
173 * FIPS specification refers to right rotations, while our ROTATE macro
174 * is left one. This is why you might notice that rotation coefficients
175 * differ from those observed in FIPS document by 32-N...
177 #define Sigma0(x) (ROTATE((x), 30) ^ ROTATE((x), 19) ^ ROTATE((x), 10))
178 #define Sigma1(x) (ROTATE((x), 26) ^ ROTATE((x), 21) ^ ROTATE((x), 7))
179 #define sigma0(x) (ROTATE((x), 25) ^ ROTATE((x), 14) ^ ((x)>>3))
180 #define sigma1(x) (ROTATE((x), 15) ^ ROTATE((x), 13) ^ ((x)>>10))
182 #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
183 #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
185 #ifdef OPENSSL_SMALL_FOOTPRINT
187 static void
188 sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host)
190 unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
191 SHA_LONG X[16];
192 int i;
193 const unsigned char *data = in;
195 while (num--) {
197 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
198 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
200 if (host) {
201 const SHA_LONG *W = (const SHA_LONG *)data;
203 for (i = 0; i < 16; i++)
205 T1 = X[i] = W[i];
206 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
207 T2 = Sigma0(a) + Maj(a, b, c);
208 h = g; g = f; f = e; e = d + T1;
209 d = c; c = b; b = a; a = T1 + T2;
212 data += SHA256_CBLOCK;
213 } else {
214 SHA_LONG l;
216 for (i = 0; i < 16; i++) {
217 HOST_c2l(data, l); T1 = X[i] = l;
218 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
219 T2 = Sigma0(a) + Maj(a, b, c);
220 h = g; g = f; f = e; e = d + T1;
221 d = c; c = b; b = a; a = T1 + T2;
225 for (; i < 64; i++) {
226 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0);
227 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1);
229 T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
230 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
231 T2 = Sigma0(a) + Maj(a, b, c);
232 h = g; g = f; f = e; e = d + T1;
233 d = c; c = b; b = a; a = T1 + T2;
236 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
237 ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
242 #else
244 #define ROUND_00_15(i, a, b, c, d, e, f, g, h) do { \
245 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; \
246 h = Sigma0(a) + Maj(a, b, c); \
247 d += T1; h += T1; } while (0)
249 #define ROUND_16_63(i, a, b, c, d, e, f, g, h, X) do { \
250 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \
251 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \
252 T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \
253 ROUND_00_15(i, a, b, c, d, e, f, g, h); } while (0)
255 static void
256 sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host)
258 unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
259 SHA_LONG X[16];
260 int i;
261 const unsigned char *data = in;
263 while (num--) {
265 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
266 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
268 if (host) {
269 const SHA_LONG *W = (const SHA_LONG *)data;
271 T1 = X[0] = W[0]; ROUND_00_15(0, a, b, c, d, e, f, g, h);
272 T1 = X[1] = W[1]; ROUND_00_15(1, h, a, b, c, d, e, f, g);
273 T1 = X[2] = W[2]; ROUND_00_15(2, g, h, a, b, c, d, e, f);
274 T1 = X[3] = W[3]; ROUND_00_15(3, f, g, h, a, b, c, d, e);
275 T1 = X[4] = W[4]; ROUND_00_15(4, e, f, g, h, a, b, c, d);
276 T1 = X[5] = W[5]; ROUND_00_15(5, d, e, f, g, h, a, b, c);
277 T1 = X[6] = W[6]; ROUND_00_15(6, c, d, e, f, g, h, a, b);
278 T1 = X[7] = W[7]; ROUND_00_15(7, b, c, d, e, f, g, h, a);
279 T1 = X[8] = W[8]; ROUND_00_15(8, a, b, c, d, e, f, g, h);
280 T1 = X[9] = W[9]; ROUND_00_15(9, h, a, b, c, d, e, f, g);
281 T1 = X[10] = W[10]; ROUND_00_15(10, g, h, a, b, c, d, e, f);
282 T1 = X[11] = W[11]; ROUND_00_15(11, f, g, h, a, b, c, d, e);
283 T1 = X[12] = W[12]; ROUND_00_15(12, e, f, g, h, a, b, c, d);
284 T1 = X[13] = W[13]; ROUND_00_15(13, d, e, f, g, h, a, b, c);
285 T1 = X[14] = W[14]; ROUND_00_15(14, c, d, e, f, g, h, a, b);
286 T1 = X[15] = W[15]; ROUND_00_15(15, b, c, d, e, f, g, h, a);
288 data += SHA256_CBLOCK;
289 } else {
290 SHA_LONG l;
292 HOST_c2l(data, l); T1 = X[0] = l; ROUND_00_15(0, a, b, c, d, e, f, g, h);
293 HOST_c2l(data, l); T1 = X[1] = l; ROUND_00_15(1, h, a, b, c, d, e, f, g);
294 HOST_c2l(data, l); T1 = X[2] = l; ROUND_00_15(2, g, h, a, b, c, d, e, f);
295 HOST_c2l(data, l); T1 = X[3] = l; ROUND_00_15(3, f, g, h, a, b, c, d, e);
296 HOST_c2l(data, l); T1 = X[4] = l; ROUND_00_15(4, e, f, g, h, a, b, c, d);
297 HOST_c2l(data, l); T1 = X[5] = l; ROUND_00_15(5, d, e, f, g, h, a, b, c);
298 HOST_c2l(data, l); T1 = X[6] = l; ROUND_00_15(6, c, d, e, f, g, h, a, b);
299 HOST_c2l(data, l); T1 = X[7] = l; ROUND_00_15(7, b, c, d, e, f, g, h, a);
300 HOST_c2l(data, l); T1 = X[8] = l; ROUND_00_15(8, a, b, c, d, e, f, g, h);
301 HOST_c2l(data, l); T1 = X[9] = l; ROUND_00_15(9, h, a, b, c, d, e, f, g);
302 HOST_c2l(data, l); T1 = X[10] = l; ROUND_00_15(10, g, h, a, b, c, d, e, f);
303 HOST_c2l(data, l); T1 = X[11] = l; ROUND_00_15(11, f, g, h, a, b, c, d, e);
304 HOST_c2l(data, l); T1 = X[12] = l; ROUND_00_15(12, e, f, g, h, a, b, c, d);
305 HOST_c2l(data, l); T1 = X[13] = l; ROUND_00_15(13, d, e, f, g, h, a, b, c);
306 HOST_c2l(data, l); T1 = X[14] = l; ROUND_00_15(14, c, d, e, f, g, h, a, b);
307 HOST_c2l(data, l); T1 = X[15] = l; ROUND_00_15(15, b, c, d, e, f, g, h, a);
310 for (i = 16; i < 64; i += 8) {
311 ROUND_16_63(i+0, a, b, c, d, e, f, g, h, X);
312 ROUND_16_63(i+1, h, a, b, c, d, e, f, g, X);
313 ROUND_16_63(i+2, g, h, a, b, c, d, e, f, X);
314 ROUND_16_63(i+3, f, g, h, a, b, c, d, e, X);
315 ROUND_16_63(i+4, e, f, g, h, a, b, c, d, X);
316 ROUND_16_63(i+5, d, e, f, g, h, a, b, c, X);
317 ROUND_16_63(i+6, c, d, e, f, g, h, a, b, X);
318 ROUND_16_63(i+7, b, c, d, e, f, g, h, a, X);
321 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
322 ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
326 #endif /* OPENSSL_SMALL_FOOTPRINT */
327 #endif /* SHA256_ASM */
330 * Idea is to trade couple of cycles for some space. On IA-32 we save
331 * about 4K in "big footprint" case. In "small footprint" case any gain
332 * is appreciated:-)
334 void
335 HASH_BLOCK_HOST_ORDER(SHA256_CTX *ctx, const void *in, size_t num)
337 sha256_block(ctx, in, num, 1);
340 void
341 HASH_BLOCK_DATA_ORDER(SHA256_CTX *ctx, const void *in, size_t num)
343 sha256_block(ctx, in, num, 0);
347 #ifdef BCMSHA256_TEST
349 * sha1test.c
351 * Description:
352 * This file will exercise the SHA-256 code performing the three
353 * tests documented in FIPS PUB 180-2 plus one which calls
354 * SHA1Input with an exact multiple of 512 bits, plus a few
355 * error test checks.
357 * Portability Issues:
358 * None.
362 #include <stdio.h>
365 * Define patterns for testing
367 #define TEST1 "abc"
368 #define TEST2a "abcdbcdecdefdefgefghfghighijhi"
369 #define TEST2b "jkijkljklmklmnlmnomnopnopq"
370 #define TEST2 TEST2a TEST2b
371 #define TEST3 "a"
373 char *testarray[3] = {
374 TEST1,
375 TEST2,
376 TEST3
380 int repeatcount[3] = { 1, 1, 1000000};
381 unsigned char resultarray[3][32] =
383 {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
384 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
385 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
386 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
388 {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
389 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
390 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
391 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
393 {0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
394 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
395 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
396 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0}
400 main()
402 SHA256_CTX sha;
403 int i, j, err, fail = 0;
404 unsigned char Message_Digest[32];
407 * Perform SHA-1 tests
409 for (j = 0; j < 3; ++j) {
410 printf("\nTest %d: %d, '%s'\n", j + 1, repeatcount[j], testarray[j]);
412 err = SHA256_Init(&sha);
414 for (i = 0; i < repeatcount[j]; ++i) {
415 err = SHA256_Update(&sha,
416 (const unsigned char *) testarray[j],
417 strlen(testarray[j]));
420 err = SHA256_Final(Message_Digest, &sha);
421 printf("\t");
422 for (i = 0; i < 32; ++i) {
423 printf("%02X ", Message_Digest[i]);
425 printf("\n");
426 printf("Should match:\n");
427 printf("\t");
428 for (i = 0; i < 32; ++i) {
429 printf("%02X ", resultarray[j][i]);
431 printf("\n");
432 if (memcmp(Message_Digest, resultarray[j], 32)) fail++;
434 #ifdef EXTRA_SHA256_TEST
435 /* Test some error returns */
436 err = SHA1Input(&sha, (const unsigned char *) testarray[1], 1);
437 printf("\nError %d. Should be %d.\n", err, shaStateError);
438 if (err != shaStateError) fail++;
440 err = SHA1Reset(0);
441 printf("\nError %d. Should be %d.\n", err, shaNull);
442 if (err != shaNull) fail++;
443 #endif
444 printf("SHA1 test %s\n", fail? "FAILED" : "PASSED");
445 return fail;
447 #endif /* BCMSHA1_TEST */