File indexing completed on 2025-08-03 08:20:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include "md5.h"
0038
0039 #include <string.h>
0040
0041
0042 #ifdef TEST
0043
0044
0045
0046
0047
0048 #include <string.h>
0049 main()
0050 {
0051 static const char *const test[7] = {
0052 "",
0053 "a",
0054 "abc",
0055 "message digest",
0056 "abcdefghijklmnopqrstuvwxyz",
0057 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
0058
0059 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
0060 };
0061 int i;
0062
0063 for (i = 0; i < 7; ++i) {
0064 md5_state_t state;
0065 md5_byte_t digest[16];
0066 int di;
0067
0068 md5_init(&state);
0069 md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
0070 md5_finish(&state, digest);
0071 printf("MD5 (\"%s\") = ", test[i]);
0072 for (di = 0; di < 16; ++di)
0073 printf("%02x", digest[di]);
0074 printf("\n");
0075 }
0076 return 0;
0077 }
0078 #endif
0079
0080
0081
0082
0083
0084 #if 0
0085 #include <math.h>
0086 main()
0087 {
0088 int i;
0089 for (i = 1; i <= 64; ++i) {
0090 unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
0091 printf("#define T%d 0x%08lx\n", i, v);
0092 }
0093 return 0;
0094 }
0095 #endif
0096
0097
0098
0099 #define T1 0xd76aa478
0100 #define T2 0xe8c7b756
0101 #define T3 0x242070db
0102 #define T4 0xc1bdceee
0103 #define T5 0xf57c0faf
0104 #define T6 0x4787c62a
0105 #define T7 0xa8304613
0106 #define T8 0xfd469501
0107 #define T9 0x698098d8
0108 #define T10 0x8b44f7af
0109 #define T11 0xffff5bb1
0110 #define T12 0x895cd7be
0111 #define T13 0x6b901122
0112 #define T14 0xfd987193
0113 #define T15 0xa679438e
0114 #define T16 0x49b40821
0115 #define T17 0xf61e2562
0116 #define T18 0xc040b340
0117 #define T19 0x265e5a51
0118 #define T20 0xe9b6c7aa
0119 #define T21 0xd62f105d
0120 #define T22 0x02441453
0121 #define T23 0xd8a1e681
0122 #define T24 0xe7d3fbc8
0123 #define T25 0x21e1cde6
0124 #define T26 0xc33707d6
0125 #define T27 0xf4d50d87
0126 #define T28 0x455a14ed
0127 #define T29 0xa9e3e905
0128 #define T30 0xfcefa3f8
0129 #define T31 0x676f02d9
0130 #define T32 0x8d2a4c8a
0131 #define T33 0xfffa3942
0132 #define T34 0x8771f681
0133 #define T35 0x6d9d6122
0134 #define T36 0xfde5380c
0135 #define T37 0xa4beea44
0136 #define T38 0x4bdecfa9
0137 #define T39 0xf6bb4b60
0138 #define T40 0xbebfbc70
0139 #define T41 0x289b7ec6
0140 #define T42 0xeaa127fa
0141 #define T43 0xd4ef3085
0142 #define T44 0x04881d05
0143 #define T45 0xd9d4d039
0144 #define T46 0xe6db99e5
0145 #define T47 0x1fa27cf8
0146 #define T48 0xc4ac5665
0147 #define T49 0xf4292244
0148 #define T50 0x432aff97
0149 #define T51 0xab9423a7
0150 #define T52 0xfc93a039
0151 #define T53 0x655b59c3
0152 #define T54 0x8f0ccc92
0153 #define T55 0xffeff47d
0154 #define T56 0x85845dd1
0155 #define T57 0x6fa87e4f
0156 #define T58 0xfe2ce6e0
0157 #define T59 0xa3014314
0158 #define T60 0x4e0811a1
0159 #define T61 0xf7537e82
0160 #define T62 0xbd3af235
0161 #define T63 0x2ad7d2bb
0162 #define T64 0xeb86d391
0163
0164 static void
0165 md5_process(md5_state_t *pms, const md5_byte_t *data )
0166 {
0167 md5_word_t
0168 a = pms->abcd[0], b = pms->abcd[1],
0169 c = pms->abcd[2], d = pms->abcd[3];
0170 md5_word_t t;
0171
0172 #ifndef ARCH_IS_BIG_ENDIAN
0173 # define ARCH_IS_BIG_ENDIAN 1
0174 #endif
0175 #if ARCH_IS_BIG_ENDIAN
0176
0177
0178
0179
0180
0181 md5_word_t X[16];
0182 const md5_byte_t *xp = data;
0183 int i;
0184
0185 for (i = 0; i < 16; ++i, xp += 4)
0186 X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
0187
0188 #else
0189
0190
0191
0192
0193
0194 md5_word_t xbuf[16];
0195 const md5_word_t *X;
0196
0197 if (!((data - (const md5_byte_t *)0) & 3)) {
0198
0199 X = (const md5_word_t *)data;
0200 } else {
0201
0202 memcpy(xbuf, data, 64);
0203 X = xbuf;
0204 }
0205 #endif
0206
0207 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
0208
0209
0210
0211
0212 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
0213 #define SET(a, b, c, d, k, s, Ti)\
0214 t = a + F(b,c,d) + X[k] + Ti;\
0215 a = ROTATE_LEFT(t, s) + b
0216
0217 SET(a, b, c, d, 0, 7, T1);
0218 SET(d, a, b, c, 1, 12, T2);
0219 SET(c, d, a, b, 2, 17, T3);
0220 SET(b, c, d, a, 3, 22, T4);
0221 SET(a, b, c, d, 4, 7, T5);
0222 SET(d, a, b, c, 5, 12, T6);
0223 SET(c, d, a, b, 6, 17, T7);
0224 SET(b, c, d, a, 7, 22, T8);
0225 SET(a, b, c, d, 8, 7, T9);
0226 SET(d, a, b, c, 9, 12, T10);
0227 SET(c, d, a, b, 10, 17, T11);
0228 SET(b, c, d, a, 11, 22, T12);
0229 SET(a, b, c, d, 12, 7, T13);
0230 SET(d, a, b, c, 13, 12, T14);
0231 SET(c, d, a, b, 14, 17, T15);
0232 SET(b, c, d, a, 15, 22, T16);
0233 #undef SET
0234
0235
0236
0237
0238 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
0239 #define SET(a, b, c, d, k, s, Ti)\
0240 t = a + G(b,c,d) + X[k] + Ti;\
0241 a = ROTATE_LEFT(t, s) + b
0242
0243 SET(a, b, c, d, 1, 5, T17);
0244 SET(d, a, b, c, 6, 9, T18);
0245 SET(c, d, a, b, 11, 14, T19);
0246 SET(b, c, d, a, 0, 20, T20);
0247 SET(a, b, c, d, 5, 5, T21);
0248 SET(d, a, b, c, 10, 9, T22);
0249 SET(c, d, a, b, 15, 14, T23);
0250 SET(b, c, d, a, 4, 20, T24);
0251 SET(a, b, c, d, 9, 5, T25);
0252 SET(d, a, b, c, 14, 9, T26);
0253 SET(c, d, a, b, 3, 14, T27);
0254 SET(b, c, d, a, 8, 20, T28);
0255 SET(a, b, c, d, 13, 5, T29);
0256 SET(d, a, b, c, 2, 9, T30);
0257 SET(c, d, a, b, 7, 14, T31);
0258 SET(b, c, d, a, 12, 20, T32);
0259 #undef SET
0260
0261
0262
0263
0264 #define H(x, y, z) ((x) ^ (y) ^ (z))
0265 #define SET(a, b, c, d, k, s, Ti)\
0266 t = a + H(b,c,d) + X[k] + Ti;\
0267 a = ROTATE_LEFT(t, s) + b
0268
0269 SET(a, b, c, d, 5, 4, T33);
0270 SET(d, a, b, c, 8, 11, T34);
0271 SET(c, d, a, b, 11, 16, T35);
0272 SET(b, c, d, a, 14, 23, T36);
0273 SET(a, b, c, d, 1, 4, T37);
0274 SET(d, a, b, c, 4, 11, T38);
0275 SET(c, d, a, b, 7, 16, T39);
0276 SET(b, c, d, a, 10, 23, T40);
0277 SET(a, b, c, d, 13, 4, T41);
0278 SET(d, a, b, c, 0, 11, T42);
0279 SET(c, d, a, b, 3, 16, T43);
0280 SET(b, c, d, a, 6, 23, T44);
0281 SET(a, b, c, d, 9, 4, T45);
0282 SET(d, a, b, c, 12, 11, T46);
0283 SET(c, d, a, b, 15, 16, T47);
0284 SET(b, c, d, a, 2, 23, T48);
0285 #undef SET
0286
0287
0288
0289
0290 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
0291 #define SET(a, b, c, d, k, s, Ti)\
0292 t = a + I(b,c,d) + X[k] + Ti;\
0293 a = ROTATE_LEFT(t, s) + b
0294
0295 SET(a, b, c, d, 0, 6, T49);
0296 SET(d, a, b, c, 7, 10, T50);
0297 SET(c, d, a, b, 14, 15, T51);
0298 SET(b, c, d, a, 5, 21, T52);
0299 SET(a, b, c, d, 12, 6, T53);
0300 SET(d, a, b, c, 3, 10, T54);
0301 SET(c, d, a, b, 10, 15, T55);
0302 SET(b, c, d, a, 1, 21, T56);
0303 SET(a, b, c, d, 8, 6, T57);
0304 SET(d, a, b, c, 15, 10, T58);
0305 SET(c, d, a, b, 6, 15, T59);
0306 SET(b, c, d, a, 13, 21, T60);
0307 SET(a, b, c, d, 4, 6, T61);
0308 SET(d, a, b, c, 11, 10, T62);
0309 SET(c, d, a, b, 2, 15, T63);
0310 SET(b, c, d, a, 9, 21, T64);
0311 #undef SET
0312
0313
0314
0315
0316 pms->abcd[0] += a;
0317 pms->abcd[1] += b;
0318 pms->abcd[2] += c;
0319 pms->abcd[3] += d;
0320 }
0321
0322 void
0323 md5_init(md5_state_t *pms)
0324 {
0325 pms->count[0] = pms->count[1] = 0;
0326 pms->abcd[0] = 0x67452301;
0327 pms->abcd[1] = 0xefcdab89;
0328 pms->abcd[2] = 0x98badcfe;
0329 pms->abcd[3] = 0x10325476;
0330 }
0331
0332 void
0333 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
0334 {
0335 const md5_byte_t *p = data;
0336 int left = nbytes;
0337 int offset = (pms->count[0] >> 3) & 63;
0338 md5_word_t nbits = (md5_word_t)(nbytes << 3);
0339
0340 if (nbytes <= 0)
0341 return;
0342
0343
0344 pms->count[1] += nbytes >> 29;
0345 pms->count[0] += nbits;
0346 if (pms->count[0] < nbits)
0347 pms->count[1]++;
0348
0349
0350 if (offset) {
0351 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
0352
0353 memcpy(pms->buf + offset, p, copy);
0354 if (offset + copy < 64)
0355 return;
0356 p += copy;
0357 left -= copy;
0358 md5_process(pms, pms->buf);
0359 }
0360
0361
0362 for (; left >= 64; p += 64, left -= 64)
0363 md5_process(pms, p);
0364
0365
0366 if (left)
0367 memcpy(pms->buf, p, left);
0368 }
0369
0370 void
0371 md5_finish(md5_state_t *pms, md5_byte_t digest[16])
0372 {
0373 static const md5_byte_t pad[64] = {
0374 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0376 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0378 };
0379 md5_byte_t data[8];
0380 int i;
0381
0382
0383 for (i = 0; i < 8; ++i)
0384 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
0385
0386 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
0387
0388 md5_append(pms, data, 8);
0389 for (i = 0; i < 16; ++i)
0390 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
0391 }