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.
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 * ====================================================================
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
;
51 c
->md_len
= SHA224_DIGEST_LENGTH
;
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
;
65 c
->md_len
= SHA256_DIGEST_LENGTH
;
69 unsigned char *SHA224(const unsigned char *d
, size_t n
, unsigned char *md
)
72 static unsigned char m
[SHA224_DIGEST_LENGTH
];
78 SHA256_Update(&c
, d
, n
);
84 unsigned char *SHA256(const unsigned char *key
, size_t n
, unsigned char *md
)
87 static unsigned char m
[SHA256_DIGEST_LENGTH
];
93 SHA256_Update(&c
, key
, n
);
100 #define SHA_LONG_LOG2 2 /* default to 32 bits */
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 { \
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)); } \
127 case SHA256_DIGEST_LENGTH: \
128 for (n = 0; n < SHA256_DIGEST_LENGTH/4; n++) \
129 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
132 if ((c)->md_len > SHA256_DIGEST_LENGTH) \
134 for (n = 0; n < (c)->md_len/4; n++) \
135 { ll = (c)->h[n]; HOST_l2c(ll, (s)); } \
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>
152 void sha256_block(SHA256_CTX
*ctx
, const void *in
, size_t num
, int host
);
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
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
;
193 const unsigned char *data
= in
;
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];
201 const SHA_LONG
*W
= (const SHA_LONG
*)data
;
203 for (i
= 0; i
< 16; 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
;
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
;
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)
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
;
261 const unsigned char *data
= in
;
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];
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
;
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
335 HASH_BLOCK_HOST_ORDER(SHA256_CTX
*ctx
, const void *in
, size_t num
)
337 sha256_block(ctx
, in
, num
, 1);
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
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
357 * Portability Issues:
365 * Define patterns for testing
368 #define TEST2a "abcdbcdecdefdefgefghfghighijhi"
369 #define TEST2b "jkijkljklmklmnlmnomnopnopq"
370 #define TEST2 TEST2a TEST2b
373 char *testarray
[3] = {
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}
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
);
422 for (i
= 0; i
< 32; ++i
) {
423 printf("%02X ", Message_Digest
[i
]);
426 printf("Should match:\n");
428 for (i
= 0; i
< 32; ++i
) {
429 printf("%02X ", resultarray
[j
][i
]);
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
++;
441 printf("\nError %d. Should be %d.\n", err
, shaNull
);
442 if (err
!= shaNull
) fail
++;
444 printf("SHA1 test %s\n", fail
? "FAILED" : "PASSED");
447 #endif /* BCMSHA1_TEST */