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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #include <stdio.h>
00089
00090 #include "gwlib.h"
00091 #include "md5.h"
00092
00093
00094
00095 static void md5_digest(char *md5str, unsigned char *digest);
00096 static void md5_init(md5_ctx *);
00097 static void md5_update(md5_ctx *, const unsigned char *, unsigned int);
00098 static void md5_final(unsigned char[16], md5_ctx *);
00099
00100
00101
00102 static void md5_digest(char *md5str, unsigned char *digest)
00103 {
00104 int i;
00105
00106 for (i = 0; i < 16; i++) {
00107 sprintf(md5str, "%02x", digest[i]);
00108 md5str += 2;
00109 }
00110
00111 *md5str = '\0';
00112 }
00113
00114
00115
00116
00117 #define S11 7
00118 #define S12 12
00119 #define S13 17
00120 #define S14 22
00121 #define S21 5
00122 #define S22 9
00123 #define S23 14
00124 #define S24 20
00125 #define S31 4
00126 #define S32 11
00127 #define S33 16
00128 #define S34 23
00129 #define S41 6
00130 #define S42 10
00131 #define S43 15
00132 #define S44 21
00133
00134 static void md5_transform(unsigned int[4], const unsigned char[64]);
00135 static void md5_encode(unsigned char *, unsigned int *, unsigned int);
00136 static void md5_decode(unsigned int *, const unsigned char *, unsigned int);
00137
00138 static unsigned char PADDING[64] =
00139 {
00140 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00143 };
00144
00145
00146
00147 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00148 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00149 #define H(x, y, z) ((x) ^ (y) ^ (z))
00150 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00151
00152
00153
00154 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00155
00156
00157
00158
00159 #define FF(a, b, c, d, x, s, ac) { \
00160 (a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00161 (a) = ROTATE_LEFT ((a), (s)); \
00162 (a) += (b); \
00163 }
00164 #define GG(a, b, c, d, x, s, ac) { \
00165 (a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00166 (a) = ROTATE_LEFT ((a), (s)); \
00167 (a) += (b); \
00168 }
00169 #define HH(a, b, c, d, x, s, ac) { \
00170 (a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00171 (a) = ROTATE_LEFT ((a), (s)); \
00172 (a) += (b); \
00173 }
00174 #define II(a, b, c, d, x, s, ac) { \
00175 (a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00176 (a) = ROTATE_LEFT ((a), (s)); \
00177 (a) += (b); \
00178 }
00179
00180 static void md5_init(md5_ctx *context)
00181 {
00182 context->count[0] = context->count[1] = 0;
00183
00184 context->state[0] = 0x67452301;
00185 context->state[1] = 0xefcdab89;
00186 context->state[2] = 0x98badcfe;
00187 context->state[3] = 0x10325476;
00188 }
00189
00190
00191
00192
00193
00194
00195 static void md5_update(md5_ctx *context, const unsigned char *input,
00196 unsigned int inputLen)
00197 {
00198 unsigned int i, index, partLen;
00199
00200
00201 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00202
00203
00204 if ((context->count[0] += ((unsigned int) inputLen << 3))
00205 < ((unsigned int) inputLen << 3))
00206 context->count[1]++;
00207 context->count[1] += ((unsigned int) inputLen >> 29);
00208
00209 partLen = 64 - index;
00210
00211
00212 if (inputLen >= partLen) {
00213 memcpy((unsigned char*) & context->buffer[index],
00214 (unsigned char*) input, partLen);
00215 md5_transform(context->state, context->buffer);
00216
00217 for (i = partLen; i + 63 < inputLen; i += 64)
00218 md5_transform(context->state, &input[i]);
00219
00220 index = 0;
00221 } else
00222 i = 0;
00223
00224
00225 memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
00226 inputLen - i);
00227 }
00228
00229
00230
00231
00232
00233 static void md5_final(unsigned char digest[16], md5_ctx *context)
00234 {
00235 unsigned char bits[8];
00236 unsigned int index, padLen;
00237
00238
00239 md5_encode(bits, context->count, 8);
00240
00241
00242
00243 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00244 padLen = (index < 56) ? (56 - index) : (120 - index);
00245 md5_update(context, PADDING, padLen);
00246
00247
00248 md5_update(context, bits, 8);
00249
00250
00251 md5_encode(digest, context->state, 16);
00252
00253
00254
00255 memset((unsigned char*) context, 0, sizeof(*context));
00256 }
00257
00258
00259
00260
00261
00262 static void md5_transform(state, block)
00263 unsigned int state[4];
00264 const unsigned char block[64];
00265 {
00266 unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00267
00268 md5_decode(x, block, 64);
00269
00270
00271 FF(a, b, c, d, x[0], S11, 0xd76aa478);
00272 FF(d, a, b, c, x[1], S12, 0xe8c7b756);
00273 FF(c, d, a, b, x[2], S13, 0x242070db);
00274 FF(b, c, d, a, x[3], S14, 0xc1bdceee);
00275 FF(a, b, c, d, x[4], S11, 0xf57c0faf);
00276 FF(d, a, b, c, x[5], S12, 0x4787c62a);
00277 FF(c, d, a, b, x[6], S13, 0xa8304613);
00278 FF(b, c, d, a, x[7], S14, 0xfd469501);
00279 FF(a, b, c, d, x[8], S11, 0x698098d8);
00280 FF(d, a, b, c, x[9], S12, 0x8b44f7af);
00281 FF(c, d, a, b, x[10], S13, 0xffff5bb1);
00282 FF(b, c, d, a, x[11], S14, 0x895cd7be);
00283 FF(a, b, c, d, x[12], S11, 0x6b901122);
00284 FF(d, a, b, c, x[13], S12, 0xfd987193);
00285 FF(c, d, a, b, x[14], S13, 0xa679438e);
00286 FF(b, c, d, a, x[15], S14, 0x49b40821);
00287
00288
00289 GG(a, b, c, d, x[1], S21, 0xf61e2562);
00290 GG(d, a, b, c, x[6], S22, 0xc040b340);
00291 GG(c, d, a, b, x[11], S23, 0x265e5a51);
00292 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);
00293 GG(a, b, c, d, x[5], S21, 0xd62f105d);
00294 GG(d, a, b, c, x[10], S22, 0x2441453);
00295 GG(c, d, a, b, x[15], S23, 0xd8a1e681);
00296 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);
00297 GG(a, b, c, d, x[9], S21, 0x21e1cde6);
00298 GG(d, a, b, c, x[14], S22, 0xc33707d6);
00299 GG(c, d, a, b, x[3], S23, 0xf4d50d87);
00300 GG(b, c, d, a, x[8], S24, 0x455a14ed);
00301 GG(a, b, c, d, x[13], S21, 0xa9e3e905);
00302 GG(d, a, b, c, x[2], S22, 0xfcefa3f8);
00303 GG(c, d, a, b, x[7], S23, 0x676f02d9);
00304 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);
00305
00306
00307 HH(a, b, c, d, x[5], S31, 0xfffa3942);
00308 HH(d, a, b, c, x[8], S32, 0x8771f681);
00309 HH(c, d, a, b, x[11], S33, 0x6d9d6122);
00310 HH(b, c, d, a, x[14], S34, 0xfde5380c);
00311 HH(a, b, c, d, x[1], S31, 0xa4beea44);
00312 HH(d, a, b, c, x[4], S32, 0x4bdecfa9);
00313 HH(c, d, a, b, x[7], S33, 0xf6bb4b60);
00314 HH(b, c, d, a, x[10], S34, 0xbebfbc70);
00315 HH(a, b, c, d, x[13], S31, 0x289b7ec6);
00316 HH(d, a, b, c, x[0], S32, 0xeaa127fa);
00317 HH(c, d, a, b, x[3], S33, 0xd4ef3085);
00318 HH(b, c, d, a, x[6], S34, 0x4881d05);
00319 HH(a, b, c, d, x[9], S31, 0xd9d4d039);
00320 HH(d, a, b, c, x[12], S32, 0xe6db99e5);
00321 HH(c, d, a, b, x[15], S33, 0x1fa27cf8);
00322 HH(b, c, d, a, x[2], S34, 0xc4ac5665);
00323
00324
00325 II(a, b, c, d, x[0], S41, 0xf4292244);
00326 II(d, a, b, c, x[7], S42, 0x432aff97);
00327 II(c, d, a, b, x[14], S43, 0xab9423a7);
00328 II(b, c, d, a, x[5], S44, 0xfc93a039);
00329 II(a, b, c, d, x[12], S41, 0x655b59c3);
00330 II(d, a, b, c, x[3], S42, 0x8f0ccc92);
00331 II(c, d, a, b, x[10], S43, 0xffeff47d);
00332 II(b, c, d, a, x[1], S44, 0x85845dd1);
00333 II(a, b, c, d, x[8], S41, 0x6fa87e4f);
00334 II(d, a, b, c, x[15], S42, 0xfe2ce6e0);
00335 II(c, d, a, b, x[6], S43, 0xa3014314);
00336 II(b, c, d, a, x[13], S44, 0x4e0811a1);
00337 II(a, b, c, d, x[4], S41, 0xf7537e82);
00338 II(d, a, b, c, x[11], S42, 0xbd3af235);
00339 II(c, d, a, b, x[2], S43, 0x2ad7d2bb);
00340 II(b, c, d, a, x[9], S44, 0xeb86d391);
00341
00342 state[0] += a;
00343 state[1] += b;
00344 state[2] += c;
00345 state[3] += d;
00346
00347
00348 memset((unsigned char*) x, 0, sizeof(x));
00349 }
00350
00351
00352
00353
00354
00355 static void md5_encode(output, input, len)
00356 unsigned char *output;
00357 unsigned int *input;
00358 unsigned int len;
00359 {
00360 unsigned int i, j;
00361
00362 for (i = 0, j = 0; j < len; i++, j += 4) {
00363 output[j] = (unsigned char) (input[i] & 0xff);
00364 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
00365 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
00366 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
00367 }
00368 }
00369
00370
00371
00372
00373
00374 static void md5_decode(output, input, len)
00375 unsigned int *output;
00376 const unsigned char *input;
00377 unsigned int len;
00378 {
00379 unsigned int i, j;
00380
00381 for (i = 0, j = 0; j < len; i++, j += 4)
00382 output[i] = ((unsigned int) input[j]) | (((unsigned int) input[j + 1]) << 8) |
00383 (((unsigned int) input[j + 2]) << 16) | (((unsigned int) input[j + 3]) << 24);
00384 }
00385
00386
00387 Octstr *md5(Octstr *data)
00388 {
00389 md5_ctx context;
00390 unsigned char digest[16];
00391 Octstr *enc;
00392
00393 if (data == NULL)
00394 return NULL;
00395
00396 md5_init(&context);
00397 md5_update(&context, octstr_get_cstr(data), octstr_len(data));
00398 md5_final(digest, &context);
00399
00400 enc = octstr_create_from_data(digest, 16);
00401
00402 return enc;
00403 }
00404
00405
00406 Octstr *md5digest(Octstr *data)
00407 {
00408 char md5str[33];
00409 Octstr *digest;
00410
00411 if (data == NULL)
00412 return NULL;
00413
00414 md5str[0] = '\0';
00415 digest = md5(data);
00416 md5_digest(md5str, octstr_get_cstr(digest));
00417 octstr_destroy(digest);
00418
00419 digest = octstr_create(md5str);
00420
00421 return digest;
00422 }
00423
00424
00425
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.