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

  1. /****************************************************************************
  2. *                                                                            *
  3. *                          MD4 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 "md4.h"
  12. #elif defined( INC_CHILD )
  13.   #include "../crypt.h"
  14.   #include "md4.h"
  15. #else
  16.   #include "crypt.h"
  17.   #include "hash/md4.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /****************************************************************************
  21. *                                                                            *
  22. *                            The MD4 Transformation                            *
  23. *                                                                            *
  24. ****************************************************************************/
  25.  
  26. /* MD4 magic numbers. C2 and C3 are from Knuth, Table 2, p.660, "The Art of
  27.    Programming", Volume 2 (Seminumerical Algorithms), Table 2, p.660.
  28.    Second Edition (1981), Addison-Wesley */
  29.  
  30. #define I0  0x67452301L      /* Initial values for MD buffer */
  31. #define I1  0xEFCDAB89L
  32. #define I2  0x98BADCFEL
  33. #define I3  0x10325476L
  34. #define C2  013240474631L    /* Round 2 constant: sqrt( 2 ) in octal */
  35. #define C3  015666365641L    /* Round 3 constant: sqrt( 3 ) in octal */
  36.  
  37. /* Round 1 shift amounts */
  38.  
  39. #define FS1  3
  40. #define FS2  7
  41. #define FS3 11
  42. #define FS4 19
  43.  
  44. /* Round 2 shift amounts */
  45.  
  46. #define GS1  3
  47. #define GS2  5
  48. #define GS3  9
  49. #define GS4 13
  50.  
  51. /* Round 3 shift amounts */
  52.  
  53. #define HS1  3
  54. #define HS2  9
  55. #define HS3 11
  56. #define HS4 15
  57.  
  58. /* F, G, and H are basic MD4 functions */
  59.  
  60. #define    F(X,Y,Z)    ( ( X & Y ) | ( ( ~X ) & Z ) )
  61. #define    G(X,Y,Z)    ( ( X & Y ) | ( X & Z ) | ( Y & Z ) )
  62. #define H(X,Y,Z)    ( X ^ Y ^ Z )
  63.  
  64. /* ROTATE_LEFT rotates x left n bits */
  65.  
  66. #define ROTATE_LEFT(x,n)    ( ( x << n ) | ( x >> ( 32 - n ) ) )
  67.  
  68. /* FF, GG, HH, and II transformations for rounds 1, 2, and 3 */
  69.  
  70. #define FF(A,B,C,D,X,shiftAmt) \
  71.     A += F( B, C, D ) + X; \
  72.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) )
  73.  
  74. #define GG(A,B,C,D,X,shiftAmt) \
  75.     A += G( B, C,D ) + X + C2; \
  76.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) )
  77.  
  78. #define HH(A,B,C,D,X,shiftAmt) \
  79.     A += H( B, C,D ) + X + C3; \
  80.     A = MASK32( ROTATE_LEFT( MASK32( A ), shiftAmt ) )
  81.  
  82. /* Basic MD4 step. Transforms digest based on data */
  83.  
  84. void MD4Transform( LONG *digest, LONG *data )
  85.     {
  86.     LONG A, B, C, D;
  87.  
  88.     /* Set up local data */
  89.     A = digest[ 0 ];
  90.     B = digest[ 1 ];
  91.     C = digest[ 2 ];
  92.     D = digest[ 3 ];
  93.  
  94.     /* Round 1 */
  95.     FF( A, B, C, D, data[  0 ], FS1 );
  96.     FF( D, A, B, C, data[  1 ], FS2 );
  97.     FF( C, D, A, B, data[  2 ], FS3 );
  98.     FF( B, C, D, A, data[  3 ], FS4 );
  99.     FF( A, B, C, D, data[  4 ], FS1 );
  100.     FF( D, A, B, C, data[  5 ], FS2 );
  101.     FF( C, D, A, B, data[  6 ], FS3 );
  102.     FF( B, C, D, A, data[  7 ], FS4 );
  103.     FF( A, B, C, D, data[  8 ], FS1 );
  104.     FF( D, A, B, C, data[  9 ], FS2 );
  105.     FF( C, D, A, B, data[ 10 ], FS3 );
  106.     FF( B, C, D, A, data[ 11 ], FS4 );
  107.     FF( A, B, C, D, data[ 12 ], FS1 );
  108.     FF( D, A, B, C, data[ 13 ], FS2 );
  109.     FF( C, D, A, B, data[ 14 ], FS3 );
  110.     FF( B, C, D, A, data[ 15 ], FS4 );
  111.  
  112.     /* Round 2 */
  113.     GG( A, B, C, D, data[  0 ], GS1 );
  114.     GG( D, A, B, C, data[  4 ], GS2 );
  115.     GG( C, D, A, B, data[  8 ], GS3 );
  116.     GG( B, C, D, A, data[ 12 ], GS4 );
  117.     GG( A, B, C, D, data[  1 ], GS1 );
  118.     GG( D, A, B, C, data[  5 ], GS2 );
  119.     GG( C, D, A, B, data[  9 ], GS3 );
  120.     GG( B, C, D, A, data[ 13 ], GS4 );
  121.     GG( A, B, C, D, data[  2 ], GS1 );
  122.     GG( D, A, B, C, data[  6 ], GS2 );
  123.     GG( C, D, A, B, data[ 10 ], GS3 );
  124.     GG( B, C, D, A, data[ 14 ], GS4 );
  125.     GG( A, B, C, D, data[  3 ], GS1 );
  126.     GG( D, A, B, C, data[  7 ], GS2 );
  127.     GG( C, D, A, B, data[ 11 ], GS3 );
  128.     GG( B, C, D, A, data[ 15 ], GS4 );
  129.  
  130.     /* Round 3 */
  131.     HH( A, B, C, D, data[  0 ], HS1 );
  132.     HH( D, A, B, C, data[  8 ], HS2 );
  133.     HH( C, D, A, B, data[  4 ], HS3 );
  134.     HH( B, C, D, A, data[ 12 ], HS4 );
  135.     HH( A, B, C, D, data[  2 ], HS1 );
  136.     HH( D, A, B, C, data[ 10 ], HS2 );
  137.     HH( C, D, A, B, data[  6 ], HS3 );
  138.     HH( B, C, D, A, data[ 14 ], HS4 );
  139.     HH( A, B, C, D, data[  1 ], HS1 );
  140.     HH( D, A, B, C, data[  9 ], HS2 );
  141.     HH( C, D, A, B, data[  5 ], HS3 );
  142.     HH( B, C, D, A, data[ 13 ], HS4 );
  143.     HH( A, B, C, D, data[  3 ], HS1 );
  144.     HH( D, A, B, C, data[ 11 ], HS2 );
  145.     HH( C, D, A, B, data[  7 ], HS3 );
  146.     HH( B, C, D, A, data[ 15 ], HS4 );
  147.  
  148.     /* Build message digest */
  149.     digest[ 0 ] = MASK32( digest[ 0 ] + A );
  150.     digest[ 1 ] = MASK32( digest[ 1 ] + B );
  151.     digest[ 2 ] = MASK32( digest[ 2 ] + C );
  152.     digest[ 3 ] = MASK32( digest[ 3 ] + D );
  153.     }
  154.  
  155. /****************************************************************************
  156. *                                                                            *
  157. *                            MD4 Support Routines                            *
  158. *                                                                            *
  159. ****************************************************************************/
  160.  
  161. /* The routine md4Initial initializes the message-digest context md4Info */
  162.  
  163. void md4Initial( MD4_INFO *md4Info )
  164.     {
  165.     /* Clear all fields */
  166.     memset( md4Info, 0, sizeof( MD4_INFO ) );
  167.  
  168.     /* Load magic initialization constants */
  169.     md4Info->digest[ 0 ] = I0;
  170.     md4Info->digest[ 1 ] = I1;
  171.     md4Info->digest[ 2 ] = I2;
  172.     md4Info->digest[ 3 ] = I3;
  173.  
  174.     /* Initialise bit count */
  175.     md4Info->countLo = md4Info->countHi = 0L;
  176.     }
  177.  
  178. /* The routine MD4Update updates the message-digest context to account for
  179.    the presence of each of the characters buffer[ 0 .. count-1 ] in the
  180.    message whose digest is being computed */
  181.  
  182. void md4Update( MD4_INFO *md4Info, BYTE *buffer, int count )
  183.     {
  184.     LONG tmp;
  185.     int dataCount;
  186.  
  187.     /* Update bitcount */
  188.     tmp = md4Info->countLo;
  189.     if ( ( md4Info->countLo = tmp + ( ( LONG ) count << 3 ) ) < tmp )
  190.         md4Info->countHi++;                /* Carry from low to high */
  191.     md4Info->countHi += count >> 29;
  192.  
  193.     /* Get count of bytes already in data */
  194.     dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
  195.  
  196.     /* Handle any leading odd-sized chunks */
  197.     if( dataCount )
  198.         {
  199. #ifdef _BIG_WORDS
  200.         BYTE *p = md4Info->dataBuffer + dataCount;
  201. #else
  202.         BYTE *p = ( BYTE * ) md4Info->data + dataCount;
  203. #endif /* _BIG_WORDS */
  204.  
  205.         dataCount = MD4_DATASIZE - dataCount;
  206.         if( count < dataCount )
  207.             {
  208.             memcpy( p, buffer, count );
  209.             return;
  210.             }
  211.         memcpy( p, buffer, dataCount );
  212. #ifdef _BIG_WORDS
  213.         copyToLLong( md4Info->data, md4Info->dataBuffer, MD4_DATASIZE );
  214. #else
  215.         littleToBigLong( md4Info->data, MD4_DATASIZE );
  216. #endif /* _BIG_WORDS */
  217.         MD4Transform( md4Info->digest, md4Info->data );
  218.         buffer += dataCount;
  219.         count -= dataCount;
  220.         }
  221.  
  222.     /* Process data in MD4_DATASIZE chunks */
  223.     while( count >= MD4_DATASIZE )
  224.         {
  225. #ifdef _BIG_WORDS
  226.         memcpy( md4Info->dataBuffer, buffer, MD4_DATASIZE );
  227.         copyToLLong( md4Info->data, md4Info->dataBuffer, MD4_DATASIZE );
  228. #else
  229.         memcpy( md4Info->data, buffer, MD4_DATASIZE );
  230.         littleToBigLong( md4Info->data, MD4_DATASIZE );
  231. #endif /* _BIG_WORDS */
  232.         MD4Transform( md4Info->digest, md4Info->data );
  233.         buffer += MD4_DATASIZE;
  234.         count -= MD4_DATASIZE;
  235.         }
  236.  
  237.     /* Handle any remaining bytes of data. */
  238. #ifdef _BIG_WORDS
  239.     memcpy( md4Info->dataBuffer, buffer, count );
  240. #else
  241.     memcpy( md4Info->data, buffer, count );
  242. #endif /* _BIG_WORDS */
  243.     }
  244.  
  245. /* Final wrapup - pad to MD4_DATASIZE-byte boundary with the bit pattern
  246.    1 0* (64-bit count of bits processed, MSB-first) */
  247.  
  248. void md4Final( MD4_INFO *md4Info )
  249.     {
  250.     int count;
  251.     BYTE *dataPtr;
  252.  
  253.     /* Compute number of bytes mod 64 */
  254.     count = ( int ) md4Info->countLo;
  255.     count = ( count >> 3 ) & 0x3F;
  256.  
  257.     /* Set the first char of padding to 0x80.  This is safe since there is
  258.        always at least one byte free */
  259. #ifdef _BIG_WORDS
  260.     dataPtr = md4Info->dataBuffer + count;
  261. #else
  262.     dataPtr = ( BYTE * ) md4Info->data + count;
  263. #endif /* _BIG_WORDS */
  264.     *dataPtr++ = 0x80;
  265.  
  266.     /* Bytes of padding needed to make 64 bytes */
  267.     count = MD4_DATASIZE - 1 - count;
  268.  
  269.     /* Pad out to 56 mod 64 */
  270.     if( count < 8 )
  271.         {
  272.         /* Two lots of padding:  Pad the first block to 64 bytes */
  273.         memset( dataPtr, 0, count );
  274. #ifdef _BIG_WORDS
  275.         copyToLLong( md4Info->data, md4Info->dataBuffer, MD4_DATASIZE );
  276. #else
  277.         littleToBigLong( md4Info->data, MD4_DATASIZE );
  278. #endif /* _BIG_WORDS */
  279.         MD4Transform( md4Info->digest, md4Info->data );
  280.  
  281.         /* Now fill the next block with 56 bytes */
  282. #ifdef _BIG_WORDS
  283.         memset( md4Info->dataBuffer, 0, MD4_DATASIZE - 8 );
  284. #else
  285.         memset( md4Info->data, 0, MD4_DATASIZE - 8 );
  286. #endif /* _BIG_WORDS */
  287.         }
  288.     else
  289.         /* Pad block to 56 bytes */
  290.         memset( dataPtr, 0, count - 8 );
  291. #ifdef _BIG_WORDS
  292.     copyToLLong( md4Info->data, md4Info->dataBuffer, MD4_DATASIZE );
  293. #endif /* _BIG_WORDS */
  294.  
  295.     /* Append length in bits and transform */
  296.     md4Info->data[ 14 ] = md4Info->countLo;
  297.     md4Info->data[ 15 ] = md4Info->countHi;
  298.  
  299. #ifndef _BIG_WORDS
  300.     littleToBigLong( md4Info->data, MD4_DATASIZE - 8 );
  301. #endif /* _BIG_WORDS */
  302.     MD4Transform( md4Info->digest, md4Info->data );
  303.  
  304.     md4Info->done = TRUE;
  305.     }
  306.