home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / HASH / MD5.C < prev    next >
Text File  |  1996-09-29  |  11KB  |  327 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                          MD5 Message Digest Algorithm                         *
  4. *                        Copyright Peter Gutmann 1992-1996                    *
  5. *                                                                            *
  6. ****************************************************************************/
  7.  
  8. #include <string.h>
  9. #if defined( INC_ALL )
  10.   #include "crypt.h"
  11.   #include "md5.h"
  12. #elif defined( INC_CHILD )
  13.   #include "../crypt.h"
  14.   #include "md5.h"
  15. #else
  16.   #include "crypt.h"
  17.   #include "hash/md5.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /****************************************************************************
  21. *                                                                            *
  22. *                            The MD5 Transformation                            *
  23. *                                                                            *
  24. ****************************************************************************/
  25.  
  26. /* Round 1 shift amounts */
  27.  
  28. #define S11    7
  29. #define S12    12
  30. #define S13    17
  31. #define S14    22
  32.  
  33. /* Round 2 shift amounts */
  34.  
  35. #define S21 5
  36. #define S22 9
  37. #define S23 14
  38. #define S24 20
  39.  
  40. /* Round 3 shift amounts */
  41.  
  42. #define S31 4
  43. #define S32 11
  44. #define S33 16
  45. #define S34 23
  46.  
  47. /* Round 4 shift amounts */
  48.  
  49. #define S41 6
  50. #define S42 10
  51. #define S43 15
  52. #define S44 21
  53.  
  54. /* F, G, H and I are basic MD5 functions */
  55.  
  56. #define F(X,Y,Z)    ( ( X & Y ) | ( ~X & Z ) )
  57. #define G(X,Y,Z)    ( ( X & Z ) | ( Y & ~Z ) )
  58. #define H(X,Y,Z)    ( X ^ Y ^ Z )
  59. #define I(X,Y,Z)    ( Y ^ ( X | ~Z ) )
  60.  
  61. /* ROTATE_LEFT rotates x left n bits */
  62.  
  63. #define ROTATE_LEFT(x,n)    ( ( x << n ) | ( x >> ( 32 - n ) ) )
  64.  
  65. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
  66.  
  67. #define FF(A,B,C,D,X,shiftAmt,magicConst) \
  68.     A += F( B, C, D ) + X + magicConst; \
  69.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) + B )
  70.  
  71. #define GG(A,B,C,D,X,shiftAmt,magicConst) \
  72.     A += G( B, C, D ) + X + magicConst; \
  73.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) + B )
  74.  
  75. #define HH(A,B,C,D,X,shiftAmt,magicConst) \
  76.     A += H( B, C, D ) + X + magicConst; \
  77.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) + B )
  78.  
  79. #define II(A,B,C,D,X,shiftAmt,magicConst) \
  80.     A += I( B, C, D ) + X + magicConst; \
  81.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) + B )
  82.  
  83. /* Basic MD5 step. Transforms digest based on data.  Note that if the
  84.    Mysterious Constants are arranged backwards in little-endian order and
  85.    decrypted with DES they produce OCCULT MESSAGES! */
  86.  
  87. void MD5Transform( LONG *digest, LONG *data )
  88.     {
  89.     LONG A, B, C, D;
  90.  
  91.     /* Set up local data */
  92.     A = digest[ 0 ];
  93.     B = digest[ 1 ];
  94.     C = digest[ 2 ];
  95.     D = digest[ 3 ];
  96.  
  97.     /* Round 1 */
  98.     FF( A, B, C, D, data[  0 ], S11, 3614090360UL );    /*  1 */
  99.     FF( D, A, B, C, data[  1 ], S12, 3905402710UL );    /*  2 */
  100.     FF( C, D, A, B, data[  2 ], S13,  606105819UL );    /*  3 */
  101.     FF( B, C, D, A, data[  3 ], S14, 3250441966UL );    /*  4 */
  102.     FF( A, B, C, D, data[  4 ], S11, 4118548399UL );    /*  5 */
  103.     FF( D, A, B, C, data[  5 ], S12, 1200080426UL );    /*  6 */
  104.     FF( C, D, A, B, data[  6 ], S13, 2821735955UL );    /*  7 */
  105.     FF( B, C, D, A, data[  7 ], S14, 4249261313UL );    /*  8 */
  106.     FF( A, B, C, D, data[  8 ], S11, 1770035416UL );    /*  9 */
  107.     FF( D, A, B, C, data[  9 ], S12, 2336552879UL );    /* 10 */
  108.     FF( C, D, A, B, data[ 10 ], S13, 4294925233UL );    /* 11 */
  109.     FF( B, C, D, A, data[ 11 ], S14, 2304563134UL );    /* 12 */
  110.     FF( A, B, C, D, data[ 12 ], S11, 1804603682UL );    /* 13 */
  111.     FF( D, A, B, C, data[ 13 ], S12, 4254626195UL );    /* 14 */
  112.     FF( C, D, A, B, data[ 14 ], S13, 2792965006UL );    /* 15 */
  113.     FF( B, C, D, A, data[ 15 ], S14, 1236535329UL );    /* 16 */
  114.  
  115.     /* Round 2 */
  116.     GG( A, B, C, D, data[  1 ], S21, 4129170786UL );    /* 17 */
  117.     GG( D, A, B, C, data[  6 ], S22, 3225465664UL );    /* 18 */
  118.     GG( C, D, A, B, data[ 11 ], S23,  643717713UL );    /* 19 */
  119.     GG( B, C, D, A, data[  0 ], S24, 3921069994UL );    /* 20 */
  120.     GG( A, B, C, D, data[  5 ], S21, 3593408605UL );    /* 21 */
  121.     GG( D, A, B, C, data[ 10 ], S22,   38016083UL );    /* 22 */
  122.     GG( C, D, A, B, data[ 15 ], S23, 3634488961UL );    /* 23 */
  123.     GG( B, C, D, A, data[  4 ], S24, 3889429448UL );    /* 24 */
  124.     GG( A, B, C, D, data[  9 ], S21,  568446438UL );    /* 25 */
  125.     GG( D, A, B, C, data[ 14 ], S22, 3275163606UL );    /* 26 */
  126.     GG( C, D, A, B, data[  3 ], S23, 4107603335UL );    /* 27 */
  127.     GG( B, C, D, A, data[  8 ], S24, 1163531501UL );    /* 28 */
  128.     GG( A, B, C, D, data[ 13 ], S21, 2850285829UL );    /* 29 */
  129.     GG( D, A, B, C, data[  2 ], S22, 4243563512UL );    /* 30 */
  130.     GG( C, D, A, B, data[  7 ], S23, 1735328473UL );    /* 31 */
  131.     GG( B, C, D, A, data[ 12 ], S24, 2368359562UL );    /* 32 */
  132.  
  133.     /* Round 3 */
  134.     HH( A, B, C, D, data[  5 ], S31, 4294588738UL );    /* 33 */
  135.     HH( D, A, B, C, data[  8 ], S32, 2272392833UL );    /* 34 */
  136.     HH( C, D, A, B, data[ 11 ], S33, 1839030562UL );    /* 35 */
  137.     HH( B, C, D, A, data[ 14 ], S34, 4259657740UL );    /* 36 */
  138.     HH( A, B, C, D, data[  1 ], S31, 2763975236UL );    /* 37 */
  139.     HH( D, A, B, C, data[  4 ], S32, 1272893353UL );    /* 38 */
  140.     HH( C, D, A, B, data[  7 ], S33, 4139469664UL );    /* 39 */
  141.     HH( B, C, D, A, data[ 10 ], S34, 3200236656UL );    /* 40 */
  142.     HH( A, B, C, D, data[ 13 ], S31,  681279174UL );    /* 41 */
  143.     HH( D, A, B, C, data[  0 ], S32, 3936430074UL );    /* 42 */
  144.     HH( C, D, A, B, data[  3 ], S33, 3572445317UL );    /* 43 */
  145.     HH( B, C, D, A, data[  6 ], S34,   76029189UL );    /* 44 */
  146.     HH( A, B, C, D, data[  9 ], S31, 3654602809UL );    /* 45 */
  147.     HH( D, A, B, C, data[ 12 ], S32, 3873151461UL );    /* 46 */
  148.     HH( C, D, A, B, data[ 15 ], S33,  530742520UL );    /* 47 */
  149.     HH( B, C, D, A, data[  2 ], S34, 3299628645UL );    /* 48 */
  150.  
  151.     /* Round 4 */
  152.     II( A, B, C, D, data[  0 ], S41, 4096336452UL );    /* 49 */
  153.     II( D, A, B, C, data[  7 ], S42, 1126891415UL );    /* 50 */
  154.     II( C, D, A, B, data[ 14 ], S43, 2878612391UL );    /* 51 */
  155.     II( B, C, D, A, data[  5 ], S44, 4237533241UL );    /* 52 */
  156.     II( A, B, C, D, data[ 12 ], S41, 1700485571UL );    /* 53 */
  157.     II( D, A, B, C, data[  3 ], S42, 2399980690UL );    /* 54 */
  158.     II( C, D, A, B, data[ 10 ], S43, 4293915773UL );    /* 55 */
  159.     II( B, C, D, A, data[  1 ], S44, 2240044497UL );    /* 56 */
  160.     II( A, B, C, D, data[  8 ], S41, 1873313359UL );    /* 57 */
  161.     II( D, A, B, C, data[ 15 ], S42, 4264355552UL );    /* 58 */
  162.     II( C, D, A, B, data[  6 ], S43, 2734768916UL );    /* 59 */
  163.     II( B, C, D, A, data[ 13 ], S44, 1309151649UL );    /* 60 */
  164.     II( A, B, C, D, data[  4 ], S41, 4149444226UL );    /* 61 */
  165.     II( D, A, B, C, data[ 11 ], S42, 3174756917UL );    /* 62 */
  166.     II( C, D, A, B, data[  2 ], S43,  718787259UL );    /* 63 */
  167.     II( B, C, D, A, data[  9 ], S44, 3951481745UL );    /* 64 */
  168.  
  169.     /* Build message digest */
  170.     digest[ 0 ] = MASK32( digest[ 0 ] + A );
  171.     digest[ 1 ] = MASK32( digest[ 1 ] + B );
  172.     digest[ 2 ] = MASK32( digest[ 2 ] + C );
  173.     digest[ 3 ] = MASK32( digest[ 3 ] + D );
  174.     }
  175.  
  176. /****************************************************************************
  177. *                                                                            *
  178. *                            MD5 Support Routines                            *
  179. *                                                                            *
  180. ****************************************************************************/
  181.  
  182. /* The routine md5Initial initializes the message-digest context md5Info */
  183.  
  184. void md5Initial( MD5_INFO *md5Info )
  185.     {
  186.     /* Clear all fields */
  187.     memset( md5Info, 0, sizeof( MD5_INFO ) );
  188.  
  189.     /* Load magic initialization constants */
  190.     md5Info->digest[ 0 ] = 0x67452301L;
  191.     md5Info->digest[ 1 ] = 0xEFCDAB89L;
  192.     md5Info->digest[ 2 ] = 0x98BADCFEL;
  193.     md5Info->digest[ 3 ] = 0x10325476L;
  194.  
  195.     /* Initialise bit count */
  196.     md5Info->countLo = md5Info->countHi = 0L;
  197.     }
  198.  
  199. /* The routine MD5Update updates the message-digest context to account for
  200.    the presence of each of the characters buffer[ 0 .. count-1 ] in the
  201.    message whose digest is being computed */
  202.  
  203. void md5Update( MD5_INFO *md5Info, BYTE *buffer, int count )
  204.     {
  205.     LONG tmp;
  206.     int dataCount;
  207.  
  208.     /* Update bitcount */
  209.     tmp = md5Info->countLo;
  210.     if ( ( md5Info->countLo = tmp + ( ( LONG ) count << 3 ) ) < tmp )
  211.         md5Info->countHi++;                /* Carry from low to high */
  212.     md5Info->countHi += count >> 29;
  213.  
  214.     /* Get count of bytes already in data */
  215.     dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
  216.  
  217.     /* Handle any leading odd-sized chunks */
  218.     if( dataCount )
  219.         {
  220. #ifdef _BIG_WORDS
  221.         BYTE *p = md5Info->dataBuffer + dataCount;
  222. #else
  223.         BYTE *p = ( BYTE * ) md5Info->data + dataCount;
  224. #endif /* _BIG_WORDS */
  225.  
  226.         dataCount = MD5_DATASIZE - dataCount;
  227.         if( count < dataCount )
  228.             {
  229.             memcpy( p, buffer, count );
  230.             return;
  231.             }
  232.         memcpy( p, buffer, dataCount );
  233. #ifdef _BIG_WORDS
  234.         copyToLLong( md5Info->data, md5Info->dataBuffer, MD5_DATASIZE );
  235. #else
  236.         littleToBigLong( md5Info->data, MD5_DATASIZE );
  237. #endif /* _BIG_WORDS */
  238.         MD5Transform( md5Info->digest, md5Info->data );
  239.         buffer += dataCount;
  240.         count -= dataCount;
  241.         }
  242.  
  243.     /* Process data in MD5_DATASIZE chunks */
  244.     while( count >= MD5_DATASIZE )
  245.         {
  246. #ifdef _BIG_WORDS
  247.         memcpy( md5Info->dataBuffer, buffer, MD5_DATASIZE );
  248.         copyToLLong( md5Info->data, md5Info->dataBuffer, MD5_DATASIZE );
  249. #else
  250.         memcpy( md5Info->data, buffer, MD5_DATASIZE );
  251.         littleToBigLong( md5Info->data, MD5_DATASIZE );
  252. #endif /* _BIG_WORDS */
  253.         MD5Transform( md5Info->digest, md5Info->data );
  254.         buffer += MD5_DATASIZE;
  255.         count -= MD5_DATASIZE;
  256.         }
  257.  
  258.     /* Handle any remaining bytes of data. */
  259. #ifdef _BIG_WORDS
  260.     memcpy( md5Info->dataBuffer, buffer, count );
  261. #else
  262.     memcpy( md5Info->data, buffer, count );
  263. #endif /* _BIG_WORDS */
  264.     }
  265.  
  266. /* Final wrapup - pad to MD5_DATASIZE-byte boundary with the bit pattern
  267.    1 0* (64-bit count of bits processed, MSB-first) */
  268.  
  269. void md5Final( MD5_INFO *md5Info )
  270.     {
  271.     int count;
  272.     BYTE *dataPtr;
  273.  
  274.     /* Compute number of bytes mod 64 */
  275.     count = ( int ) md5Info->countLo;
  276.     count = ( count >> 3 ) & 0x3F;
  277.  
  278.     /* Set the first char of padding to 0x80.  This is safe since there is
  279.        always at least one byte free */
  280. #ifdef _BIG_WORDS
  281.     dataPtr = md5Info->dataBuffer + count;
  282. #else
  283.     dataPtr = ( BYTE * ) md5Info->data + count;
  284. #endif /* _BIG_WORDS */
  285.     *dataPtr++ = 0x80;
  286.  
  287.     /* Bytes of padding needed to make 64 bytes */
  288.     count = MD5_DATASIZE - 1 - count;
  289.  
  290.     /* Pad out to 56 mod 64 */
  291.     if( count < 8 )
  292.         {
  293.         /* Two lots of padding:  Pad the first block to 64 bytes */
  294.         memset( dataPtr, 0, count );
  295. #ifdef _BIG_WORDS
  296.         copyToLLong( md5Info->data, md5Info->dataBuffer, MD5_DATASIZE );
  297. #else
  298.         littleToBigLong( md5Info->data, MD5_DATASIZE );
  299. #endif /* _BIG_WORDS */
  300.         MD5Transform( md5Info->digest, md5Info->data );
  301.  
  302.         /* Now fill the next block with 56 bytes */
  303. #ifdef _BIG_WORDS
  304.         memset( md5Info->dataBuffer, 0, MD5_DATASIZE - 8 );
  305. #else
  306.         memset( md5Info->data, 0, MD5_DATASIZE - 8 );
  307. #endif /* _BIG_WORDS */
  308.         }
  309.     else
  310.         /* Pad block to 56 bytes */
  311.         memset( dataPtr, 0, count - 8 );
  312. #ifdef _BIG_WORDS
  313.     copyToLLong( md5Info->data, md5Info->dataBuffer, MD5_DATASIZE );
  314. #endif /* _BIG_WORDS */
  315.  
  316.     /* Append length in bits and transform */
  317.     md5Info->data[ 14 ] = md5Info->countLo;
  318.     md5Info->data[ 15 ] = md5Info->countHi;
  319.  
  320. #ifndef _BIG_WORDS
  321.     littleToBigLong( md5Info->data, MD5_DATASIZE - 8 );
  322. #endif /* _BIG_WORDS */
  323.     MD5Transform( md5Info->digest, md5Info->data );
  324.  
  325.     md5Info->done = TRUE;
  326.     }
  327.