Embedded systems coursework 2.
Fork of Crypto_light by
Embed:
(wiki syntax)
Show/hide line numbers
MD5.cpp
00001 /** 00002 Implementation of MD5 as described here: 00003 http://tools.ietf.org/html/rfc1321 00004 */ 00005 00006 #include "MD5.h" 00007 #include <string.h> 00008 00009 static const uint32_t A = 0x67452301; 00010 static const uint32_t B = 0xefcdab89; 00011 static const uint32_t C = 0x98badcfe; 00012 static const uint32_t D = 0x10325476; 00013 00014 00015 #define F(X,Y,Z) (((X) & (Y)) | ((~(X)) & (Z))) 00016 #define G(X,Y,Z) (((X) & (Z)) | ((Y) & (~(Z)))) 00017 #define H(X,Y,Z) ((X) ^ (Y) ^ (Z)) 00018 #define I(X,Y,Z) ((Y) ^ ((X) | (~(Z)))) 00019 00020 #define ROTL(W,N) (((W) << N) | ((W) >> (32-N))) 00021 00022 #define ROUND1(a,b,c,d,x,s,t) \ 00023 a = ROTL(a + F(b,c,d) + x + t,s) + b; 00024 00025 #define ROUND2(a,b,c,d,x,s,t) \ 00026 a = ROTL(a + G(b,c,d) + x + t,s) + b; 00027 00028 #define ROUND3(a,b,c,d,x,s,t) \ 00029 a = ROTL(a + H(b,c,d) + x + t,s) + b; 00030 00031 #define ROUND4(a,b,c,d,x,s,t) \ 00032 a = ROTL(a + I(b,c,d) + x + t,s) + b; 00033 00034 00035 00036 MD5::MD5(): 00037 HashAlgorithm(), 00038 a(A), 00039 b(B), 00040 c(C), 00041 d(D), 00042 totalBufferLength(0), 00043 buffer(), 00044 bufferLength(0) 00045 { 00046 } 00047 00048 uint8_t MD5::outputSize() const 00049 { 00050 return 16; 00051 } 00052 00053 void MD5::update(uint8_t *data, uint32_t length) 00054 { 00055 if((int)length < 64-bufferLength) 00056 { 00057 memcpy(&buffer[bufferLength], data, length); 00058 bufferLength += length; 00059 totalBufferLength += length; 00060 return; 00061 } 00062 int offset = 64-bufferLength; 00063 memcpy(&buffer[bufferLength], data, offset); 00064 computeRounds(&a, &b, &c, &d, buffer); 00065 while(length-offset > 64) 00066 { 00067 memcpy(buffer, &data[offset], 64); 00068 computeRounds(&a, &b, &c, &d, buffer); 00069 offset += 64; 00070 } 00071 if(offset > (int)length) 00072 offset -= 64; 00073 bufferLength = length - offset; 00074 memcpy(buffer, &data[offset], bufferLength); 00075 totalBufferLength += length; 00076 } 00077 00078 void MD5::finalize(uint8_t *hash) 00079 { 00080 uint32_t *hash2 = (uint32_t*)hash; 00081 uint16_t padding; 00082 if(totalBufferLength % 64 < 56) 00083 padding = 56 - (totalBufferLength % 64); 00084 else 00085 padding = 56 + (64 - (totalBufferLength % 64)); 00086 buffer[bufferLength++] = 0x80; 00087 padding--; 00088 if(padding+bufferLength == 56) 00089 memset(&buffer[bufferLength], 0, padding); 00090 else 00091 { 00092 memset(&buffer[bufferLength], 0, 64-bufferLength); 00093 computeRounds(&a, &b, &c, &d, buffer); 00094 memset(buffer, 0, 56); 00095 } 00096 uint64_t lengthBit = totalBufferLength << 3; 00097 uint32_t lengthBitLow = lengthBit; 00098 uint32_t lengthBitHigh = lengthBit >> 32; 00099 memcpy(&buffer[56], &lengthBitLow, 4); 00100 memcpy(&buffer[60], &lengthBitHigh, 4); 00101 computeRounds(&a, &b, &c, &d, buffer); 00102 00103 hash2[0] = a; 00104 hash2[1] = b; 00105 hash2[2] = c; 00106 hash2[3] = d; 00107 // reset state 00108 a = A; 00109 b = B; 00110 c = C; 00111 d = D; 00112 totalBufferLength = 0; 00113 bufferLength = 0; 00114 } 00115 00116 00117 void MD5::computeHash(uint8_t *hash, uint8_t *data, uint32_t length) 00118 { 00119 uint32_t *hash2 = (uint32_t*)hash; 00120 uint64_t lengthBit = length << 3; 00121 uint32_t padding; 00122 if(length % 64 < 56) 00123 padding = 56 - (length % 64); 00124 else 00125 padding = 56 + (64 - (length % 64)); 00126 00127 uint32_t a = A, b = B, c = C, d = D; 00128 while(length >= 64) 00129 { 00130 computeRounds(&a, &b, &c, &d, data); 00131 data += 64; 00132 length -= 64; 00133 } 00134 uint8_t buffer[64]; 00135 memcpy(buffer, data, length); 00136 buffer[length++] = 0x80; 00137 padding--; 00138 if(padding+length == 56) 00139 memset(&buffer[length], 0, padding); 00140 else 00141 { 00142 memset(&buffer[length], 0, 64-length); 00143 computeRounds(&a, &b, &c, &d, data); 00144 memset(buffer, 0, 56); 00145 } 00146 00147 uint32_t lengthBitLow = lengthBit; 00148 uint32_t lengthBitHigh = lengthBit >> 32; 00149 memcpy(&buffer[56], &lengthBitLow, 4); 00150 memcpy(&buffer[60], &lengthBitHigh, 4); 00151 00152 computeRounds(&a, &b, &c, &d, buffer); 00153 00154 hash2[0] = a; 00155 hash2[1] = b; 00156 hash2[2] = c; 00157 hash2[3] = d; 00158 } 00159 00160 00161 00162 #ifdef __CC_ARM 00163 __forceinline 00164 #endif 00165 void MD5::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer) 00166 { 00167 uint32_t a = *a2, b = *b2, c = *c2, d = *d2; 00168 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d; 00169 00170 uint32_t *x = (uint32_t*)buffer; 00171 00172 // Round 1 00173 ROUND1(a,b,c,d,x[0],7,0xd76aa478); ROUND1(d,a,b,c,x[1],12,0xe8c7b756); ROUND1(c,d,a,b,x[2],17,0x242070db); ROUND1(b,c,d,a,x[3],22,0xc1bdceee); 00174 ROUND1(a,b,c,d,x[4],7,0xf57c0faf); ROUND1(d,a,b,c,x[5],12,0x4787c62a); ROUND1(c,d,a,b,x[6],17,0xa8304613); ROUND1(b,c,d,a,x[7],22,0xfd469501); 00175 ROUND1(a,b,c,d,x[8],7,0x698098d8); ROUND1(d,a,b,c,x[9],12,0x8b44f7af); ROUND1(c,d,a,b,x[10],17,0xffff5bb1); ROUND1(b,c,d,a,x[11],22,0x895cd7be); 00176 ROUND1(a,b,c,d,x[12],7,0x6b901122); ROUND1(d,a,b,c,x[13],12,0xfd987193); ROUND1(c,d,a,b,x[14],17,0xa679438e); ROUND1(b,c,d,a,x[15],22,0x49b40821); 00177 00178 00179 // Round 2 00180 ROUND2(a,b,c,d,x[1],5,0xf61e2562); ROUND2(d,a,b,c,x[6],9,0xc040b340); ROUND2(c,d,a,b,x[11],14,0x265e5a51); ROUND2(b,c,d,a,x[0],20,0xe9b6c7aa); 00181 ROUND2(a,b,c,d,x[5],5,0xd62f105d); ROUND2(d,a,b,c,x[10],9,0x02441453); ROUND2(c,d,a,b,x[15],14,0xd8a1e681); ROUND2(b,c,d,a,x[4],20,0xe7d3fbc8); 00182 ROUND2(a,b,c,d,x[9],5,0x21e1cde6); ROUND2(d,a,b,c,x[14],9,0xc33707d6); ROUND2(c,d,a,b,x[3],14,0xf4d50d87); ROUND2(b,c,d,a,x[8],20,0x455a14ed); 00183 ROUND2(a,b,c,d,x[13],5,0xa9e3e905); ROUND2(d,a,b,c,x[2],9,0xfcefa3f8); ROUND2(c,d,a,b,x[7],14,0x676f02d9); ROUND2(b,c,d,a,x[12],20,0x8d2a4c8a); 00184 00185 00186 // Round 3 00187 ROUND3(a,b,c,d,x[5],4,0xfffa3942); ROUND3(d,a,b,c,x[8],11,0x8771f681); ROUND3(c,d,a,b,x[11],16,0x6d9d6122); ROUND3(b,c,d,a,x[14],23,0xfde5380c); 00188 ROUND3(a,b,c,d,x[1],4,0xa4beea44); ROUND3(d,a,b,c,x[4],11,0x4bdecfa9); ROUND3(c,d,a,b,x[7],16,0xf6bb4b60); ROUND3(b,c,d,a,x[10],23,0xbebfbc70); 00189 ROUND3(a,b,c,d,x[13],4,0x289b7ec6); ROUND3(d,a,b,c,x[0],11,0xeaa127fa); ROUND3(c,d,a,b,x[3],16,0xd4ef3085); ROUND3(b,c,d,a,x[6],23,0x04881d05); 00190 ROUND3(a,b,c,d,x[9],4,0xd9d4d039); ROUND3(d,a,b,c,x[12],11,0xe6db99e5); ROUND3(c,d,a,b,x[15],16,0x1fa27cf8); ROUND3(b,c,d,a,x[2],23,0xc4ac5665); 00191 00192 00193 // Round 4 00194 ROUND4(a,b,c,d,x[0],6,0xf4292244); ROUND4(d,a,b,c,x[7],10,0x432aff97); ROUND4(c,d,a,b,x[14],15,0xab9423a7); ROUND4(b,c,d,a,x[5],21,0xfc93a039); 00195 ROUND4(a,b,c,d,x[12],6,0x655b59c3); ROUND4(d,a,b,c,x[3],10,0x8f0ccc92); ROUND4(c,d,a,b,x[10],15,0xffeff47d); ROUND4(b,c,d,a,x[1],21,0x85845dd1); 00196 ROUND4(a,b,c,d,x[8],6,0x6fa87e4f); ROUND4(d,a,b,c,x[15],10,0xfe2ce6e0); ROUND4(c,d,a,b,x[6],15,0xa3014314); ROUND4(b,c,d,a,x[13],21,0x4e0811a1); 00197 ROUND4(a,b,c,d,x[4],6,0xf7537e82); ROUND4(d,a,b,c,x[11],10,0xbd3af235); ROUND4(c,d,a,b,x[2],15,0x2ad7d2bb); ROUND4(b,c,d,a,x[9],21,0xeb86d391); 00198 00199 *a2 = a + tmpA; 00200 *b2 = b + tmpB; 00201 *c2 = c + tmpC; 00202 *d2 = d + tmpD; 00203 }
Generated on Wed Jul 20 2022 22:55:43 by 1.7.2