00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "system.h"
00029 #include "md5.h"
00030 #include "mp32.h"
00031 #include "endianness.h"
00032 #include "debug.h"
00033
00036
00037 static uint32 md5hinit[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
00038
00039
00040 const hashFunction md5 = { "MD5", sizeof(md5Param), 64, 4 * sizeof(uint32), (hashFunctionReset) md5Reset, (hashFunctionUpdate) md5Update, (hashFunctionDigest) md5Digest };
00041
00042
00043
00044 int md5Reset(register md5Param* p)
00045 {
00046 mp32copy(4, p->h, md5hinit);
00047 mp32zero(16, p->data);
00048 p->length = 0;
00049 p->offset = 0;
00050 return 0;
00051 }
00052
00053
00054 #define FF(a, b, c, d, w, s, t) \
00055 a += ((b&(c^d))^d) + w + t; \
00056 a = ROTL32(a, s); \
00057 a += b;
00058
00059 #define GG(a, b, c, d, w, s, t) \
00060 a += ((d&(b^c))^c) + w + t; \
00061 a = ROTL32(a, s); \
00062 a += b;
00063
00064 #define HH(a, b, c, d, w, s, t) \
00065 a += (b^c^d) + w + t; \
00066 a = ROTL32(a, s); \
00067 a += b;
00068
00069 #define II(a, b, c, d, w, s, t) \
00070 a += (c^(b|~d)) + w + t; \
00071 a = ROTL32(a, s); \
00072 a += b;
00073
00074 #ifndef ASM_MD5PROCESS
00075
00076 void md5Process(md5Param* p)
00077 {
00078 register uint32 a,b,c,d;
00079 register uint32* w;
00080 #if WORDS_BIGENDIAN
00081 register byte t;
00082 #endif
00083
00084 w = p->data;
00085 #if WORDS_BIGENDIAN
00086 t = 16;
00087 while (t--)
00088 {
00089 register uint32 temp = swapu32(*w);
00090 *(w++) = temp;
00091 }
00092 w = p->data;
00093 #endif
00094
00095 a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
00096
00097 FF(a, b, c, d, w[ 0], 7, 0xd76aa478);
00098 FF(d, a, b, c, w[ 1], 12, 0xe8c7b756);
00099 FF(c, d, a, b, w[ 2], 17, 0x242070db);
00100 FF(b, c, d, a, w[ 3], 22, 0xc1bdceee);
00101 FF(a, b, c, d, w[ 4], 7, 0xf57c0faf);
00102 FF(d, a, b, c, w[ 5], 12, 0x4787c62a);
00103 FF(c, d, a, b, w[ 6], 17, 0xa8304613);
00104 FF(b, c, d, a, w[ 7], 22, 0xfd469501);
00105 FF(a, b, c, d, w[ 8], 7, 0x698098d8);
00106 FF(d, a, b, c, w[ 9], 12, 0x8b44f7af);
00107 FF(c, d, a, b, w[10], 17, 0xffff5bb1);
00108 FF(b, c, d, a, w[11], 22, 0x895cd7be);
00109 FF(a, b, c, d, w[12], 7, 0x6b901122);
00110 FF(d, a, b, c, w[13], 12, 0xfd987193);
00111 FF(c, d, a, b, w[14], 17, 0xa679438e);
00112 FF(b, c, d, a, w[15], 22, 0x49b40821);
00113
00114 GG(a, b, c, d, w[ 1], 5, 0xf61e2562);
00115 GG(d, a, b, c, w[ 6], 9, 0xc040b340);
00116 GG(c, d, a, b, w[11], 14, 0x265e5a51);
00117 GG(b, c, d, a, w[ 0], 20, 0xe9b6c7aa);
00118 GG(a, b, c, d, w[ 5], 5, 0xd62f105d);
00119 GG(d, a, b, c, w[10], 9, 0x02441453);
00120 GG(c, d, a, b, w[15], 14, 0xd8a1e681);
00121 GG(b, c, d, a, w[ 4], 20, 0xe7d3fbc8);
00122 GG(a, b, c, d, w[ 9], 5, 0x21e1cde6);
00123 GG(d, a, b, c, w[14], 9, 0xc33707d6);
00124 GG(c, d, a, b, w[ 3], 14, 0xf4d50d87);
00125 GG(b, c, d, a, w[ 8], 20, 0x455a14ed);
00126 GG(a, b, c, d, w[13], 5, 0xa9e3e905);
00127 GG(d, a, b, c, w[ 2], 9, 0xfcefa3f8);
00128 GG(c, d, a, b, w[ 7], 14, 0x676f02d9);
00129 GG(b, c, d, a, w[12], 20, 0x8d2a4c8a);
00130
00131 HH(a, b, c, d, w[ 5], 4, 0xfffa3942);
00132 HH(d, a, b, c, w[ 8], 11, 0x8771f681);
00133 HH(c, d, a, b, w[11], 16, 0x6d9d6122);
00134 HH(b, c, d, a, w[14], 23, 0xfde5380c);
00135 HH(a, b, c, d, w[ 1], 4, 0xa4beea44);
00136 HH(d, a, b, c, w[ 4], 11, 0x4bdecfa9);
00137 HH(c, d, a, b, w[ 7], 16, 0xf6bb4b60);
00138 HH(b, c, d, a, w[10], 23, 0xbebfbc70);
00139 HH(a, b, c, d, w[13], 4, 0x289b7ec6);
00140 HH(d, a, b, c, w[ 0], 11, 0xeaa127fa);
00141 HH(c, d, a, b, w[ 3], 16, 0xd4ef3085);
00142 HH(b, c, d, a, w[ 6], 23, 0x04881d05);
00143 HH(a, b, c, d, w[ 9], 4, 0xd9d4d039);
00144 HH(d, a, b, c, w[12], 11, 0xe6db99e5);
00145 HH(c, d, a, b, w[15], 16, 0x1fa27cf8);
00146 HH(b, c, d, a, w[ 2], 23, 0xc4ac5665);
00147
00148 II(a, b, c, d, w[ 0], 6, 0xf4292244);
00149 II(d, a, b, c, w[ 7], 10, 0x432aff97);
00150 II(c, d, a, b, w[14], 15, 0xab9423a7);
00151 II(b, c, d, a, w[ 5], 21, 0xfc93a039);
00152 II(a, b, c, d, w[12], 6, 0x655b59c3);
00153 II(d, a, b, c, w[ 3], 10, 0x8f0ccc92);
00154 II(c, d, a, b, w[10], 15, 0xffeff47d);
00155 II(b, c, d, a, w[ 1], 21, 0x85845dd1);
00156 II(a, b, c, d, w[ 8], 6, 0x6fa87e4f);
00157 II(d, a, b, c, w[15], 10, 0xfe2ce6e0);
00158 II(c, d, a, b, w[ 6], 15, 0xa3014314);
00159 II(b, c, d, a, w[13], 21, 0x4e0811a1);
00160 II(a, b, c, d, w[ 4], 6, 0xf7537e82);
00161 II(d, a, b, c, w[11], 10, 0xbd3af235);
00162 II(c, d, a, b, w[ 2], 15, 0x2ad7d2bb);
00163 II(b, c, d, a, w[ 9], 21, 0xeb86d391);
00164
00165 p->h[0] += a;
00166 p->h[1] += b;
00167 p->h[2] += c;
00168 p->h[3] += d;
00169 }
00170
00171 #endif
00172
00173
00174 int md5Update(md5Param* p, const byte* data, int size)
00175 {
00176 register int proclength;
00177
00178 p->length += size;
00179 while (size > 0)
00180 {
00181 proclength = ((p->offset + size) > 64) ? (64 - p->offset) : size;
00182 memmove(((byte *) p->data) + p->offset, data, proclength);
00183 size -= proclength;
00184 data += proclength;
00185 p->offset += proclength;
00186
00187 if (p->offset == 64)
00188 {
00189 md5Process(p);
00190 p->offset = 0;
00191 }
00192 }
00193 return 0;
00194 }
00195
00196
00199
00200 static void md5Finish(md5Param* p)
00201
00202 {
00203 register byte *ptr = ((byte *) p->data) + p->offset++;
00204
00205 *(ptr++) = 0x80;
00206
00207 if (p->offset > 56)
00208 {
00209 while (p->offset++ < 64)
00210 *(ptr++) = 0;
00211
00212 md5Process(p);
00213 p->offset = 0;
00214 }
00215
00216 ptr = ((byte *) p->data) + p->offset;
00217 while (p->offset++ < 56)
00218 *(ptr++) = 0;
00219
00220 #if !WORDS_BIGENDIAN
00221 p->data[14] = ((uint32)((p->length << 3) & 0xffffffff));
00222 p->data[15] = ((uint32)(p->length >> 29));
00223 #else
00224 p->data[14] = swapu32((uint32)((p->length << 3) & 0xffffffff));
00225 p->data[15] = swapu32((uint32)(p->length >> 29));
00226 #endif
00227
00228 md5Process(p);
00229
00230 #if 1
00231 p->h[0] = swapu32(p->h[0]);
00232 p->h[1] = swapu32(p->h[1]);
00233 p->h[2] = swapu32(p->h[2]);
00234 p->h[3] = swapu32(p->h[3]);
00235 #endif
00236 p->offset = 0;
00237 }
00238
00239
00240
00241 int md5Digest(md5Param* p, uint32* data)
00242 {
00243 md5Finish(p);
00244 mp32copy(4, data, p->h);
00245 (void) md5Reset(p);
00246 return 0;
00247 }
00248