This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MD2.cpp Source File

MD2.cpp

00001 /**
00002     Implementation of MD2 as described here:
00003     http://tools.ietf.org/html/rfc1319
00004 */
00005 
00006 #include "MD2.h"
00007 #include <string.h>
00008 
00009 
00010 static const uint8_t s[] =
00011 {
00012     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 
00013     0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 
00014     0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 
00015     0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, 
00016     0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
00017     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 
00018     0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, 
00019     0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 
00020     0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, 
00021     0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, 
00022     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 
00023     0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, 
00024     0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 
00025     0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 
00026     0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 
00027     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
00028 };
00029 
00030 
00031 MD2::MD2():
00032 HashAlgorithm(),
00033 bufferLength(0),
00034 l(0)
00035 {
00036     memset(checksum, 0, 16);
00037     memset(x, 0, 16);
00038 }
00039 
00040 uint8_t MD2::outputSize() const
00041 {
00042     return 16;
00043 }
00044 
00045 void MD2::update(uint8_t *data, uint32_t length)
00046 { 
00047     if(bufferLength == 0)
00048     {
00049         while(length >= 16)
00050         {
00051             computeBlock(checksum, x, &l, data);
00052             length -= 16;
00053             data += 16;
00054         }
00055         bufferLength = length;
00056         memcpy(buffer, data, length);
00057     }
00058     else if((int)length < 16-bufferLength)
00059     {
00060         memcpy(&buffer[bufferLength], data, length);
00061         bufferLength += length;
00062     }
00063     else
00064     {
00065         int offset = 16-bufferLength;
00066         memcpy(&buffer[bufferLength], data, offset);
00067         computeBlock(checksum, x, &l, buffer);
00068         data += offset;
00069         length -= offset;
00070         while(length >= 16)
00071         {
00072             computeBlock(checksum, x, &l, data);
00073             data += 16;
00074             length -= 16;
00075         }
00076         bufferLength = length;
00077         memcpy(buffer, &data, length);
00078     }
00079     
00080 }
00081 
00082 void MD2::finalize(uint8_t *hash)
00083 {
00084     // compute what's left data the buffer
00085     int padding = 16 - bufferLength;
00086     memset(&buffer[bufferLength], padding, padding);
00087     computeBlock(checksum, x, &l, buffer);
00088     computeBlock(checksum, x, &l, checksum);
00089     memcpy(hash, x, 16);
00090 
00091     uint32_t *x2 = (uint32_t*)x;
00092     uint32_t *checksum2 = (uint32_t*)checksum;
00093 
00094     // reset state
00095     bufferLength = 0;
00096     l = 0;
00097     checksum2[0] = x2[0] = 0;
00098     checksum2[1] = x2[1] = 0;
00099     checksum2[2] = x2[2] = 0;
00100     checksum2[3] = x2[3] = 0;
00101 }
00102 
00103 void MD2::computeHash(uint8_t *hash, uint8_t *data, uint32_t length)
00104 {
00105     uint8_t x[48];
00106     uint8_t checksum[16];
00107     uint8_t buffer[16];
00108     memset(x, 0, 16);
00109     memset(checksum, 0, 16);
00110     uint8_t l = 0;
00111     while(length >= 16)
00112     {
00113         computeBlock(checksum, x, &l, data);
00114         length -= 16;
00115         data += 16;
00116     }
00117 
00118     memcpy(buffer, data, length);
00119     uint8_t padding = 16-length;
00120     memset(&buffer[length], padding, padding);
00121     computeBlock(checksum, x, &l, buffer);
00122     computeBlock(checksum,x, &l, checksum);
00123     memcpy(hash, x, 16);
00124 }
00125 
00126 #ifdef __CC_ARM
00127 __forceinline 
00128 #endif
00129 void MD2::computeBlock(uint8_t *checksum2, uint8_t *x2, uint8_t *l2, uint8_t *buffer2)
00130 {
00131     if(checksum2 != buffer2)
00132     {
00133         #ifdef __CC_ARM
00134             #pragma unroll_completely   
00135         #endif
00136         for(int j = 0; j < 16; ++j)
00137         {
00138             uint8_t c = buffer2[j];
00139             *l2 = (checksum2[j] ^= s[c^(*l2)]);
00140         }
00141     }
00142     
00143     uint32_t *x3 = (uint32_t*)x2;
00144     uint32_t *buffer3 = (uint32_t*)buffer2;
00145     
00146     x3[4] = buffer3[0];
00147     x3[5] = buffer3[1];
00148     x3[6] = buffer3[2];
00149     x3[7] = buffer3[3];
00150     for(int j = 0; j < 4; ++j)
00151         x3[8+j] = x3[4+j] ^ x3[j];
00152     
00153     uint8_t t = 0;
00154     #ifdef __CC_ARM
00155         #pragma unroll_completely   
00156     #endif
00157     for(int j = 0; j < 18; ++j)
00158     {
00159         t = (x2[0] ^= s[t]);
00160         t = (x2[1] ^= s[t]);
00161         t = (x2[2] ^= s[t]);
00162         t = (x2[3] ^= s[t]);
00163         t = (x2[4] ^= s[t]);
00164         t = (x2[5] ^= s[t]);
00165         t = (x2[6] ^= s[t]);
00166         t = (x2[7] ^= s[t]);
00167         t = (x2[8] ^= s[t]);
00168         t = (x2[9] ^= s[t]);
00169         t = (x2[10] ^= s[t]);
00170         t = (x2[11] ^= s[t]);
00171         t = (x2[12] ^= s[t]);
00172         t = (x2[13] ^= s[t]);
00173         t = (x2[14] ^= s[t]);
00174         t = (x2[15] ^= s[t]);
00175         t = (x2[16] ^= s[t]);
00176         t = (x2[17] ^= s[t]);
00177         t = (x2[18] ^= s[t]);
00178         t = (x2[19] ^= s[t]);
00179         t = (x2[20] ^= s[t]);
00180         t = (x2[21] ^= s[t]);
00181         t = (x2[22] ^= s[t]);
00182         t = (x2[23] ^= s[t]);            
00183         t = (x2[24] ^= s[t]);
00184         t = (x2[25] ^= s[t]);
00185         t = (x2[26] ^= s[t]);
00186         t = (x2[27] ^= s[t]);
00187         t = (x2[28] ^= s[t]);
00188         t = (x2[29] ^= s[t]);
00189         t = (x2[30] ^= s[t]);
00190         t = (x2[31] ^= s[t]);
00191         t = (x2[32] ^= s[t]);
00192         t = (x2[33] ^= s[t]);
00193         t = (x2[34] ^= s[t]);
00194         t = (x2[35] ^= s[t]);
00195         t = (x2[36] ^= s[t]);
00196         t = (x2[37] ^= s[t]);
00197         t = (x2[38] ^= s[t]);
00198         t = (x2[39] ^= s[t]);
00199         t = (x2[40] ^= s[t]);
00200         t = (x2[41] ^= s[t]);
00201         t = (x2[42] ^= s[t]);
00202         t = (x2[43] ^= s[t]);
00203         t = (x2[44] ^= s[t]);
00204         t = (x2[45] ^= s[t]);
00205         t = (x2[46] ^= s[t]);
00206         t = (x2[47] ^= s[t]);            
00207         
00208         t += j;
00209     }
00210 }