sha.c
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:16k
源码类别:

CA认证

开发平台:

C/C++

  1. #pragma ident "@(#)sha.c 1.1 95/11/19 Sun Microsystems"
  2. /* --------------------------------- SHA.C ------------------------------- */
  3. #include <string.h>
  4. #include "sha.h"
  5. /*
  6.  * NIST Secure Hash Algorithm.
  7.  *
  8.  * Written 2 September 1992, Peter C. Gutmann.
  9.  * This implementation placed in the public domain.
  10.  *
  11.  * Modified 1 June 1993, Colin Plumb.
  12.  * Modified for the new SHS based on Peter Gutmann's work,
  13.  * 18 July 1994, Colin Plumb.
  14.  * Gutmann's work.
  15.  * Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb.
  16.  * These modifications placed in the public domain.
  17.  *
  18.  * Comments to pgut1@cs.aukuni.ac.nz
  19.  */
  20. /*
  21.  * The SHA f()-functions.  The f1 and f3 functions can be optimized to
  22.  * save one boolean operation each - thanks to Rich Schroeppel,
  23.  * rcs@cs.arizona.edu for discovering this
  24.  */
  25. /*#define f1(x,y,z) ( (x & y) | (~x & z) ) // Rounds  0-19 */
  26. #define f1(x,y,z) ( z ^ (x & (y ^ z) ) ) /* Rounds  0-19 */
  27. #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
  28. /*#define f3(x,y,z) ( (x & y) | (x & z) | (y & z) ) // Rounds 40-59 */
  29. #define f3(x,y,z) ( (x & y) | (z & (x | y) ) ) /* Rounds 40-59 */
  30. #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
  31. /*
  32.  * The SHA Mysterious Constants.
  33.  * K1 = floor(sqrt(2) * 2^30)
  34.  * K2 = floor(sqrt(3) * 2^30)
  35.  * K3 = floor(sqrt(5) * 2^30)
  36.  * K4 = floor(sqrt(10) * 2^30)
  37.  */
  38. #define K1 0x5A827999L /* Rounds  0-19 */
  39. #define K2 0x6ED9EBA1L /* Rounds 20-39 */
  40. #define K3 0x8F1BBCDCL /* Rounds 40-59 */
  41. #define K4 0xCA62C1D6L /* Rounds 60-79 */
  42. /* SHA initial values */
  43. #define h0init 0x67452301L
  44. #define h1init 0xEFCDAB89L
  45. #define h2init 0x98BADCFEL
  46. #define h3init 0x10325476L
  47. #define h4init 0xC3D2E1F0L
  48. /*
  49.  * Note that it may be necessary to add parentheses to these macros
  50.  * if they are to be called with expressions as arguments.
  51.  */
  52. /* 32-bit rotate left - kludged with shifts */
  53. #define ROTL(n,X)  ( (X << n) | (X >> (32-n)) )
  54. /*
  55.  * The initial expanding function
  56.  *
  57.  * The hash function is defined over an 80-word expanded input array W,
  58.  * where the first 16 are copies of the input data, and the remaining 64
  59.  * are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3].  This
  60.  * implementation generates these values on the fly in a circular buffer.
  61.  */
  62. #if SHA_VERSION
  63. /* The new ("corrected") SHA, FIPS 180.1 */
  64. /* Same as below, but then rotate left one bit */
  65. #define expand(W,i) (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], 
  66.                      W[i&15] = ROTL(1, W[i&15]))
  67. #else
  68. /* The old (pre-correction) SHA, FIPS 180 */
  69. #define expand(W,i) (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15])
  70. #endif
  71. /*
  72.  * The prototype SHA sub-round
  73.  *
  74.  * The fundamental sub-round is
  75.  * a' = e + ROTL(5,a) + f(b, c, d) + k + data;
  76.  * b' = a;
  77.  * c' = ROTL(30,b);
  78.  * d' = c;
  79.  * e' = d;
  80.  * ... but this is implemented by unrolling the loop 5 times and renaming
  81.  * the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration.
  82.  */
  83. #define subRound(a, b, c, d, e, f, k, data) 
  84. ( e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b) )
  85. /*
  86.  * The above code is replicated 20 times for each of the 4 functions,
  87.  * using the next 20 values from the W[] array each time.
  88.  */
  89. /* Initialize the SHA values */
  90. void
  91. shaInit(struct SHAContext *sha)
  92. {
  93. /* Set the h-vars to their initial values */
  94. sha->digest[0] = h0init;
  95. sha->digest[1] = h1init;
  96. sha->digest[2] = h2init;
  97. sha->digest[3] = h3init;
  98. sha->digest[4] = h4init;
  99. /* Initialise bit count */
  100. #ifdef HAVE64
  101. sha->count = 0;
  102. #else
  103. sha->countLo = sha->countHi = 0;
  104. #endif
  105. }
  106. /*
  107.  * Perform the SHA transformation.  Note that this code, like MD5, seems to
  108.  * break some optimizing compilers due to the complexity of the expressions
  109.  * and the size of the basic block.  It may be necessary to split it into
  110.  * sections, e.g. based on the four subrounds
  111.  *
  112.  * Note that this corrupts the sha->data area
  113.  */
  114. #ifndef ASM
  115. void shaTransform(struct SHAContext *sha)
  116. {
  117. register word32 A, B, C, D, E;
  118. /* Set up first buffer */
  119. A = sha->digest[0];
  120. B = sha->digest[1];
  121. C = sha->digest[2];
  122. D = sha->digest[3];
  123. E = sha->digest[4];
  124. /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
  125. subRound( A, B, C, D, E, f1, K1, sha->data[ 0] );
  126. subRound( E, A, B, C, D, f1, K1, sha->data[ 1] );
  127. subRound( D, E, A, B, C, f1, K1, sha->data[ 2] );
  128. subRound( C, D, E, A, B, f1, K1, sha->data[ 3] );
  129. subRound( B, C, D, E, A, f1, K1, sha->data[ 4] );
  130. subRound( A, B, C, D, E, f1, K1, sha->data[ 5] );
  131. subRound( E, A, B, C, D, f1, K1, sha->data[ 6] );
  132. subRound( D, E, A, B, C, f1, K1, sha->data[ 7] );
  133. subRound( C, D, E, A, B, f1, K1, sha->data[ 8] );
  134. subRound( B, C, D, E, A, f1, K1, sha->data[ 9] );
  135. subRound( A, B, C, D, E, f1, K1, sha->data[10] );
  136. subRound( E, A, B, C, D, f1, K1, sha->data[11] );
  137. subRound( D, E, A, B, C, f1, K1, sha->data[12] );
  138. subRound( C, D, E, A, B, f1, K1, sha->data[13] );
  139. subRound( B, C, D, E, A, f1, K1, sha->data[14] );
  140. subRound( A, B, C, D, E, f1, K1, sha->data[15] );
  141. subRound( E, A, B, C, D, f1, K1, expand(sha->data, 16) );
  142. subRound( D, E, A, B, C, f1, K1, expand(sha->data, 17) );
  143. subRound( C, D, E, A, B, f1, K1, expand(sha->data, 18) );
  144. subRound( B, C, D, E, A, f1, K1, expand(sha->data, 19) );
  145. subRound( A, B, C, D, E, f2, K2, expand(sha->data, 20) );
  146. subRound( E, A, B, C, D, f2, K2, expand(sha->data, 21) );
  147. subRound( D, E, A, B, C, f2, K2, expand(sha->data, 22) );
  148. subRound( C, D, E, A, B, f2, K2, expand(sha->data, 23) );
  149. subRound( B, C, D, E, A, f2, K2, expand(sha->data, 24) );
  150. subRound( A, B, C, D, E, f2, K2, expand(sha->data, 25) );
  151. subRound( E, A, B, C, D, f2, K2, expand(sha->data, 26) );
  152. subRound( D, E, A, B, C, f2, K2, expand(sha->data, 27) );
  153. subRound( C, D, E, A, B, f2, K2, expand(sha->data, 28) );
  154. subRound( B, C, D, E, A, f2, K2, expand(sha->data, 29) );
  155. subRound( A, B, C, D, E, f2, K2, expand(sha->data, 30) );
  156. subRound( E, A, B, C, D, f2, K2, expand(sha->data, 31) );
  157. subRound( D, E, A, B, C, f2, K2, expand(sha->data, 32) );
  158. subRound( C, D, E, A, B, f2, K2, expand(sha->data, 33) );
  159. subRound( B, C, D, E, A, f2, K2, expand(sha->data, 34) );
  160. subRound( A, B, C, D, E, f2, K2, expand(sha->data, 35) );
  161. subRound( E, A, B, C, D, f2, K2, expand(sha->data, 36) );
  162. subRound( D, E, A, B, C, f2, K2, expand(sha->data, 37) );
  163. subRound( C, D, E, A, B, f2, K2, expand(sha->data, 38) );
  164. subRound( B, C, D, E, A, f2, K2, expand(sha->data, 39) );
  165. subRound( A, B, C, D, E, f3, K3, expand(sha->data, 40) );
  166. subRound( E, A, B, C, D, f3, K3, expand(sha->data, 41) );
  167. subRound( D, E, A, B, C, f3, K3, expand(sha->data, 42) );
  168. subRound( C, D, E, A, B, f3, K3, expand(sha->data, 43) );
  169. subRound( B, C, D, E, A, f3, K3, expand(sha->data, 44) );
  170. subRound( A, B, C, D, E, f3, K3, expand(sha->data, 45) );
  171. subRound( E, A, B, C, D, f3, K3, expand(sha->data, 46) );
  172. subRound( D, E, A, B, C, f3, K3, expand(sha->data, 47) );
  173. subRound( C, D, E, A, B, f3, K3, expand(sha->data, 48) );
  174. subRound( B, C, D, E, A, f3, K3, expand(sha->data, 49) );
  175. subRound( A, B, C, D, E, f3, K3, expand(sha->data, 50) );
  176. subRound( E, A, B, C, D, f3, K3, expand(sha->data, 51) );
  177. subRound( D, E, A, B, C, f3, K3, expand(sha->data, 52) );
  178. subRound( C, D, E, A, B, f3, K3, expand(sha->data, 53) );
  179. subRound( B, C, D, E, A, f3, K3, expand(sha->data, 54) );
  180. subRound( A, B, C, D, E, f3, K3, expand(sha->data, 55) );
  181. subRound( E, A, B, C, D, f3, K3, expand(sha->data, 56) );
  182. subRound( D, E, A, B, C, f3, K3, expand(sha->data, 57) );
  183. subRound( C, D, E, A, B, f3, K3, expand(sha->data, 58) );
  184. subRound( B, C, D, E, A, f3, K3, expand(sha->data, 59) );
  185. subRound( A, B, C, D, E, f4, K4, expand(sha->data, 60) );
  186. subRound( E, A, B, C, D, f4, K4, expand(sha->data, 61) );
  187. subRound( D, E, A, B, C, f4, K4, expand(sha->data, 62) );
  188. subRound( C, D, E, A, B, f4, K4, expand(sha->data, 63) );
  189. subRound( B, C, D, E, A, f4, K4, expand(sha->data, 64) );
  190. subRound( A, B, C, D, E, f4, K4, expand(sha->data, 65) );
  191. subRound( E, A, B, C, D, f4, K4, expand(sha->data, 66) );
  192. subRound( D, E, A, B, C, f4, K4, expand(sha->data, 67) );
  193. subRound( C, D, E, A, B, f4, K4, expand(sha->data, 68) );
  194. subRound( B, C, D, E, A, f4, K4, expand(sha->data, 69) );
  195. subRound( A, B, C, D, E, f4, K4, expand(sha->data, 70) );
  196. subRound( E, A, B, C, D, f4, K4, expand(sha->data, 71) );
  197. subRound( D, E, A, B, C, f4, K4, expand(sha->data, 72) );
  198. subRound( C, D, E, A, B, f4, K4, expand(sha->data, 73) );
  199. subRound( B, C, D, E, A, f4, K4, expand(sha->data, 74) );
  200. subRound( A, B, C, D, E, f4, K4, expand(sha->data, 75) );
  201. subRound( E, A, B, C, D, f4, K4, expand(sha->data, 76) );
  202. subRound( D, E, A, B, C, f4, K4, expand(sha->data, 77) );
  203. subRound( C, D, E, A, B, f4, K4, expand(sha->data, 78) );
  204. subRound( B, C, D, E, A, f4, K4, expand(sha->data, 79) );
  205. /* Build message digest */
  206. sha->digest[0] += A;
  207. sha->digest[1] += B;
  208. sha->digest[2] += C;
  209. sha->digest[3] += D;
  210. sha->digest[4] += E;
  211. }
  212. #endif /* !ASM */
  213. /*
  214.  * SHA is defined in big-endian form, so this converts the buffer from
  215.  * bytes to words, independent of the machine's native endianness.
  216.  *
  217.  * Assuming a consistent byte ordering for the machine, this also
  218.  * has the magic property of being self-inverse.  It is used as
  219.  * such.
  220.  */
  221. static void byteReverse(word32 *buffer, unsigned byteCount)
  222. {
  223. word32 value;
  224. byteCount /= sizeof(word32);
  225. while ( byteCount-- ) {
  226. value = (word32)((unsigned)((word8 *)buffer)[0] << 8 |
  227.                    ((word8 *)buffer)[1]) << 16 |
  228.                 ((unsigned)((word8 *)buffer)[2] << 8 |
  229.                    ((word8 *)buffer)[3]);
  230. *buffer++ = value;
  231. }
  232. }
  233. /* Update SHA for a block of data. */
  234. void
  235. shaUpdate(struct SHAContext *sha, word8 const *buffer, unsigned count)
  236. {
  237. word32 t;
  238. /* Update bitcount */
  239. #ifdef HAVE64
  240. t = (word32)sha->count & 0x3f;
  241. sha->count += count;
  242. #else
  243. t = sha->countLo;
  244. if ( ( sha->countLo = t + count ) < t )
  245. sha->countHi++; /* Carry from low to high */
  246. t &= 0x3f; /* Bytes already in sha->data */
  247. #endif
  248. /* Handle any leading odd-sized chunks */
  249. if (t) {
  250. word8 *p = (word8 *)sha->data + t;
  251. t = 64-t;
  252. if (count < t) {
  253. memcpy(p, buffer, count);
  254. return;
  255. }
  256. memcpy(p, buffer, t);
  257. byteReverse(sha->data, SHA_BLOCKSIZE);
  258. shaTransform(sha);
  259. buffer += t;
  260. count -= t;
  261. }
  262. /* Process data in SHA_BLOCKSIZE chunks */
  263. while (count >= SHA_BLOCKSIZE) {
  264. memcpy(sha->data, buffer, SHA_BLOCKSIZE);
  265. byteReverse(sha->data, SHA_BLOCKSIZE);
  266. shaTransform(sha);
  267. buffer += SHA_BLOCKSIZE;
  268. count -= SHA_BLOCKSIZE;
  269. }
  270. /* Handle any remaining bytes of data. */
  271. memcpy(sha->data, buffer, count);
  272. }
  273. /* Final wrapup - pad to 64-byte boundary with the bit pattern
  274.    1 0* (64-bit count of bits processed, MSB-first) */
  275. void
  276. shaFinal(struct SHAContext *sha, word8 *hash)
  277. {
  278. int count;
  279. word8 *p;
  280. /* Compute number of bytes mod 64 */
  281. #ifdef HAVE64
  282. count = (int)sha->count & 0x3F;
  283. #else
  284. count = (int)sha->countLo & 0x3F;
  285. #endif
  286. /*
  287.  * Set the first char of padding to 0x80.
  288.  * This is safe since there is always at least one byte free
  289.  */
  290. p = (word8 *)sha->data + count;
  291. *p++ = 0x80;
  292. /* Bytes of padding needed to make 64 bytes */
  293. count = SHA_BLOCKSIZE - 1 - count;
  294. /* Pad out to 56 mod 64 */
  295. if (count < 8) {
  296. /* Two lots of padding:  Pad the first block to 64 bytes */
  297. memset(p, 0, count);
  298. byteReverse(sha->data, SHA_BLOCKSIZE);
  299. shaTransform(sha);
  300. /* Now fill the next block with 56 bytes */
  301. memset(sha->data, 0, SHA_BLOCKSIZE-8);
  302. } else {
  303. /* Pad block to 56 bytes */
  304. memset(p, 0, count-8);
  305. }
  306. byteReverse(sha->data, SHA_BLOCKSIZE-8);
  307. /* Append length in *bits* and transform */
  308. #if HAVE64
  309. sha->data[14] = (word32)(sha->count >> 29);
  310. sha->data[15] = (word32)sha->count << 3;
  311. #else
  312. sha->data[14] = sha->countHi << 3 | sha->countLo >> 29;
  313. sha->data[15] = sha->countLo << 3;
  314. #endif
  315. shaTransform(sha);
  316. /* Store output hash in buffer */
  317. byteReverse(sha->digest, SHA_DIGESTSIZE);
  318. memcpy(hash, sha->digest, SHA_DIGESTSIZE);
  319. memset(sha, 0, sizeof(*sha));
  320. }
  321. #if 0
  322. /* ----------------------------- SHA Test code --------------------------- */
  323. #include <stdio.h>
  324. #include <stdlib.h> /* For exit() */
  325. #include <time.h>
  326. /* Size of buffer for SHA speed test data */
  327. #define TEST_BLOCK_SIZE ( SHA_DIGESTSIZE * 100 )
  328. /* Number of bytes of test data to process */
  329. #define TEST_BYTES 10000000L
  330. #define TEST_BLOCKS ( TEST_BYTES / TEST_BLOCK_SIZE )
  331. #if SHA_VERSION
  332. static char const *shaTestResults[] = {
  333. "A9993E364706816ABA3E25717850C26C9CD0D89D",
  334. "84983E441C3BD26EBAAE4AA1F95129E5E54670F1",
  335. "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
  336. "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
  337. "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" };
  338. #else
  339. static char const *shaTestResults[] = {
  340. "0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880",
  341. "D2516EE1ACFA5BAF33DFC1C471E438449EF134C8",
  342. "3232AFFA48628A26653B5AAA44541FD90D690603",
  343. "3232AFFA48628A26653B5AAA44541FD90D690603",
  344. "3232AFFA48628A26653B5AAA44541FD90D690603" };
  345. #endif
  346. static int
  347. compareSHAresults(word8 *hash, int level)
  348. {
  349. char buf[41];
  350. int i;
  351. for (i = 0; i < SHA_DIGESTSIZE; i++)
  352. sprintf(buf+2*i, "%02X", hash[i]);
  353. if (strcmp(buf, shaTestResults[level-1]) == 0) {
  354. printf("Test %d passed, result = %sn", level, buf);
  355. return 0;
  356. } else {
  357. printf("Error in SHA implementation: Test %d failedn", level);
  358. printf("  Result = %sn", buf);
  359. printf("Expected = %sn", shaTestResults[level-1]);
  360. return -1;
  361. }
  362. }
  363. int
  364. main(void)
  365. {
  366. struct SHAContext sha;
  367. word8 data[TEST_BLOCK_SIZE];
  368. word8 hash[SHA_DIGESTSIZE];
  369. time_t seconds;
  370. long i;
  371. word32 t;
  372. /* Check that LITTLE_ENDIAN is set correctly */
  373. t = 0x12345678;
  374. #if LITTLE_ENDIAN
  375.      if (*(word8 *)&t != 0x78) {
  376.         puts("Error: Define BIG_ENDIAN in SHA.H and recompile");
  377.          exit(-1);
  378.         }
  379. #elif BIG_ENDIAN
  380.      if (*(word8 *)&t != 0x12) {
  381.         puts("Error: Define LITTLE_ENDIAN in SHA.H and recompile");
  382.         exit(-1);
  383.         }
  384. #endif
  385. /*
  386.  * Test output data (these are the only test data given in the
  387.  * Secure Hash Standard document, but chances are if it works
  388.  * for this it'll work for anything)
  389.  */
  390. shaInit(&sha);
  391. shaUpdate(&sha, (word8 *)"abc", 3);
  392. shaFinal(&sha, hash);
  393. if (compareSHAresults(hash, 1) < 0)
  394. exit (-1);
  395. shaInit(&sha);
  396. shaUpdate(&sha, (word8 *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
  397. shaFinal(&sha, hash);
  398. if (compareSHAresults(hash, 2) < 0)
  399. exit (-1);
  400. /* 1,000,000 bytes of ASCII 'a' (0x61), by 64's */
  401. shaInit(&sha);
  402. for (i = 0; i < 15625; i++)
  403. shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64);
  404. shaFinal(&sha, hash);
  405. if (compareSHAresults(hash, 3) < 0)
  406. exit (-1);
  407. /* 1,000,000 bytes of ASCII 'a' (0x61), by 25's */
  408. shaInit(&sha);
  409. for (i = 0; i < 40000; i++)
  410. shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25);
  411. shaFinal(&sha, hash);
  412. if (compareSHAresults(hash, 4) < 0)
  413. exit (-1);
  414. /* 1,000,000 bytes of ASCII 'a' (0x61), by 125's */
  415. shaInit(&sha);
  416. for (i = 0; i < 8000; i++)
  417. shaUpdate(&sha, (word8 *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125);
  418. shaFinal(&sha, hash);
  419. if (compareSHAresults(hash, 5) < 0)
  420. exit (-1);
  421. /* Now perform time trial, generating MD for 10MB of data.  First,
  422.    initialize the test data */
  423. memset(data, 0, TEST_BLOCK_SIZE);
  424. /* Get start time */
  425. printf("SHA time trial.  Processing %ld characters...n", TEST_BYTES);
  426. seconds = time((time_t *)0);
  427. /* Calculate SHA message digest in TEST_BLOCK_SIZE byte blocks */
  428. shaInit(&sha);
  429. for (i = TEST_BLOCKS; i > 0; i--)
  430. shaUpdate(&sha, data, TEST_BLOCK_SIZE);
  431. shaFinal(&sha, hash);
  432. /* Get finish time and print difference */
  433. seconds = time((time_t *)0) - seconds;
  434. printf("Seconds to process test input: %ldn", seconds);
  435. printf("Characters processed per second: %ldn", TEST_BYTES / seconds);
  436. return 0;
  437. }
  438. #endif /* Test driver */