2 * Copyright (C) The Internet Society (2001). All Rights Reserved.
4 * This document and translations of it may be copied and furnished to
5 * others, and derivative works that comment on or otherwise explain it
6 * or assist in its implementation may be prepared, copied, published
7 * and distributed, in whole or in part, without restriction of any
8 * kind, provided that the above copyright notice and this paragraph are
9 * included on all such copies and derivative works. However, this
10 * document itself may not be modified in any way, such as by removing
11 * the copyright notice or references to the Internet Society or other
12 * Internet organizations, except as needed for the purpose of
13 * developing Internet standards in which case the procedures for
14 * copyrights defined in the Internet Standards process must be
15 * followed, or as required to translate it into languages other than
18 * The limited permissions granted above are perpetual and will not be
19 * revoked by the Internet Society or its successors or assigns.
21 * This document and the information contained herein is provided on an
22 * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
23 * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
24 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
25 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
26 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
28 * Copyright (C) 2012, Broadcom Corporation
29 * All Rights Reserved.
31 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
32 * the contents of this file may not be disclosed to third parties, copied
33 * or duplicated in any form, in whole or in part, without the prior
34 * written permission of Broadcom Corporation.
36 * $Id: sha1.c 241182 2011-02-17 21:50:03Z $
45 * This file implements the Secure Hashing Algorithm 1 as
46 * defined in FIPS PUB 180-1 published April 17, 1995.
48 * The SHA-1, produces a 160-bit message digest for a given
49 * data stream. It should take about 2**n steps to find a
50 * message with the same digest as a given message and
51 * 2**(n/2) to find any two messages with the same digest,
52 * when n is the digest size in bits. Therefore, this
53 * algorithm can serve as a means of providing a
54 * "fingerprint" for a message.
57 * SHA-1 is defined in terms of 32-bit "words". This code
58 * uses <stdint.h> (included via "sha1.h" to define 32 and 8
59 * bit unsigned integer types. If your C compiler does not
60 * support 32 bit unsigned integers, this code is not
64 * SHA-1 is designed to work with messages less than 2^64 bits
65 * long. Although SHA-1 allows a message digest to be generated
66 * for messages of any number of bits less than 2^64, this
67 * implementation only works with messages with a length that is
68 * a multiple of the size of an 8-bit character.
72 #include <bcmcrypto/sha1.h>
78 #endif /* BCMDRIVER */
81 * Define the SHA1 circular left shift macro
83 #define SHA1CircularShift(bits, word) \
84 (((word) << (bits)) | ((word) >> (32-(bits))))
86 /* Local Function Prototyptes */
87 static void SHA1PadMessage(SHA1Context
*);
88 static void SHA1ProcessMessageBlock(SHA1Context
*);
94 * This function will initialize the SHA1Context in preparation
95 * for computing a new SHA1 message digest.
99 * The context to reset.
106 BCMROMFN(SHA1Reset
)(SHA1Context
*context
)
112 context
->Length_Low
= 0;
113 context
->Length_High
= 0;
114 context
->Message_Block_Index
= 0;
116 context
->Intermediate_Hash
[0] = 0x67452301;
117 context
->Intermediate_Hash
[1] = 0xEFCDAB89;
118 context
->Intermediate_Hash
[2] = 0x98BADCFE;
119 context
->Intermediate_Hash
[3] = 0x10325476;
120 context
->Intermediate_Hash
[4] = 0xC3D2E1F0;
122 context
->Computed
= 0;
123 context
->Corrupted
= 0;
132 * This function will return the 160-bit message digest into the
133 * Message_Digest array provided by the caller.
134 * NOTE: The first octet of hash is stored in the 0th element,
135 * the last octet of hash in the 19th element.
139 * The context to use to calculate the SHA-1 hash.
140 * Message_Digest: [out]
141 * Where the digest is returned.
148 BCMROMFN(SHA1Result
)(SHA1Context
*context
, uint8 Message_Digest
[SHA1HashSize
])
152 if (!context
|| !Message_Digest
) {
156 if (context
->Corrupted
) {
157 return context
->Corrupted
;
160 if (!context
->Computed
) {
161 SHA1PadMessage(context
);
162 for (i
= 0; i
< 64; ++i
) {
163 /* message may be sensitive, clear it out */
164 context
->Message_Block
[i
] = 0;
166 context
->Length_Low
= 0; /* and clear length */
167 context
->Length_High
= 0;
168 context
->Computed
= 1;
171 for (i
= 0; i
< SHA1HashSize
; ++i
) {
172 Message_Digest
[i
] = context
->Intermediate_Hash
[i
>> 2] >>
173 8 * (3 - (i
& 0x03));
183 * This function accepts an array of octets as the next portion
188 * The SHA context to update
189 * message_array: [in]
190 * An array of characters representing the next portion of
193 * The length of the message in message_array
200 BCMROMFN(SHA1Input
)(SHA1Context
*context
, const uint8
*message_array
, unsigned length
)
206 if (!context
|| !message_array
) {
210 if (context
->Computed
) {
211 context
->Corrupted
= shaStateError
;
212 return shaStateError
;
215 if (context
->Corrupted
) {
216 return context
->Corrupted
;
218 while (length
-- && !context
->Corrupted
) {
219 context
->Message_Block
[context
->Message_Block_Index
++] =
220 (*message_array
& 0xFF);
222 context
->Length_Low
+= 8;
223 if (context
->Length_Low
== 0) {
224 context
->Length_High
++;
225 if (context
->Length_High
== 0) {
226 /* Message is too long */
227 context
->Corrupted
= 1;
231 if (context
->Message_Block_Index
== 64) {
232 SHA1ProcessMessageBlock(context
);
242 * SHA1ProcessMessageBlock
245 * This function will process the next 512 bits of the message
246 * stored in the Message_Block array.
255 * Many of the variable names in this code, especially the
256 * single character names, were used because those were the
257 * names used in the publication.
262 SHA1ProcessMessageBlock(SHA1Context
*context
)
264 const uint32 K
[] = { /* Constants defined in SHA-1 */
270 int t
; /* Loop counter */
271 uint32 temp
; /* Temporary word value */
272 uint32 W
[80]; /* Word sequence */
273 uint32 A
, B
, C
, D
, E
; /* Word buffers */
276 * Initialize the first 16 words in the array W
278 for (t
= 0; t
< 16; t
++) {
279 W
[t
] = context
->Message_Block
[t
* 4] << 24;
280 W
[t
] |= context
->Message_Block
[t
* 4 + 1] << 16;
281 W
[t
] |= context
->Message_Block
[t
* 4 + 2] << 8;
282 W
[t
] |= context
->Message_Block
[t
* 4 + 3];
285 for (t
= 16; t
< 80; t
++) {
286 W
[t
] = SHA1CircularShift(1, W
[t
-3] ^ W
[t
-8] ^ W
[t
-14] ^ W
[t
-16]);
289 A
= context
->Intermediate_Hash
[0];
290 B
= context
->Intermediate_Hash
[1];
291 C
= context
->Intermediate_Hash
[2];
292 D
= context
->Intermediate_Hash
[3];
293 E
= context
->Intermediate_Hash
[4];
295 for (t
= 0; t
< 20; t
++) {
296 temp
= SHA1CircularShift(5, A
) +
297 ((B
& C
) | ((~B
) & D
)) + E
+ W
[t
] + K
[0];
300 C
= SHA1CircularShift(30, B
);
305 for (t
= 20; t
< 40; t
++) {
306 temp
= SHA1CircularShift(5, A
) + (B
^ C
^ D
) + E
+ W
[t
] + K
[1];
309 C
= SHA1CircularShift(30, B
);
314 for (t
= 40; t
< 60; t
++) {
315 temp
= SHA1CircularShift(5, A
) +
316 ((B
& C
) | (B
& D
) | (C
& D
)) + E
+ W
[t
] + K
[2];
319 C
= SHA1CircularShift(30, B
);
324 for (t
= 60; t
< 80; t
++) {
325 temp
= SHA1CircularShift(5, A
) + (B
^ C
^ D
) + E
+ W
[t
] + K
[3];
328 C
= SHA1CircularShift(30, B
);
333 context
->Intermediate_Hash
[0] += A
;
334 context
->Intermediate_Hash
[1] += B
;
335 context
->Intermediate_Hash
[2] += C
;
336 context
->Intermediate_Hash
[3] += D
;
337 context
->Intermediate_Hash
[4] += E
;
339 context
->Message_Block_Index
= 0;
347 * According to the standard, the message must be padded to an even
348 * 512 bits. The first padding bit must be a '1'. The last 64
349 * bits represent the length of the original message. All bits in
350 * between should be 0. This function will pad the message
351 * according to those rules by filling the Message_Block array
352 * accordingly. It will also call the ProcessMessageBlock function
353 * provided appropriately. When it returns, it can be assumed that
354 * the message digest has been computed.
359 * ProcessMessageBlock: [in]
360 * The appropriate SHA*ProcessMessageBlock function
367 SHA1PadMessage(SHA1Context
*context
)
370 * Check to see if the current message block is too small to hold
371 * the initial padding bits and length. If so, we will pad the
372 * block, process it, and then continue padding into a second
375 if (context
->Message_Block_Index
> 55) {
376 context
->Message_Block
[context
->Message_Block_Index
++] = 0x80;
377 while (context
->Message_Block_Index
< 64) {
378 context
->Message_Block
[context
->Message_Block_Index
++] = 0;
381 SHA1ProcessMessageBlock(context
);
383 while (context
->Message_Block_Index
< 56) {
384 context
->Message_Block
[context
->Message_Block_Index
++] = 0;
387 context
->Message_Block
[context
->Message_Block_Index
++] = 0x80;
388 while (context
->Message_Block_Index
< 56) {
389 context
->Message_Block
[context
->Message_Block_Index
++] = 0;
394 * Store the message length as the last 8 octets
396 context
->Message_Block
[56] = (uint8
) (context
->Length_High
>> 24);
397 context
->Message_Block
[57] = (uint8
) (context
->Length_High
>> 16);
398 context
->Message_Block
[58] = (uint8
) (context
->Length_High
>> 8);
399 context
->Message_Block
[59] = (uint8
) (context
->Length_High
);
400 context
->Message_Block
[60] = (uint8
) (context
->Length_Low
>> 24);
401 context
->Message_Block
[61] = (uint8
) (context
->Length_Low
>> 16);
402 context
->Message_Block
[62] = (uint8
) (context
->Length_Low
>> 8);
403 context
->Message_Block
[63] = (uint8
) (context
->Length_Low
);
405 SHA1ProcessMessageBlock(context
);
413 * This file will exercise the SHA-1 code performing the three
414 * tests documented in FIPS PUB 180-1 plus one which calls
415 * SHA1Input with an exact multiple of 512 bits, plus a few
418 * Portability Issues:
426 * Define patterns for testing
429 #define TEST2a "abcdbcdecdefdefgefghfghighijhi"
430 #define TEST2b "jkijkljklmklmnlmnomnopnopq"
431 #define TEST2 TEST2a TEST2b
433 #define TEST4a "01234567012345670123456701234567"
434 #define TEST4b "01234567012345670123456701234567"
435 /* an exact multiple of 512 bits */
436 #define TEST4 TEST4a TEST4b
444 int repeatcount
[4] = { 1, 1, 1000000, 10 };
445 uint8 resultarray
[4][20] =
447 {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
448 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
449 {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
450 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
451 {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
452 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F},
453 {0xDE, 0xA3, 0x56, 0xA2, 0xCD, 0xDD, 0x90, 0xC7, 0xA7, 0xEC,
454 0xED, 0xC5, 0xEB, 0xB5, 0x63, 0x93, 0x4F, 0x46, 0x04, 0x52}
461 int i
, j
, err
, fail
= 0;
462 uint8 Message_Digest
[20];
465 * Perform SHA-1 tests
467 for (j
= 0; j
< 4; ++j
) {
468 printf("\nTest %d: %d, '%s'\n", j
+ 1, repeatcount
[j
], testarray
[j
]);
470 err
= SHA1Reset(&sha
);
472 fprintf(stderr
, "SHA1Reset Error %d.\n", err
);
473 break; /* out of for j loop */
476 for (i
= 0; i
< repeatcount
[j
]; ++i
) {
477 err
= SHA1Input(&sha
,
478 (const unsigned char *) testarray
[j
],
479 strlen(testarray
[j
]));
481 fprintf(stderr
, "SHA1Input Error %d.\n", err
);
482 break; /* out of for i loop */
486 err
= SHA1Result(&sha
, Message_Digest
);
489 "SHA1Result Error %d, could not compute message digest.\n",
493 for (i
= 0; i
< 20; ++i
) {
494 printf("%02X ", Message_Digest
[i
]);
498 printf("Should match:\n");
500 for (i
= 0; i
< 20; ++i
) {
501 printf("%02X ", resultarray
[j
][i
]);
504 if (memcmp(Message_Digest
, resultarray
[j
], 20)) fail
++;
507 /* Test some error returns */
508 err
= SHA1Input(&sha
, (const unsigned char *) testarray
[1], 1);
509 printf("\nError %d. Should be %d.\n", err
, shaStateError
);
510 if (err
!= shaStateError
) fail
++;
513 printf("\nError %d. Should be %d.\n", err
, shaNull
);
514 if (err
!= shaNull
) fail
++;
516 printf("SHA1 test %s\n", fail
? "FAILED" : "PASSED");
519 #endif /* BCMSHA1_TEST */