Resync with broadcom drivers 5.100.138.20 and utilities.
[tomato.git] / release / src-rt / bcmcrypto / sha256.c
blobed6c2e9c916e2b8f66d4aa93b75fc09c02569cbb
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) 2010, 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,v 1.2.578.1 2010-05-28 15:25:49 Exp $
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 <stddef.h> /* for size_t */
36 #if defined(__GNUC__)
37 extern void bcopy(const void *src, void *dst, size_t len);
38 extern int bcmp(const void *b1, const void *b2, size_t len);
39 extern void bzero(void *b, size_t len);
40 #else
41 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
42 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
43 #define bzero(b, len) memset((b), 0, (len))
44 #endif
45 #endif /* BCMDRIVER */
47 #include <bcmcrypto/sha256.h>
49 const char *SHA256_version = "SHA-256";
51 int SHA224_Init(SHA256_CTX *c)
53 c->h[0] = 0xc1059ed8UL; c->h[1] = 0x367cd507UL;
54 c->h[2] = 0x3070dd17UL; c->h[3] = 0xf70e5939UL;
55 c->h[4] = 0xffc00b31UL; c->h[5] = 0x68581511UL;
56 c->h[6] = 0x64f98fa7UL; c->h[7] = 0xbefa4fa4UL;
57 c->Nl = 0; c->Nh = 0;
58 c->num = 0; c->md_len = SHA224_DIGEST_LENGTH;
59 return 1;
62 int SHA256_Init(SHA256_CTX *c)
64 c->h[0] = 0x6a09e667UL; c->h[1] = 0xbb67ae85UL;
65 c->h[2] = 0x3c6ef372UL; c->h[3] = 0xa54ff53aUL;
66 c->h[4] = 0x510e527fUL; c->h[5] = 0x9b05688cUL;
67 c->h[6] = 0x1f83d9abUL; c->h[7] = 0x5be0cd19UL;
68 c->Nl = 0; c->Nh = 0;
69 c->num = 0; c->md_len = SHA256_DIGEST_LENGTH;
70 return 1;
73 unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
75 SHA256_CTX c;
76 static unsigned char m[SHA224_DIGEST_LENGTH];
78 if (md == NULL) md = m;
79 SHA224_Init(&c);
80 SHA256_Update(&c, d, n);
81 SHA256_Final(md, &c);
82 return (md);
85 unsigned char *SHA256(const unsigned char *key, size_t n, unsigned char *md)
87 SHA256_CTX c;
88 static unsigned char m[SHA256_DIGEST_LENGTH];
90 if (md == NULL) md = m;
91 SHA256_Init(&c);
92 SHA256_Update(&c, key, n);
93 SHA256_Final(md, &c);
94 return (md);
97 #ifndef SHA_LONG_LOG2
98 #define SHA_LONG_LOG2 2 /* default to 32 bits */
99 #endif
101 #define DATA_ORDER_IS_BIG_ENDIAN
103 #define HASH_LONG SHA_LONG
104 #define HASH_LONG_LOG2 SHA_LONG_LOG2
105 #define HASH_CTX SHA256_CTX
106 #define HASH_CBLOCK SHA_CBLOCK
107 #define HASH_LBLOCK SHA_LBLOCK
109 * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
110 * default: case below covers for it. It's not clear however if it's
111 * permitted to truncate to amount of bytes not divisible by 4. I bet not,
112 * but if it is, then default: case shall be extended. For reference.
113 * Idea behind separate cases for pre-defined lenghts is to let the
114 * compiler decide if it's appropriate to unroll small loops.
116 #define HASH_MAKE_STRING(c, s) do { \
117 unsigned long ll; \
118 unsigned int n; \
119 switch ((c)->md_len) \
120 { case SHA224_DIGEST_LENGTH: \
121 for (n = 0; n < SHA224_DIGEST_LENGTH/4; n++) \
122 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
123 break; \
124 case SHA256_DIGEST_LENGTH: \
125 for (n = 0; n < SHA256_DIGEST_LENGTH/4; n++) \
126 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
127 break; \
128 default: \
129 if ((c)->md_len > SHA256_DIGEST_LENGTH) \
130 return 0; \
131 for (n = 0; n < (c)->md_len/4; n++) \
132 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
133 break; \
135 } while (0)
137 #define HASH_UPDATE SHA256_Update
138 #define HASH_TRANSFORM SHA256_Transform
139 #define HASH_FINAL SHA256_Final
140 #define HASH_BLOCK_HOST_ORDER sha256_block_host_order
141 #define HASH_BLOCK_DATA_ORDER sha256_block_data_order
142 void sha256_block_host_order(SHA256_CTX *ctx, const void *in, size_t num);
143 void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
145 #include <bcmcrypto/md32_common.h>
147 #ifdef SHA256_ASM
148 void sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host);
149 #else
150 static const SHA_LONG K256[64] = {
151 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
152 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
153 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
154 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
155 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
156 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
157 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
158 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
159 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
160 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
161 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
162 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
163 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
164 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
165 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
166 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL };
169 * FIPS specification refers to right rotations, while our ROTATE macro
170 * is left one. This is why you might notice that rotation coefficients
171 * differ from those observed in FIPS document by 32-N...
173 #define Sigma0(x) (ROTATE((x), 30) ^ ROTATE((x), 19) ^ ROTATE((x), 10))
174 #define Sigma1(x) (ROTATE((x), 26) ^ ROTATE((x), 21) ^ ROTATE((x), 7))
175 #define sigma0(x) (ROTATE((x), 25) ^ ROTATE((x), 14) ^ ((x)>>3))
176 #define sigma1(x) (ROTATE((x), 15) ^ ROTATE((x), 13) ^ ((x)>>10))
178 #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
179 #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
181 #ifdef OPENSSL_SMALL_FOOTPRINT
183 static void sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host)
185 unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
186 SHA_LONG X[16];
187 int i;
188 const unsigned char *data = in;
190 while (num--) {
192 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
193 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
195 if (host)
197 const SHA_LONG *W = (const SHA_LONG *)data;
199 for (i = 0; i < 16; i++)
201 T1 = X[i] = W[i];
202 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
203 T2 = Sigma0(a) + Maj(a, b, c);
204 h = g; g = f; f = e; e = d + T1;
205 d = c; c = b; b = a; a = T1 + T2;
208 data += SHA256_CBLOCK;
210 else
212 SHA_LONG l;
214 for (i = 0; i < 16; i++)
216 HOST_c2l(data, l); T1 = X[i] = l;
217 T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
218 T2 = Sigma0(a) + Maj(a, b, c);
219 h = g; g = f; f = e; e = d + T1;
220 d = c; c = b; b = a; a = T1 + T2;
224 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 sha256_block(SHA256_CTX *ctx, const void *in, size_t num, int host)
257 unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
258 SHA_LONG X[16];
259 int i;
260 const unsigned char *data = in;
262 while (num--) {
264 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
265 e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
267 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;
290 else
292 SHA_LONG l;
294 HOST_c2l(data, l); T1 = X[0] = l; ROUND_00_15(0, a, b, c, d, e, f, g, h);
295 HOST_c2l(data, l); T1 = X[1] = l; ROUND_00_15(1, h, a, b, c, d, e, f, g);
296 HOST_c2l(data, l); T1 = X[2] = l; ROUND_00_15(2, g, h, a, b, c, d, e, f);
297 HOST_c2l(data, l); T1 = X[3] = l; ROUND_00_15(3, f, g, h, a, b, c, d, e);
298 HOST_c2l(data, l); T1 = X[4] = l; ROUND_00_15(4, e, f, g, h, a, b, c, d);
299 HOST_c2l(data, l); T1 = X[5] = l; ROUND_00_15(5, d, e, f, g, h, a, b, c);
300 HOST_c2l(data, l); T1 = X[6] = l; ROUND_00_15(6, c, d, e, f, g, h, a, b);
301 HOST_c2l(data, l); T1 = X[7] = l; ROUND_00_15(7, b, c, d, e, f, g, h, a);
302 HOST_c2l(data, l); T1 = X[8] = l; ROUND_00_15(8, a, b, c, d, e, f, g, h);
303 HOST_c2l(data, l); T1 = X[9] = l; ROUND_00_15(9, h, a, b, c, d, e, f, g);
304 HOST_c2l(data, l); T1 = X[10] = l; ROUND_00_15(10, g, h, a, b, c, d, e, f);
305 HOST_c2l(data, l); T1 = X[11] = l; ROUND_00_15(11, f, g, h, a, b, c, d, e);
306 HOST_c2l(data, l); T1 = X[12] = l; ROUND_00_15(12, e, f, g, h, a, b, c, d);
307 HOST_c2l(data, l); T1 = X[13] = l; ROUND_00_15(13, d, e, f, g, h, a, b, c);
308 HOST_c2l(data, l); T1 = X[14] = l; ROUND_00_15(14, c, d, e, f, g, h, a, b);
309 HOST_c2l(data, l); T1 = X[15] = l; ROUND_00_15(15, b, c, d, e, f, g, h, a);
312 for (i = 16; i < 64; i += 8)
314 ROUND_16_63(i+0, a, b, c, d, e, f, g, h, X);
315 ROUND_16_63(i+1, h, a, b, c, d, e, f, g, X);
316 ROUND_16_63(i+2, g, h, a, b, c, d, e, f, X);
317 ROUND_16_63(i+3, f, g, h, a, b, c, d, e, X);
318 ROUND_16_63(i+4, e, f, g, h, a, b, c, d, X);
319 ROUND_16_63(i+5, d, e, f, g, h, a, b, c, X);
320 ROUND_16_63(i+6, c, d, e, f, g, h, a, b, X);
321 ROUND_16_63(i+7, b, c, d, e, f, g, h, a, X);
324 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
325 ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
330 #endif /* OPENSSL_SMALL_FOOTPRINT */
331 #endif /* SHA256_ASM */
334 * Idea is to trade couple of cycles for some space. On IA-32 we save
335 * about 4K in "big footprint" case. In "small footprint" case any gain
336 * is appreciated:-)
338 void HASH_BLOCK_HOST_ORDER(SHA256_CTX *ctx, const void *in, size_t num)
339 { sha256_block(ctx, in, num, 1); }
341 void HASH_BLOCK_DATA_ORDER(SHA256_CTX *ctx, const void *in, size_t num)
342 { sha256_block(ctx, in, num, 0); }
345 #ifdef BCMSHA256_TEST
347 * sha1test.c
349 * Description:
350 * This file will exercise the SHA-256 code performing the three
351 * tests documented in FIPS PUB 180-2 plus one which calls
352 * SHA1Input with an exact multiple of 512 bits, plus a few
353 * error test checks.
355 * Portability Issues:
356 * None.
360 #include <stdio.h>
363 * Define patterns for testing
365 #define TEST1 "abc"
366 #define TEST2a "abcdbcdecdefdefgefghfghighijhi"
367 #define TEST2b "jkijkljklmklmnlmnomnopnopq"
368 #define TEST2 TEST2a TEST2b
369 #define TEST3 "a"
371 char *testarray[3] =
373 TEST1,
374 TEST2,
375 TEST3
379 int repeatcount[3] = { 1, 1, 1000000};
380 unsigned char resultarray[3][32] =
382 {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
383 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
384 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
385 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
387 {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
388 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
389 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
390 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
392 {0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
393 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
394 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
395 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0}
398 int main()
400 SHA256_CTX sha;
401 int i, j, err, fail = 0;
402 unsigned char Message_Digest[32];
405 * Perform SHA-1 tests
407 for (j = 0; j < 3; ++j) {
408 printf("\nTest %d: %d, '%s'\n", j + 1, repeatcount[j], testarray[j]);
410 err = SHA256_Init(&sha);
412 for (i = 0; i < repeatcount[j]; ++i) {
413 err = SHA256_Update(&sha,
414 (const unsigned char *) testarray[j],
415 strlen(testarray[j]));
418 err = SHA256_Final(Message_Digest, &sha);
419 printf("\t");
420 for (i = 0; i < 32; ++i) {
421 printf("%02X ", Message_Digest[i]);
423 printf("\n");
424 printf("Should match:\n");
425 printf("\t");
426 for (i = 0; i < 32; ++i) {
427 printf("%02X ", resultarray[j][i]);
429 printf("\n");
430 if (bcmp(Message_Digest, resultarray[j], 32)) fail++;
432 #ifdef EXTRA_SHA256_TEST
433 /* Test some error returns */
434 err = SHA1Input(&sha, (const unsigned char *) testarray[1], 1);
435 printf("\nError %d. Should be %d.\n", err, shaStateError);
436 if (err != shaStateError) fail++;
438 err = SHA1Reset(0);
439 printf("\nError %d. Should be %d.\n", err, shaNull);
440 if (err != shaNull) fail++;
441 #endif
442 printf("SHA1 test %s\n", fail? "FAILED" : "PASSED");
443 return fail;
445 #endif /* BCMSHA1_TEST */