md5.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* md5.c - RSA Data Security, Inc., MD5 message-digest algorithm */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01a,29mar01,spm  file creation: copied from version 01g of tor2_0.open_stack
  8.                  branch (wpwr VOB) for unified code base
  9. */
  10. /*
  11.  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
  12.  * rights reserved.
  13.  *
  14.  * License to copy and use this software is granted provided that it
  15.  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
  16.  * Algorithm" in all material mentioning or referencing this software
  17.  * or this function.
  18.  *
  19.  * License is also granted to make and use derivative works provided
  20.  * that such works are identified as "derived from the RSA Data
  21.  * Security, Inc. MD5 Message-Digest Algorithm" in all material
  22.  * mentioning or referencing the derived work.
  23.  *
  24.  * RSA Data Security, Inc. makes no representations concerning either
  25.  * the merchantability of this software or the suitability of this
  26.  * software for any particular purpose. It is provided "as is"
  27.  * without express or implied warranty of any kind.
  28.  *
  29.  * These notices must be retained in any copies of any part of this
  30.  * documentation and/or software.
  31.  */
  32. /*
  33. DESCRIPTION
  34. This module implements the Message Digest 5 (MD5) algorithm.  To create
  35. a message digest of a block of text the following is used:
  36. MD5_CTX_T ctx
  37. MD5Init(&ctx)
  38. MD5Update(&ctx, text)
  39. MD5Final(digest, &ctx)
  40. Simply create a context and initialize it.  Then use MD5Update to
  41. add to the message digest.  Note that MD5Update can be called any number
  42. of times.  Then call MD5Final which creates and stores the calculated
  43. 16 byte digest.
  44. INCLUDES: md5.h
  45. SEE ALSO: RFC 1321
  46. */
  47. #ifdef RIP_MD5
  48. /* defines */
  49. #define MD5_TEST 0
  50. /* includes */
  51. #include "string.h"
  52. #include "vxWorks.h"
  53. #include "rip/md5.h"
  54. /* forward declarations */
  55. LOCAL void MD5Transform(ULONG [4], UCHAR [64]);
  56. /* locals */
  57. LOCAL UCHAR PADDING[64] =
  58.     {
  59.     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  60.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  61.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  62.     };
  63. /* defines */
  64. /* Constants for MD5 Transform routine  */ 
  65. #define S11 7
  66. #define S12 12
  67. #define S13 17
  68. #define S14 22
  69. #define S21 5
  70. #define S22 9
  71. #define S23 14
  72. #define S24 20
  73. #define S31 4
  74. #define S32 11
  75. #define S33 16
  76. #define S34 23
  77. #define S41 6
  78. #define S42 10
  79. #define S43 15
  80. #define S44 21
  81. /* macros */
  82. /* The so called "unbiased" bitwise auxiliary functions! */
  83. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  84. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  85. #define H(x, y, z) ((x) ^ (y) ^ (z))
  86. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  87. /* ROTATE_LEFT rotates x left n bits (circular left shift) */
  88. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
  89. /* Rounds 1(FF), 2(GG), 3(HH), and 4(II) transformations */
  90. #define FF(a, b, c, d, x, s, ac) 
  91.         { 
  92.         (a) += (F((b), (c), (d)) + (x) + (ULONG)(ac)); 
  93.         (a) = ROTATE_LEFT((a), (s)); 
  94.         (a) += (b); 
  95.         }
  96. #define GG(a, b, c, d, x, s, ac) 
  97.         { 
  98.         (a) += (G((b), (c), (d)) + (x) + (ULONG)(ac)); 
  99.         (a) = ROTATE_LEFT((a), (s)); 
  100.         (a) += (b); 
  101.         }
  102. #define HH(a, b, c, d, x, s, ac) 
  103.         { 
  104.         (a) += (H((b), (c), (d)) + (x) + (ULONG)(ac)); 
  105.         (a) = ROTATE_LEFT((a), (s)); 
  106.         (a) += (b); 
  107.         }
  108. #define II(a, b, c, d, x, s, ac) 
  109.         { 
  110.         (a) += (I((b), (c), (d)) + (x) + (ULONG)(ac)); 
  111.         (a) = ROTATE_LEFT((a), (s)); 
  112.         (a) += (b); 
  113.         }
  114. /***************************************************************************
  115. * MD5Transform - Basic MD5 transformation.
  116. * Transforms the state registers based on the given block.
  117. *
  118. * RETURNS: A new state.
  119. *
  120. * NOMANUAL
  121. */
  122. LOCAL void MD5Transform
  123.     (
  124.     ULONG state[4],
  125.     UCHAR block[64]
  126.     )
  127.     {
  128.     ULONG a, b, c, d;
  129.     ULONG x[16];
  130.     UINT i, j;
  131.     /* Copy block[j] into x[i] */
  132.     for (i = 0, j = 0; j < 64; i++, j += 4)
  133.         {
  134.         x[i] = (((ULONG)block[j]) |
  135.                 (((ULONG)block[j+1]) << 8) |
  136.                 (((ULONG)block[j+2]) << 16) |
  137.                 (((ULONG)block[j+3]) << 24));
  138.         }
  139.     /* Copy context->state[] to working vars */
  140.     a = state[0];
  141.     b = state[1];
  142.     c = state[2];
  143.     d = state[3];
  144.     /*
  145.      * The last argument of the following function is based of the
  146.      * sine funciton.  A 64 element table T[1...64] has been constructed
  147.      * where T[i] denotes the i-th element of the table which is equal
  148.      * to the integer part of 4294967296 times abs(sin(i)), i is in radians.
  149.      * See the appendix of RFC 1321 for actual values.
  150.      */
  151.     /* Round 1 */
  152.     FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  153.     FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  154.     FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  155.     FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  156.     FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  157.     FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  158.     FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  159.     FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  160.     FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  161.     FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  162.     FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  163.     FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  164.     FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  165.     FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  166.     FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  167.     FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  168.     /* Round 2 */
  169.     GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  170.     GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  171.     GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  172.     GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  173.     GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  174.     GG(d, a, b, c, x[10], S22,  0x2441453); /* 22 */
  175.     GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  176.     GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  177.     GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  178.     GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  179.     GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  180.     GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  181.     GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  182.     GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  183.     GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  184.     GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  185.     /* Round 3 */
  186.     HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  187.     HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  188.     HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  189.     HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  190.     HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  191.     HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  192.     HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  193.     HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  194.     HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  195.     HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  196.     HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  197.     HH(b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
  198.     HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  199.     HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  200.     HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  201.     HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  202.     /* Round 4 */
  203.     II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  204.     II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  205.     II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  206.     II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  207.     II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  208.     II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  209.     II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  210.     II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  211.     II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  212.     II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  213.     II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  214.     II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  215.     II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  216.     II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  217.     II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  218.     II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  219.     /* increment each state register by the new value */
  220.     state[0] += a;
  221.     state[1] += b;
  222.     state[2] += c;
  223.     state[3] += d;
  224.     /* Zeroize sensitive information */
  225.     memset((UCHAR *)x, 0, sizeof(x));
  226.     }
  227. /***************************************************************************
  228. *
  229. * MD5Init - Initialize the MD5 routine.
  230. *
  231. * Begins an MD5 operation by writing a new context.
  232. *
  233. * RETURNS: N/A
  234. */
  235. void MD5Init
  236.     (
  237.     MD5_CTX_T * context
  238.     )
  239.     {
  240.     context->count[0] = context->count[1] = 0;
  241.     /* Load magic initialization constants */
  242.     context->state[0] = 0x67452301;
  243.     context->state[1] = 0xefcdab89;
  244.     context->state[2] = 0x98badcfe;
  245.     context->state[3] = 0x10325476;
  246.     }
  247. /***************************************************************************
  248. *
  249. * MD5Update - MD5 block update operation.
  250. *
  251. * Continues an MD5 message-digest operation by processing another
  252. * message block and updating the context.
  253. *
  254. * RETURNS: N/A
  255. */
  256. void MD5Update
  257.     (
  258.     MD5_CTX_T * context,
  259.     UCHAR *     input,
  260.     UINT        inputLen
  261.     )
  262.     {
  263.     UINT i, index, partLen;
  264.     /* Compute number of bytes mod 64 */
  265.     index = (UINT)((context->count[0] >> 3) & 0x3F);
  266.     /* Update number of bits */
  267.     if ((context->count[0] += ((ULONG)inputLen << 3)) < ((ULONG)inputLen << 3))
  268.         {
  269.         context->count[1]++;
  270.         }
  271.     context->count[1] += ((ULONG)inputLen >> 29);
  272.     partLen = 64 - index;
  273.     /* Transform as many times as possible */
  274.     if (inputLen >= partLen)
  275.         {
  276.         memcpy((UCHAR *)&context->buffer[index], (UCHAR *)input, partLen);
  277.         MD5Transform((ULONG *)context->state, (UCHAR *)context->buffer);
  278.         for (i = partLen; (i + 63) < inputLen; i += 64)
  279.             {
  280.             MD5Transform((ULONG *)context->state, (UCHAR *)&input[i]);
  281.             }
  282.         index = 0;
  283.         }
  284.     else
  285.         {
  286.         i = 0;
  287.         }
  288.     /* Buffer remaining input */
  289.     memcpy((UCHAR *)&context->buffer[index], (UCHAR *)&input[i], inputLen - i);
  290.     }
  291. /***************************************************************************
  292. *
  293. * MD5Final - MD5 finalization.
  294. *
  295. * Ends an MD5 message-digest operation by writing the message digest
  296. * and zeroizing the context.
  297. *
  298. * RETURNS: N/A
  299. */
  300. void MD5Final
  301.     (
  302.     UCHAR       digest[16],
  303.     MD5_CTX_T * context
  304.     )
  305.     {
  306.     UCHAR bits[8];
  307.     UINT index, padLen;
  308.     UINT i, j;
  309.     /* Save number of bits */
  310.     for (i = 0, j = 0; j < 8; i++, j += 4)
  311.         {
  312.         bits[j] = (UCHAR)(context->count[i] & 0xff);
  313.         bits[j+1] = (UCHAR)((context->count[i] >> 8) & 0xff);
  314.         bits[j+2] = (UCHAR)((context->count[i] >> 16) & 0xff);
  315.         bits[j+3] = (UCHAR)((context->count[i] >> 24) & 0xff);
  316.         }
  317.     /* Pad out to 56 mod 64 */
  318.     index = (UINT)((context->count[0] >> 3) & 0x3f);
  319.     padLen = (index < 56) ? (56 - index) : (120 - index);
  320.     MD5Update(context, PADDING, padLen);
  321.     /* Append length (before padding) */
  322.     MD5Update(context, bits, 8);
  323.     /*
  324.      * Store the state as the digest.  The digest begins with the
  325.      * low-order byte of the first register and ends with the high-order
  326.      * byte of the last register.
  327.      */
  328.     for (i = 0, j = 0; j < 16; i++, j += 4)
  329.         {
  330.         digest[j] = (UCHAR)(context->state[i] & 0xff);
  331.         digest[j+1] = (UCHAR)((context->state[i] >> 8) & 0xff);
  332.         digest[j+2] = (UCHAR)((context->state[i] >> 16) & 0xff);
  333.         digest[j+3] = (UCHAR)((context->state[i] >> 24) & 0xff);
  334.         }
  335.     /* Zeroize sensitive information */
  336.     memset((UCHAR *)context, 0, sizeof(*context));
  337.     }
  338. #if MD5_TEST
  339. #include <stdio.h>
  340. LOCAL void MD5String
  341.     (
  342.     char * pString,
  343.     char * pResult
  344.     )
  345.     {
  346.     MD5_CTX_T context;
  347.     UCHAR digest[16];
  348.     UCHAR strDigest[32 + 1];
  349.     UCHAR * pTemp;
  350.     UINT len = strlen(pString);
  351.     int i;
  352.     MD5Init(&context);
  353.     MD5Update(&context, pString, len);
  354.     MD5Final(digest, &context);
  355.     for (pTemp = strDigest, i = 0; i < 16; i++)
  356.         pTemp += sprintf(pTemp, "%02x", digest[i]);
  357.     fprintf(stderr, "MD5("%s")n--> %s", pString, strDigest);
  358.     if (strcmp(strDigest, pResult) != 0) fprintf(stderr, " FAILEDn");
  359.     else fprintf(stderr, " PASSEDn");
  360.     }
  361. void MD5Test
  362.     (
  363.     void
  364.     )
  365.     {
  366.     printf("n");
  367.     MD5String("", "d41d8cd98f00b204e9800998ecf8427e");
  368.     MD5String("a", "0cc175b9c0f1b6a831c399e269772661");
  369.     MD5String("abc", "900150983cd24fb0d6963f7d28e17f72");
  370.     MD5String("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
  371.     MD5String("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
  372.     MD5String("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f");
  373.     MD5String("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a");
  374.     printf("n");
  375.     }
  376. #endif /* MD5_TEST */
  377. #endif /* RIP_MD5 */