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

  1. /****************************************************************************
  2. *                                                                            *
  3. *                          MD2 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 "md2.h"
  12. #elif defined( INC_CHILD )
  13.   #include "../crypt.h"
  14.   #include "md2.h"
  15. #else
  16.   #include "crypt.h"
  17.   #include "hash/md2.h"
  18. #endif /* Compiler-specific includes */
  19.  
  20. /****************************************************************************
  21. *                                                                            *
  22. *                            The MD2 Transformation                            *
  23. *                                                                            *
  24. ****************************************************************************/
  25.  
  26. /* The MD2 S-box, which is derived (somehow) from the digits of pi */
  27.  
  28. static BYTE pi[ 256 ] = {
  29.     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
  30.     0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
  31.     0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
  32.     0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
  33.     0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
  34.     0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
  35.     0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
  36.     0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
  37.     0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
  38.     0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
  39.     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
  40.     0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
  41.     0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
  42.     0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
  43.     0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
  44.     0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
  45.     0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
  46.     0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
  47.     0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
  48.     0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
  49.     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
  50.     0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
  51.     0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
  52.     0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
  53.     0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
  54.     0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
  55.     0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
  56.     0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
  57.     0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
  58.     0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
  59.     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
  60.     0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
  61.     };
  62.  
  63. /* Basic MD2 step. Transforms digest based on data */
  64.  
  65. void MD2Transform( MD2_INFO *md2Info, BYTE *data )
  66.     {
  67.     BYTE intermediate[ MD2_DATASIZE * 3 ], tmp = 0;
  68.     int i;
  69.  
  70.     /* Form the encryption block from the current MD, the next chunk of the
  71.        message, and the XOR of the MD and message chunk */
  72.     for( i = 0; i < MD2_DATASIZE; i++ )
  73.         {
  74.         BYTE stateTmp = md2Info->state[ i ], dataTmp = data[ i ];
  75.  
  76.         intermediate[ i ] = stateTmp;
  77.         intermediate[ i + MD2_DATASIZE ] = dataTmp;
  78.         intermediate[ i + ( MD2_DATASIZE * 2 ) ] = stateTmp ^ dataTmp;
  79.         }
  80.  
  81.     /* Make 18 passes over the intermediate data block.  We unrol the inner
  82.        loop a bit for speed */
  83.     tmp = 0;
  84.     for( i = 0; i < 18; i++ )
  85.         {
  86.         int j;
  87.  
  88.         for( j = 0; j < 48; j += 16 )
  89.             {
  90.             tmp = intermediate[ j +  0 ] ^= pi[ tmp ];
  91.             tmp = intermediate[ j +  1 ] ^= pi[ tmp ];
  92.             tmp = intermediate[ j +  2 ] ^= pi[ tmp ];
  93.             tmp = intermediate[ j +  3 ] ^= pi[ tmp ];
  94.             tmp = intermediate[ j +  4 ] ^= pi[ tmp ];
  95.             tmp = intermediate[ j +  5 ] ^= pi[ tmp ];
  96.             tmp = intermediate[ j +  6 ] ^= pi[ tmp ];
  97.             tmp = intermediate[ j +  7 ] ^= pi[ tmp ];
  98.             tmp = intermediate[ j +  8 ] ^= pi[ tmp ];
  99.             tmp = intermediate[ j +  9 ] ^= pi[ tmp ];
  100.             tmp = intermediate[ j + 10 ] ^= pi[ tmp ];
  101.             tmp = intermediate[ j + 11 ] ^= pi[ tmp ];
  102.             tmp = intermediate[ j + 12 ] ^= pi[ tmp ];
  103.             tmp = intermediate[ j + 13 ] ^= pi[ tmp ];
  104.             tmp = intermediate[ j + 14 ] ^= pi[ tmp ];
  105.             tmp = intermediate[ j + 15 ] ^= pi[ tmp ];
  106.             }
  107.  
  108.         tmp = ( tmp + i ) & 0xFF;
  109.         }
  110.  
  111.     /* Save the new state */
  112.     memcpy( md2Info->state, intermediate, MD2_DIGESTSIZE );
  113.  
  114.     /* Update the checksum */
  115.     tmp = md2Info->checksum[ MD2_DATASIZE - 1 ];
  116.     for( i = 0; i < MD2_DATASIZE; i++ )
  117.         tmp = md2Info->checksum[ i ] ^= pi[ data[ i ] ^ tmp ];
  118.  
  119.     /* Clean up */
  120.     zeroise( intermediate, MD2_DATASIZE * 3 );
  121.     }
  122.  
  123. /****************************************************************************
  124. *                                                                            *
  125. *                            MD2 Support Routines                            *
  126. *                                                                            *
  127. ****************************************************************************/
  128.  
  129. /* The routine md2Initial initializes the message-digest context md2Info */
  130.  
  131. void md2Initial( MD2_INFO *md2Info )
  132.     {
  133.     /* Clear all fields */
  134.     memset( md2Info, 0, sizeof( MD2_INFO ) );
  135.     }
  136.  
  137. /* The routine md2Update updates the message-digest context to account for
  138.    the presence of each of the characters buffer[ 0 .. count-1 ] in the
  139.    message whose digest is being computed */
  140.  
  141. void md2Update( MD2_INFO *md2Info, BYTE *buffer, int count )
  142.     {
  143.     int dataCount = md2Info->length;
  144.  
  145.     /* Handle simple case of no data */
  146.     if( !count )
  147.         return;
  148.  
  149.     /* Update the overall byte count mod MD2_DATASIZE */
  150.     md2Info->length = ( md2Info->length + count ) % MD2_DATASIZE;
  151.  
  152.     /* If there's any leftover data from a previous call, process it now */
  153.     if( dataCount )
  154.         {
  155.         int bytesLeft = MD2_DATASIZE - dataCount;
  156.  
  157.         /* If there's enough new data to build a chunk to process, do so
  158.            now */
  159.         if( count >= bytesLeft )
  160.             {
  161.             memcpy( md2Info->data + dataCount, buffer, bytesLeft );
  162.             MD2Transform( md2Info, md2Info->data );
  163.             buffer += bytesLeft;
  164.             count -= bytesLeft;
  165.             }
  166.         else
  167.             {
  168.             /* Save the input for later */
  169.             memcpy( md2Info->data + dataCount, buffer, count );
  170.             return;
  171.             }
  172.         }
  173.  
  174.     /* Rumble through the input in MD2_DATASIZE chunks */
  175.     while( count >= MD2_DATASIZE )
  176.         {
  177.         MD2Transform( md2Info, buffer );
  178.         buffer += MD2_DATASIZE;
  179.         count -= MD2_DATASIZE;
  180.         }
  181.  
  182.     /* Save the remaining input for later */
  183.     memcpy( md2Info->data, buffer, count );
  184.     }
  185.  
  186. /* Final wrapup - pad to a multiple of MD2_DATASIZE bytes and process */
  187.  
  188. void md2Final( MD2_INFO *md2Info )
  189.     {
  190.     int i, pad;
  191.  
  192.     /* Pad the message out to a multiple of 16 bytes and transform.  The
  193.        padding character is the number of padding bytes necessary */
  194.     pad = MD2_DATASIZE - md2Info->length;
  195.     for( i = md2Info->length; i < MD2_DATASIZE; i++ )
  196.         md2Info->data[ i ] = pad;
  197.     MD2Transform( md2Info, md2Info->data );
  198.  
  199.     /* Add the message checksum and transform */
  200.     memcpy( md2Info->data, md2Info->checksum, MD2_DATASIZE );
  201.     MD2Transform( md2Info, md2Info->data );
  202.  
  203.     md2Info->done = TRUE;
  204.     }
  205.