md5.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:15k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /* 
  2. ** **************************************************************************
  3. ** md5.c -- Implementation of MD5 Message Digest Algorithm                 **
  4. ** Updated: 2/16/90 by Ronald L. Rivest                                    **
  5. ** (C) 1990 RSA Data Security, Inc.                                        **
  6. ** **************************************************************************
  7. */
  8. /* 
  9. ** To use MD5:
  10. **   -- Include md5.h in your program
  11. **   -- Declare an MDstruct MD to hold the state of the digest computation.
  12. **   -- Initialize MD using MDbegin(&MD)
  13. **   -- For each full block (64 bytes) X you wish to process, call
  14. **          MDupdate(&MD,X,512)
  15. **      (512 is the number of bits in a full block.)
  16. **   -- For the last block (less than 64 bytes) you wish to process,
  17. **          MDupdate(&MD,X,n)
  18. **      where n is the number of bits in the partial block. A partial
  19. **      block terminates the computation, so every MD computation should
  20. **      terminate by processing a partial block, even if it has n = 0.
  21. **   -- The message digest is available in MD.buffer[0] ... MD.buffer[3].
  22. **      (Least-significant byte of each word should be output first.)
  23. **   -- You can print out the digest using MDprint(&MD)
  24. */
  25. /* Implementation notes:
  26. ** This implementation assumes that ints are 32-bit quantities.
  27. ** If the machine stores the least-significant byte of an int in the
  28. ** least-addressed byte (eg., VAX and 8086), then LOWBYTEFIRST should be
  29. ** set to TRUE.  Otherwise (eg., SUNS), LOWBYTEFIRST should be set to
  30. ** FALSE.  Note that on machines with LOWBYTEFIRST FALSE the routine
  31. ** MDupdate modifies has a side-effect on its input array (the order of bytes
  32. ** in each word are reversed).  If this is undesired a call to MDreverse(X) can
  33. ** reverse the bytes of X back into order after each call to MDupdate.
  34. */
  35. /* code uses WORDS_BIGENDIAN defined by configure now  -- WH 9/27/95 */
  36. /* Compile-time includes 
  37. */
  38. #include <config.h>
  39. #include <stdio.h>
  40. #include <sys/types.h>
  41. #if HAVE_STRING_H
  42. #include <string.h>
  43. #else
  44. #include <strings.h>
  45. #endif
  46. #if HAVE_WINSOCK_H
  47. #include <ip/socket.h>
  48. #endif
  49. #include "md5.h"
  50. /* Compile-time declarations of MD5 ``magic constants''.
  51. */
  52. #define I0  0x67452301       /* Initial values for MD buffer */
  53. #define I1  0xefcdab89
  54. #define I2  0x98badcfe
  55. #define I3  0x10325476
  56. #define fs1  7               /* round 1 shift amounts */
  57. #define fs2 12   
  58. #define fs3 17  
  59. #define fs4 22  
  60. #define gs1  5               /* round 2 shift amounts */
  61. #define gs2  9   
  62. #define gs3 14   
  63. #define gs4 20  
  64. #define hs1  4               /* round 3 shift amounts */
  65. #define hs2 11 
  66. #define hs3 16 
  67. #define hs4 23
  68. #define is1  6               /* round 4 shift amounts */
  69. #define is2 10
  70. #define is3 15
  71. #define is4 21
  72. /* Compile-time macro declarations for MD5.
  73. ** Note: The ``rot'' operator uses the variable ``tmp''.
  74. ** It assumes tmp is declared as unsigned int, so that the >>
  75. ** operator will shift in zeros rather than extending the sign bit.
  76. */
  77. #define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
  78. #define g(X,Y,Z)             ((X&Z) | (Y&(~Z)))
  79. #define h(X,Y,Z)             (X^Y^Z)
  80. #define i_(X,Y,Z)            (Y ^ ((X) | (~Z)))
  81. #define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
  82. #define ff(A,B,C,D,i,s,lp)   A = rot((A + f(B,C,D) + X[i] + lp),s) + B
  83. #define gg(A,B,C,D,i,s,lp)   A = rot((A + g(B,C,D) + X[i] + lp),s) + B
  84. #define hh(A,B,C,D,i,s,lp)   A = rot((A + h(B,C,D) + X[i] + lp),s) + B
  85. #define ii(A,B,C,D,i,s,lp)   A = rot((A + i_(B,C,D) + X[i] + lp),s) + B
  86. #ifdef STDC_HEADERS
  87. #define Uns(num) num##U
  88. #else
  89. #define Uns(num) num
  90. #endif /* STDC_HEADERS */
  91. void MDreverse (unsigned int *);
  92. static void MDblock (MDptr, unsigned int *);
  93. #ifdef SNMP_TESTING_CODE
  94. /* MDprint(MDp)
  95. ** Print message digest buffer MDp as 32 hexadecimal digits.
  96. ** Order is from low-order byte of buffer[0] to high-order byte of buffer[3].
  97. ** Each byte is printed with high-order hexadecimal digit first.
  98. ** This is a user-callable routine.
  99. */
  100. void 
  101. MDprint(MDptr MDp)
  102.     int i,j;
  103.     for (i=0;i<4;i++)
  104. for (j=0;j<32;j=j+8)
  105.     printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
  106.     printf("n");
  107.     fflush(stdout);
  108. }
  109. #endif /* SNMP_TESTING_CODE */
  110. /* MDbegin(MDp)
  111. ** Initialize message digest buffer MDp. 
  112. ** This is a user-callable routine.
  113. */
  114. void 
  115. MDbegin(MDptr MDp)
  116.     int i;
  117.     MDp->buffer[0] = I0;  
  118.     MDp->buffer[1] = I1;  
  119.     MDp->buffer[2] = I2;  
  120.     MDp->buffer[3] = I3; 
  121.     for (i=0;i<8;i++) MDp->count[i] = 0;
  122.     MDp->done = 0;
  123. }
  124. /* MDreverse(X)
  125. ** Reverse the byte-ordering of every int in X.
  126. ** Assumes X is an array of 16 ints.
  127. ** The macro revx reverses the byte-ordering of the next word of X.
  128. */
  129. #define revx { t = (*X << 16) | (*X >> 16); 
  130.        *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
  131. void MDreverse(unsigned int *X)
  132.     register unsigned int t;
  133.     revx; revx; revx; revx; revx; revx; revx; revx;
  134.     revx; revx; revx; revx; revx; revx; revx; revx;
  135. }
  136. /* MDblock(MDp,X)
  137. ** Update message digest buffer MDp->buffer using 16-word data block X.
  138. ** Assumes all 16 words of X are full of data.
  139. ** Does not update MDp->count.
  140. ** This routine is not user-callable. 
  141. */
  142. static void
  143. MDblock(MDptr MDp,
  144. unsigned int *X)
  145.     register unsigned int tmp, A, B, C, D;  /* hpux sysv sun */
  146. #ifdef WORDS_BIGENDIAN
  147.     MDreverse(X);
  148. #endif
  149.     A = MDp->buffer[0];
  150.     B = MDp->buffer[1];
  151.     C = MDp->buffer[2];
  152.     D = MDp->buffer[3];
  153.     
  154.     /* Update the message digest buffer */
  155.     ff(A , B , C , D ,  0 , fs1 , Uns(3614090360)); /* Round 1 */
  156.     ff(D , A , B , C ,  1 , fs2 , Uns(3905402710)); 
  157.     ff(C , D , A , B ,  2 , fs3 ,  Uns(606105819)); 
  158.     ff(B , C , D , A ,  3 , fs4 , Uns(3250441966)); 
  159.     ff(A , B , C , D ,  4 , fs1 , Uns(4118548399)); 
  160.     ff(D , A , B , C ,  5 , fs2 , Uns(1200080426)); 
  161.     ff(C , D , A , B ,  6 , fs3 , Uns(2821735955)); 
  162.     ff(B , C , D , A ,  7 , fs4 , Uns(4249261313)); 
  163.     ff(A , B , C , D ,  8 , fs1 , Uns(1770035416)); 
  164.     ff(D , A , B , C ,  9 , fs2 , Uns(2336552879)); 
  165.     ff(C , D , A , B , 10 , fs3 , Uns(4294925233)); 
  166.     ff(B , C , D , A , 11 , fs4 , Uns(2304563134)); 
  167.     ff(A , B , C , D , 12 , fs1 , Uns(1804603682)); 
  168.     ff(D , A , B , C , 13 , fs2 , Uns(4254626195)); 
  169.     ff(C , D , A , B , 14 , fs3 , Uns(2792965006)); 
  170.     ff(B , C , D , A , 15 , fs4 , Uns(1236535329)); 
  171.     gg(A , B , C , D ,  1 , gs1 , Uns(4129170786)); /* Round 2 */
  172.     gg(D , A , B , C ,  6 , gs2 , Uns(3225465664)); 
  173.     gg(C , D , A , B , 11 , gs3 ,  Uns(643717713)); 
  174.     gg(B , C , D , A ,  0 , gs4 , Uns(3921069994)); 
  175.     gg(A , B , C , D ,  5 , gs1 , Uns(3593408605)); 
  176.     gg(D , A , B , C , 10 , gs2 ,   Uns(38016083)); 
  177.     gg(C , D , A , B , 15 , gs3 , Uns(3634488961)); 
  178.     gg(B , C , D , A ,  4 , gs4 , Uns(3889429448)); 
  179.     gg(A , B , C , D ,  9 , gs1 ,  Uns(568446438)); 
  180.     gg(D , A , B , C , 14 , gs2 , Uns(3275163606)); 
  181.     gg(C , D , A , B ,  3 , gs3 , Uns(4107603335)); 
  182.     gg(B , C , D , A ,  8 , gs4 , Uns(1163531501)); 
  183.     gg(A , B , C , D , 13 , gs1 , Uns(2850285829)); 
  184.     gg(D , A , B , C ,  2 , gs2 , Uns(4243563512)); 
  185.     gg(C , D , A , B ,  7 , gs3 , Uns(1735328473)); 
  186.     gg(B , C , D , A , 12 , gs4 , Uns(2368359562));  
  187.     hh(A , B , C , D ,  5 , hs1 , Uns(4294588738)); /* Round 3 */
  188.     hh(D , A , B , C ,  8 , hs2 , Uns(2272392833)); 
  189.     hh(C , D , A , B , 11 , hs3 , Uns(1839030562)); 
  190.     hh(B , C , D , A , 14 , hs4 , Uns(4259657740)); 
  191.     hh(A , B , C , D ,  1 , hs1 , Uns(2763975236)); 
  192.     hh(D , A , B , C ,  4 , hs2 , Uns(1272893353)); 
  193.     hh(C , D , A , B ,  7 , hs3 , Uns(4139469664)); 
  194.     hh(B , C , D , A , 10 , hs4 , Uns(3200236656)); 
  195.     hh(A , B , C , D , 13 , hs1 ,  Uns(681279174)); 
  196.     hh(D , A , B , C ,  0 , hs2 , Uns(3936430074)); 
  197.     hh(C , D , A , B ,  3 , hs3 , Uns(3572445317)); 
  198.     hh(B , C , D , A ,  6 , hs4 ,   Uns(76029189)); 
  199.     hh(A , B , C , D ,  9 , hs1 , Uns(3654602809)); 
  200.     hh(D , A , B , C , 12 , hs2 , Uns(3873151461)); 
  201.     hh(C , D , A , B , 15 , hs3 ,  Uns(530742520)); 
  202.     hh(B , C , D , A ,  2 , hs4 , Uns(3299628645));
  203.     ii(A , B , C , D ,  0 , is1 , Uns(4096336452)); /* Round 4 */
  204.     ii(D , A , B , C ,  7 , is2 , Uns(1126891415));
  205.     ii(C , D , A , B , 14 , is3 , Uns(2878612391));
  206.     ii(B , C , D , A ,  5 , is4 , Uns(4237533241));
  207.     ii(A , B , C , D , 12 , is1 , Uns(1700485571));
  208.     ii(D , A , B , C ,  3 , is2 , Uns(2399980690));
  209.     ii(C , D , A , B , 10 , is3 , Uns(4293915773));
  210.     ii(B , C , D , A ,  1 , is4 , Uns(2240044497));
  211.     ii(A , B , C , D ,  8 , is1 , Uns(1873313359));
  212.     ii(D , A , B , C , 15 , is2 , Uns(4264355552));
  213.     ii(C , D , A , B ,  6 , is3 , Uns(2734768916));
  214.     ii(B , C , D , A , 13 , is4 , Uns(1309151649));
  215.     ii(A , B , C , D ,  4 , is1 , Uns(4149444226));
  216.     ii(D , A , B , C , 11 , is2 , Uns(3174756917));
  217.     ii(C , D , A , B ,  2 , is3 ,  Uns(718787259));
  218.     ii(B , C , D , A ,  9 , is4 , Uns(3951481745));
  219.     
  220.     MDp->buffer[0] += A; 
  221.     MDp->buffer[1] += B;
  222.     MDp->buffer[2] += C;
  223.     MDp->buffer[3] += D; 
  224. #ifdef WORDS_BIGENDIAN
  225.     MDreverse(X);
  226. #endif
  227. }
  228. /* MDupdate(MDp,X,count)
  229. ** Input: MDp -- an MDptr
  230. **        X -- a pointer to an array of unsigned characters.
  231. **        count -- the number of bits of X to use.
  232. **                 (if not a multiple of 8, uses high bits of last byte.)
  233. ** Update MDp using the number of bits of X given by count.
  234. ** This is the basic input routine for an MD5 user.
  235. ** The routine completes the MD computation when count < 512, so
  236. ** every MD computation should end with one call to MDupdate with a
  237. ** count less than 512.  A call with count 0 will be ignored if the
  238. ** MD has already been terminated (done != 0), so an extra call with count
  239. ** 0 can be given as a ``courtesy close'' to force termination if desired.
  240. ** Returns : 0 if processing succeeds or was already done;
  241. **          -1 if processing was already done
  242. **          -2 if count was too large
  243. */
  244. int 
  245. MDupdate(MDptr MDp,
  246.  unsigned char *X,
  247.  unsigned int count)
  248.     unsigned int i, tmp, bit, byte, mask;
  249.     unsigned char XX[64];
  250.     unsigned char *p;
  251.     /* return with no error if this is a courtesy close with count
  252.   ** zero and MDp->done is true.
  253.   */
  254.     if (count == 0 && MDp->done) return 0;
  255.     /* check to see if MD is already done and report error */
  256.     if (MDp->done) { return -1; }
  257. /*
  258.     if (MDp->done) { fprintf(stderr,"nError: MDupdate MD already done."); return; }
  259. */
  260.     /* Add count to MDp->count */
  261.     tmp = count;
  262.     p = MDp->count;
  263.     while (tmp)
  264.     { tmp += *p;
  265.     *p++ = (u_char)tmp;
  266.     tmp = tmp >> 8;
  267.     }
  268.     /* Process data */
  269.     if (count == 512) 
  270.     { /* Full block of data to handle */
  271. MDblock(MDp,(unsigned int *)X);
  272.     }
  273.     else if (count > 512) /* Check for count too large */
  274.     return -2;
  275. /*
  276.     { fprintf(stderr,"nError: MDupdate called with illegal count value %d.",count);
  277.     return;
  278.     }
  279. */
  280.     else /* partial block -- must be last block so finish up */
  281.     { /* Find out how many bytes and residual bits there are */
  282.         int copycount;
  283. byte = count >> 3;
  284. bit =  count & 7;
  285. copycount = byte; if (bit) copycount++;
  286. /* Copy X into XX since we need to modify it */
  287. memset(XX,0,sizeof(XX));
  288. memcpy(XX,X,copycount);
  289. /* Add padding '1' bit and low-order zeros in last byte */
  290. mask = ((unsigned long)1) << (7 - bit);
  291. XX[byte] = (u_char)((XX[byte] | mask) & ~( mask - 1));
  292. /* If room for bit count, finish up with this block */
  293. if (byte <= 55)
  294. { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
  295. MDblock(MDp,(unsigned int *)XX);
  296. }
  297. else /* need to do two blocks to finish up */
  298. { MDblock(MDp,(unsigned int *)XX);
  299. for (i=0;i<56;i++) XX[i] = 0;
  300. for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
  301. MDblock(MDp,(unsigned int *)XX);
  302. }
  303. /* Set flag saying we're done with MD computation */
  304. MDp->done = 1;
  305.     }
  306.     return 0;
  307. }
  308. /* MDchecksum(data, len, MD5): do a checksum on an arbirtrary amount of data */
  309. int
  310. MDchecksum(u_char *data, size_t len, u_char *mac, size_t maclen)
  311. {
  312.   MDstruct md;
  313.   MDstruct *MD = &md;
  314.   int rc = 0;
  315.   
  316.   MDbegin(MD);
  317.   while (len >= 64) {
  318.     rc = MDupdate(MD, data, 64*8);
  319.     if (rc) goto check_end;
  320.     data += 64;
  321.     len -= 64;
  322.   }
  323.   rc = MDupdate(MD, data, len*8);
  324.   if (rc) goto check_end;
  325.   /* copy the checksum to the outgoing data (all of it that is requested). */
  326.   MDget(MD, mac, maclen);
  327. check_end:
  328.   memset(&md,0,sizeof(md));
  329.   return rc;
  330. }
  331. /* MDsign(data, len, MD5): do a checksum on an arbirtrary amount
  332.    of data, and prepended with a secret in the standard fashion */
  333. int
  334. MDsign(u_char *data, size_t len, u_char *mac, size_t maclen,
  335.        u_char *secret, size_t secretlen)
  336. {
  337. #define HASHKEYLEN 64
  338.   MDstruct MD;
  339.   u_char   K1[HASHKEYLEN];
  340.   u_char   K2[HASHKEYLEN];
  341.   u_char   extendedAuthKey[HASHKEYLEN];
  342.   u_char   buf[HASHKEYLEN];
  343.   size_t   i;
  344.   u_char  *cp;
  345.   int      rc = 0;
  346. /*
  347.   memset(K1,0,HASHKEYLEN);
  348.   memset(K2,0,HASHKEYLEN);
  349.   memset(buf,0,HASHKEYLEN);
  350.   memset(extendedAuthKey,0,HASHKEYLEN);
  351. */
  352.   if (secretlen != 16 || secret == NULL || mac == NULL || data == NULL ||
  353.     len <= 0 || maclen <= 0) {
  354. /*    DEBUGMSGTL(("md5","MD5 signing not properly initialized")); */
  355.     return -1;
  356.   }
  357.   
  358.   memset(extendedAuthKey, 0, HASHKEYLEN);
  359.   memcpy(extendedAuthKey, secret, secretlen);
  360.   for(i = 0; i < HASHKEYLEN; i++) {
  361.     K1[i] = extendedAuthKey[i] ^ 0x36;
  362.     K2[i] = extendedAuthKey[i] ^ 0x5c;
  363.   }
  364.   MDbegin(&MD);
  365.   rc = MDupdate(&MD, K1, HASHKEYLEN*8);
  366.   if (rc) goto update_end;
  367.   i = len;
  368.   cp = data;
  369.   while (i >= 64) {
  370.     rc = MDupdate(&MD, cp, 64*8);
  371. if (rc) goto update_end;
  372.     cp += 64;
  373.     i -= 64;
  374.   }
  375.   rc = MDupdate(&MD, cp, i*8);
  376.   if (rc) goto update_end;
  377.   memset(buf,0,HASHKEYLEN);
  378.   MDget(&MD, buf, HASHKEYLEN);
  379.   MDbegin(&MD);
  380.   rc = MDupdate(&MD, K2, HASHKEYLEN*8);
  381.   if (rc) goto update_end;
  382.   rc = MDupdate(&MD, buf, 16*8);
  383.   if (rc) goto update_end;
  384.   
  385.   /* copy the sign checksum to the outgoing pointer */
  386.   MDget(&MD, mac, maclen);
  387. update_end:
  388.   memset(buf, 0, HASHKEYLEN);
  389.   memset(K1, 0, HASHKEYLEN);
  390.   memset(K2, 0, HASHKEYLEN);
  391.   memset(extendedAuthKey, 0, HASHKEYLEN);
  392.   memset(&MD, 0, sizeof(MD));
  393.   return rc;
  394. }
  395. void
  396. MDget(MDstruct *MD, u_char *buf, size_t buflen)
  397. {
  398.   int i, j;
  399.   
  400.   /* copy the checksum to the outgoing data (all of it that is requested). */
  401.   for(i=0; i < 4 && i*4 < (int)buflen; i++)
  402.     for(j=0; j < 4 && i*4+j < (int)buflen; j++)
  403.       buf[i*4+j] = (u_char)((MD->buffer[i] >> j*8) & 0xff);
  404. }
  405. /* 
  406. ** End of md5.c
  407. ****************************(cut)*****************************************/