00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef HAVE_OPENSSL
00039
00040 #include <ace/config-all.h>
00041
00042 #include <string.h>
00043
00044 #include "md5.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00054 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
00055 #define H(x, y, z) ((x) ^ (y) ^ (z))
00056 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
00057
00058
00059
00060
00061 #define STEP(f, a, b, c, d, x, t, s) \
00062 (a) += f((b), (c), (d)) + (x) + (t); \
00063 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
00064 (a) += (b);
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
00075 #define SET(n) \
00076 (*(MD5_u32plus *)&ptr[(n) * 4])
00077 #define GET(n) \
00078 SET(n)
00079 #else
00080 #define SET(n) \
00081 (ctx->block[(n)] = \
00082 (MD5_u32plus)ptr[(n) * 4] | \
00083 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
00084 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
00085 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
00086 #define GET(n) \
00087 (ctx->block[(n)])
00088 #endif
00089
00090
00091
00092
00093
00094 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
00095 {
00096 const unsigned char *ptr;
00097 MD5_u32plus a, b, c, d;
00098 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
00099
00100 ptr = (const unsigned char *) data;
00101
00102 a = ctx->a;
00103 b = ctx->b;
00104 c = ctx->c;
00105 d = ctx->d;
00106
00107 do {
00108 saved_a = a;
00109 saved_b = b;
00110 saved_c = c;
00111 saved_d = d;
00112
00113
00114 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
00115 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
00116 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
00117 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
00118 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
00119 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
00120 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
00121 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
00122 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
00123 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
00124 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
00125 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
00126 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
00127 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
00128 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
00129 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
00130
00131
00132 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
00133 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
00134 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
00135 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
00136 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
00137 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
00138 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
00139 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
00140 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
00141 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
00142 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
00143 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
00144 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
00145 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
00146 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
00147 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
00148
00149
00150 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
00151 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
00152 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
00153 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
00154 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
00155 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
00156 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
00157 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
00158 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
00159 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
00160 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
00161 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
00162 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
00163 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
00164 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
00165 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
00166
00167
00168 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
00169 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
00170 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
00171 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
00172 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
00173 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
00174 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
00175 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
00176 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
00177 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
00178 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
00179 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
00180 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
00181 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
00182 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
00183 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
00184
00185 a += saved_a;
00186 b += saved_b;
00187 c += saved_c;
00188 d += saved_d;
00189
00190 ptr += 64;
00191 } while (size -= 64);
00192
00193 ctx->a = a;
00194 ctx->b = b;
00195 ctx->c = c;
00196 ctx->d = d;
00197
00198 return ptr;
00199 }
00200
00201 void MD5_Init(MD5_CTX *ctx)
00202 {
00203 ctx->a = 0x67452301;
00204 ctx->b = 0xefcdab89;
00205 ctx->c = 0x98badcfe;
00206 ctx->d = 0x10325476;
00207
00208 ctx->lo = 0;
00209 ctx->hi = 0;
00210 }
00211
00212 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
00213 {
00214 MD5_u32plus saved_lo;
00215 unsigned long used;
00216
00217 saved_lo = ctx->lo;
00218 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
00219 ctx->hi++;
00220 ctx->hi += size >> 29;
00221
00222 used = saved_lo & 0x3f;
00223
00224 if (used) {
00225 unsigned long free = 64 - used;
00226
00227 if (size < free) {
00228 memcpy(&ctx->buffer[used], data, size);
00229 return;
00230 }
00231
00232 memcpy(&ctx->buffer[used], data, free);
00233 data = (unsigned char *)data + free;
00234 size -= free;
00235 body(ctx, ctx->buffer, 64);
00236 }
00237
00238 if (size >= 64) {
00239 data = body(ctx, data, size & ~(unsigned long)0x3f);
00240 size &= 0x3f;
00241 }
00242
00243 memcpy(ctx->buffer, data, size);
00244 }
00245
00246 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
00247 {
00248 unsigned long used, free;
00249
00250 used = ctx->lo & 0x3f;
00251
00252 ctx->buffer[used++] = 0x80;
00253
00254 free = 64 - used;
00255
00256 if (free < 8) {
00257 memset(&ctx->buffer[used], 0, free);
00258 body(ctx, ctx->buffer, 64);
00259 used = 0;
00260 free = 64;
00261 }
00262
00263 memset(&ctx->buffer[used], 0, free - 8);
00264
00265 ctx->lo <<= 3;
00266 ctx->buffer[56] = ctx->lo;
00267 ctx->buffer[57] = ctx->lo >> 8;
00268 ctx->buffer[58] = ctx->lo >> 16;
00269 ctx->buffer[59] = ctx->lo >> 24;
00270 ctx->buffer[60] = ctx->hi;
00271 ctx->buffer[61] = ctx->hi >> 8;
00272 ctx->buffer[62] = ctx->hi >> 16;
00273 ctx->buffer[63] = ctx->hi >> 24;
00274
00275 body(ctx, ctx->buffer, 64);
00276
00277 result[0] = ctx->a;
00278 result[1] = ctx->a >> 8;
00279 result[2] = ctx->a >> 16;
00280 result[3] = ctx->a >> 24;
00281 result[4] = ctx->b;
00282 result[5] = ctx->b >> 8;
00283 result[6] = ctx->b >> 16;
00284 result[7] = ctx->b >> 24;
00285 result[8] = ctx->c;
00286 result[9] = ctx->c >> 8;
00287 result[10] = ctx->c >> 16;
00288 result[11] = ctx->c >> 24;
00289 result[12] = ctx->d;
00290 result[13] = ctx->d >> 8;
00291 result[14] = ctx->d >> 16;
00292 result[15] = ctx->d >> 24;
00293
00294 memset(ctx, 0, sizeof(*ctx));
00295 }
00296
00297 #endif