00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 # include <config.h>
00026 #endif
00027
00028 #include <sys/types.h>
00029
00030 #if STDC_HEADERS || defined _LIBC
00031 # include <stdlib.h>
00032 # include <string.h>
00033 #else
00034 # ifndef HAVE_MEMCPY
00035 # define memcpy(d, s, n) bcopy ((s), (d), (n))
00036 # endif
00037 #endif
00038
00039 #include "ansidecl.h"
00040 #include "md5.h"
00041
00042 #ifdef _LIBC
00043 # include <endian.h>
00044 # if __BYTE_ORDER == __BIG_ENDIAN
00045 # define WORDS_BIGENDIAN 1
00046 # endif
00047 #endif
00048
00049 #ifdef WORDS_BIGENDIAN
00050 # define SWAP(n) \
00051 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
00052 #else
00053 # define SWAP(n) (n)
00054 #endif
00055
00056
00057
00058
00059 static const unsigned char fillbuf[64] = { 0x80, 0 };
00060
00061
00062
00063
00064 void
00065 md5_init_ctx (ctx)
00066 struct md5_ctx *ctx;
00067 {
00068 ctx->A = (md5_uint32) 0x67452301;
00069 ctx->B = (md5_uint32) 0xefcdab89;
00070 ctx->C = (md5_uint32) 0x98badcfe;
00071 ctx->D = (md5_uint32) 0x10325476;
00072
00073 ctx->total[0] = ctx->total[1] = 0;
00074 ctx->buflen = 0;
00075 }
00076
00077
00078
00079
00080
00081
00082 void *
00083 md5_read_ctx (ctx, resbuf)
00084 const struct md5_ctx *ctx;
00085 void *resbuf;
00086 {
00087 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
00088 ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
00089 ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
00090 ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
00091
00092 return resbuf;
00093 }
00094
00095
00096
00097
00098
00099
00100 void *
00101 md5_finish_ctx (ctx, resbuf)
00102 struct md5_ctx *ctx;
00103 void *resbuf;
00104 {
00105
00106 md5_uint32 bytes = ctx->buflen;
00107 size_t pad;
00108
00109
00110 ctx->total[0] += bytes;
00111 if (ctx->total[0] < bytes)
00112 ++ctx->total[1];
00113
00114 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
00115 memcpy (&ctx->buffer[bytes], fillbuf, pad);
00116
00117
00118 *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
00119 *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
00120 (ctx->total[0] >> 29));
00121
00122
00123 md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
00124
00125 return md5_read_ctx (ctx, resbuf);
00126 }
00127
00128
00129
00130
00131 int
00132 md5_stream (stream, resblock)
00133 FILE *stream;
00134 void *resblock;
00135 {
00136
00137 #define BLOCKSIZE 4096
00138 struct md5_ctx ctx;
00139 char buffer[BLOCKSIZE + 72];
00140 size_t sum;
00141
00142
00143 md5_init_ctx (&ctx);
00144
00145
00146 while (1)
00147 {
00148
00149
00150
00151 size_t n;
00152 sum = 0;
00153
00154
00155 do
00156 {
00157 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
00158
00159 sum += n;
00160 }
00161 while (sum < BLOCKSIZE && n != 0);
00162 if (n == 0 && ferror (stream))
00163 return 1;
00164
00165
00166 if (n == 0)
00167 break;
00168
00169
00170
00171
00172 md5_process_block (buffer, BLOCKSIZE, &ctx);
00173 }
00174
00175
00176 if (sum > 0)
00177 md5_process_bytes (buffer, sum, &ctx);
00178
00179
00180 md5_finish_ctx (&ctx, resblock);
00181 return 0;
00182 }
00183
00184
00185
00186
00187
00188 void *
00189 md5_buffer (buffer, len, resblock)
00190 const char *buffer;
00191 size_t len;
00192 void *resblock;
00193 {
00194 struct md5_ctx ctx;
00195
00196
00197 md5_init_ctx (&ctx);
00198
00199
00200 md5_process_bytes (buffer, len, &ctx);
00201
00202
00203 return md5_finish_ctx (&ctx, resblock);
00204 }
00205
00206
00207 void
00208 md5_process_bytes (buffer, len, ctx)
00209 const void *buffer;
00210 size_t len;
00211 struct md5_ctx *ctx;
00212 {
00213
00214
00215 if (ctx->buflen != 0)
00216 {
00217 size_t left_over = ctx->buflen;
00218 size_t add = 128 - left_over > len ? len : 128 - left_over;
00219
00220 memcpy (&ctx->buffer[left_over], buffer, add);
00221 ctx->buflen += add;
00222
00223 if (left_over + add > 64)
00224 {
00225 md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
00226
00227 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
00228 (left_over + add) & 63);
00229 ctx->buflen = (left_over + add) & 63;
00230 }
00231
00232 buffer = (const void *) ((const char *) buffer + add);
00233 len -= add;
00234 }
00235
00236
00237 if (len > 64)
00238 {
00239 md5_process_block (buffer, len & ~63, ctx);
00240 buffer = (const void *) ((const char *) buffer + (len & ~63));
00241 len &= 63;
00242 }
00243
00244
00245 if (len > 0)
00246 {
00247 memcpy (ctx->buffer, buffer, len);
00248 ctx->buflen = len;
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257 #define FF(b, c, d) (d ^ (b & (c ^ d)))
00258 #define FG(b, c, d) FF (d, b, c)
00259 #define FH(b, c, d) (b ^ c ^ d)
00260 #define FI(b, c, d) (c ^ (b | ~d))
00261
00262
00263
00264
00265 void
00266 md5_process_block (buffer, len, ctx)
00267 const void *buffer;
00268 size_t len;
00269 struct md5_ctx *ctx;
00270 {
00271 md5_uint32 correct_words[16];
00272 const md5_uint32 *words = (const md5_uint32 *) buffer;
00273 size_t nwords = len / sizeof (md5_uint32);
00274 const md5_uint32 *endp = words + nwords;
00275 md5_uint32 A = ctx->A;
00276 md5_uint32 B = ctx->B;
00277 md5_uint32 C = ctx->C;
00278 md5_uint32 D = ctx->D;
00279
00280
00281
00282
00283 ctx->total[0] += len;
00284 if (ctx->total[0] < len)
00285 ++ctx->total[1];
00286
00287
00288
00289 while (words < endp)
00290 {
00291 md5_uint32 *cwp = correct_words;
00292 md5_uint32 A_save = A;
00293 md5_uint32 B_save = B;
00294 md5_uint32 C_save = C;
00295 md5_uint32 D_save = D;
00296
00297
00298
00299
00300
00301
00302
00303
00304 #define OP(a, b, c, d, s, T) \
00305 do \
00306 { \
00307 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
00308 ++words; \
00309 CYCLIC (a, s); \
00310 a += b; \
00311 } \
00312 while (0)
00313
00314
00315
00316 #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
00317
00318
00319
00320
00321
00322
00323
00324
00325 OP (A, B, C, D, 7, (md5_uint32) 0xd76aa478);
00326 OP (D, A, B, C, 12, (md5_uint32) 0xe8c7b756);
00327 OP (C, D, A, B, 17, (md5_uint32) 0x242070db);
00328 OP (B, C, D, A, 22, (md5_uint32) 0xc1bdceee);
00329 OP (A, B, C, D, 7, (md5_uint32) 0xf57c0faf);
00330 OP (D, A, B, C, 12, (md5_uint32) 0x4787c62a);
00331 OP (C, D, A, B, 17, (md5_uint32) 0xa8304613);
00332 OP (B, C, D, A, 22, (md5_uint32) 0xfd469501);
00333 OP (A, B, C, D, 7, (md5_uint32) 0x698098d8);
00334 OP (D, A, B, C, 12, (md5_uint32) 0x8b44f7af);
00335 OP (C, D, A, B, 17, (md5_uint32) 0xffff5bb1);
00336 OP (B, C, D, A, 22, (md5_uint32) 0x895cd7be);
00337 OP (A, B, C, D, 7, (md5_uint32) 0x6b901122);
00338 OP (D, A, B, C, 12, (md5_uint32) 0xfd987193);
00339 OP (C, D, A, B, 17, (md5_uint32) 0xa679438e);
00340 OP (B, C, D, A, 22, (md5_uint32) 0x49b40821);
00341
00342
00343
00344
00345 #undef OP
00346 #define OP(a, b, c, d, k, s, T) \
00347 do \
00348 { \
00349 a += FX (b, c, d) + correct_words[k] + T; \
00350 CYCLIC (a, s); \
00351 a += b; \
00352 } \
00353 while (0)
00354
00355 #define FX(b, c, d) FG (b, c, d)
00356
00357
00358 OP (A, B, C, D, 1, 5, (md5_uint32) 0xf61e2562);
00359 OP (D, A, B, C, 6, 9, (md5_uint32) 0xc040b340);
00360 OP (C, D, A, B, 11, 14, (md5_uint32) 0x265e5a51);
00361 OP (B, C, D, A, 0, 20, (md5_uint32) 0xe9b6c7aa);
00362 OP (A, B, C, D, 5, 5, (md5_uint32) 0xd62f105d);
00363 OP (D, A, B, C, 10, 9, (md5_uint32) 0x02441453);
00364 OP (C, D, A, B, 15, 14, (md5_uint32) 0xd8a1e681);
00365 OP (B, C, D, A, 4, 20, (md5_uint32) 0xe7d3fbc8);
00366 OP (A, B, C, D, 9, 5, (md5_uint32) 0x21e1cde6);
00367 OP (D, A, B, C, 14, 9, (md5_uint32) 0xc33707d6);
00368 OP (C, D, A, B, 3, 14, (md5_uint32) 0xf4d50d87);
00369 OP (B, C, D, A, 8, 20, (md5_uint32) 0x455a14ed);
00370 OP (A, B, C, D, 13, 5, (md5_uint32) 0xa9e3e905);
00371 OP (D, A, B, C, 2, 9, (md5_uint32) 0xfcefa3f8);
00372 OP (C, D, A, B, 7, 14, (md5_uint32) 0x676f02d9);
00373 OP (B, C, D, A, 12, 20, (md5_uint32) 0x8d2a4c8a);
00374
00375 #undef FX
00376 #define FX(b, c, d) FH (b, c, d)
00377
00378
00379 OP (A, B, C, D, 5, 4, (md5_uint32) 0xfffa3942);
00380 OP (D, A, B, C, 8, 11, (md5_uint32) 0x8771f681);
00381 OP (C, D, A, B, 11, 16, (md5_uint32) 0x6d9d6122);
00382 OP (B, C, D, A, 14, 23, (md5_uint32) 0xfde5380c);
00383 OP (A, B, C, D, 1, 4, (md5_uint32) 0xa4beea44);
00384 OP (D, A, B, C, 4, 11, (md5_uint32) 0x4bdecfa9);
00385 OP (C, D, A, B, 7, 16, (md5_uint32) 0xf6bb4b60);
00386 OP (B, C, D, A, 10, 23, (md5_uint32) 0xbebfbc70);
00387 OP (A, B, C, D, 13, 4, (md5_uint32) 0x289b7ec6);
00388 OP (D, A, B, C, 0, 11, (md5_uint32) 0xeaa127fa);
00389 OP (C, D, A, B, 3, 16, (md5_uint32) 0xd4ef3085);
00390 OP (B, C, D, A, 6, 23, (md5_uint32) 0x04881d05);
00391 OP (A, B, C, D, 9, 4, (md5_uint32) 0xd9d4d039);
00392 OP (D, A, B, C, 12, 11, (md5_uint32) 0xe6db99e5);
00393 OP (C, D, A, B, 15, 16, (md5_uint32) 0x1fa27cf8);
00394 OP (B, C, D, A, 2, 23, (md5_uint32) 0xc4ac5665);
00395
00396 #undef FX
00397 #define FX(b, c, d) FI (b, c, d)
00398
00399
00400 OP (A, B, C, D, 0, 6, (md5_uint32) 0xf4292244);
00401 OP (D, A, B, C, 7, 10, (md5_uint32) 0x432aff97);
00402 OP (C, D, A, B, 14, 15, (md5_uint32) 0xab9423a7);
00403 OP (B, C, D, A, 5, 21, (md5_uint32) 0xfc93a039);
00404 OP (A, B, C, D, 12, 6, (md5_uint32) 0x655b59c3);
00405 OP (D, A, B, C, 3, 10, (md5_uint32) 0x8f0ccc92);
00406 OP (C, D, A, B, 10, 15, (md5_uint32) 0xffeff47d);
00407 OP (B, C, D, A, 1, 21, (md5_uint32) 0x85845dd1);
00408 OP (A, B, C, D, 8, 6, (md5_uint32) 0x6fa87e4f);
00409 OP (D, A, B, C, 15, 10, (md5_uint32) 0xfe2ce6e0);
00410 OP (C, D, A, B, 6, 15, (md5_uint32) 0xa3014314);
00411 OP (B, C, D, A, 13, 21, (md5_uint32) 0x4e0811a1);
00412 OP (A, B, C, D, 4, 6, (md5_uint32) 0xf7537e82);
00413 OP (D, A, B, C, 11, 10, (md5_uint32) 0xbd3af235);
00414 OP (C, D, A, B, 2, 15, (md5_uint32) 0x2ad7d2bb);
00415 OP (B, C, D, A, 9, 21, (md5_uint32) 0xeb86d391);
00416
00417
00418 A += A_save;
00419 B += B_save;
00420 C += C_save;
00421 D += D_save;
00422 }
00423
00424
00425 ctx->A = A;
00426 ctx->B = B;
00427 ctx->C = C;
00428 ctx->D = D;
00429 }