File indexing completed on 2026-04-09 07:49:24
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
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #ifndef HAVE_OPENSSL
0059
0060 #include <cstring>
0061
0062 #include "md5.hh"
0063
0064
0065
0066
0067
0068
0069
0070
0071 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
0072 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
0073 #define H(x, y, z) (((x) ^ (y)) ^ (z))
0074 #define H2(x, y, z) ((x) ^ ((y) ^ (z)))
0075 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
0076
0077
0078
0079
0080 #define STEP(f, a, b, c, d, x, t, s) \
0081 (a) += f((b), (c), (d)) + (x) + (t); \
0082 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
0083 (a) += (b);
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
0094 #define SET(n) \
0095 (*(MD5_u32plus *)&ptr[(n) * 4])
0096 #define GET(n) \
0097 SET(n)
0098 #else
0099 #define SET(n) \
0100 (ctx->block[(n)] = \
0101 (MD5_u32plus)ptr[(n) * 4] | \
0102 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
0103 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
0104 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
0105 #define GET(n) \
0106 (ctx->block[(n)])
0107 #endif
0108
0109
0110
0111
0112
0113 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
0114 {
0115 const unsigned char *ptr;
0116 MD5_u32plus a, b, c, d;
0117 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
0118
0119 ptr = (const unsigned char *)data;
0120
0121 a = ctx->a;
0122 b = ctx->b;
0123 c = ctx->c;
0124 d = ctx->d;
0125
0126 do {
0127 saved_a = a;
0128 saved_b = b;
0129 saved_c = c;
0130 saved_d = d;
0131
0132
0133 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
0134 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
0135 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
0136 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
0137 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
0138 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
0139 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
0140 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
0141 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
0142 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
0143 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
0144 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
0145 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
0146 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
0147 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
0148 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
0149
0150
0151 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
0152 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
0153 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
0154 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
0155 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
0156 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
0157 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
0158 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
0159 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
0160 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
0161 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
0162 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
0163 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
0164 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
0165 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
0166 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
0167
0168
0169 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
0170 STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
0171 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
0172 STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
0173 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
0174 STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
0175 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
0176 STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
0177 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
0178 STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
0179 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
0180 STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
0181 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
0182 STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
0183 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
0184 STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
0185
0186
0187 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
0188 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
0189 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
0190 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
0191 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
0192 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
0193 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
0194 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
0195 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
0196 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
0197 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
0198 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
0199 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
0200 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
0201 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
0202 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
0203
0204 a += saved_a;
0205 b += saved_b;
0206 c += saved_c;
0207 d += saved_d;
0208
0209 ptr += 64;
0210 } while (size -= 64);
0211
0212 ctx->a = a;
0213 ctx->b = b;
0214 ctx->c = c;
0215 ctx->d = d;
0216
0217 return ptr;
0218 }
0219
0220 void MD5_Init(MD5_CTX *ctx)
0221 {
0222 ctx->a = 0x67452301;
0223 ctx->b = 0xefcdab89;
0224 ctx->c = 0x98badcfe;
0225 ctx->d = 0x10325476;
0226
0227 ctx->lo = 0;
0228 ctx->hi = 0;
0229 }
0230
0231 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
0232 {
0233 MD5_u32plus saved_lo;
0234 unsigned long used, available;
0235
0236 saved_lo = ctx->lo;
0237 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
0238 ctx->hi++;
0239 ctx->hi += size >> 29;
0240
0241 used = saved_lo & 0x3f;
0242
0243 if (used) {
0244 available = 64 - used;
0245
0246 if (size < available) {
0247 memcpy(&ctx->buffer[used], data, size);
0248 return;
0249 }
0250
0251 memcpy(&ctx->buffer[used], data, available);
0252 data = (const unsigned char *)data + available;
0253 size -= available;
0254 body(ctx, ctx->buffer, 64);
0255 }
0256
0257 if (size >= 64) {
0258 data = body(ctx, data, size & ~(unsigned long)0x3f);
0259 size &= 0x3f;
0260 }
0261
0262 memcpy(ctx->buffer, data, size);
0263 }
0264
0265
0266
0267 #ifdef _MSC_VER
0268
0269 #pragma warning( disable : 4244 )
0270 #endif
0271
0272 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
0273 {
0274 unsigned long used, available;
0275
0276 used = ctx->lo & 0x3f;
0277
0278 ctx->buffer[used++] = 0x80;
0279
0280 available = 64 - used;
0281
0282 if (available < 8) {
0283 memset(&ctx->buffer[used], 0, available);
0284 body(ctx, ctx->buffer, 64);
0285 used = 0;
0286 available = 64;
0287 }
0288
0289 memset(&ctx->buffer[used], 0, available - 8);
0290
0291 ctx->lo <<= 3;
0292 ctx->buffer[56] = ctx->lo;
0293 ctx->buffer[57] = ctx->lo >> 8;
0294 ctx->buffer[58] = ctx->lo >> 16;
0295 ctx->buffer[59] = ctx->lo >> 24;
0296 ctx->buffer[60] = ctx->hi;
0297 ctx->buffer[61] = ctx->hi >> 8;
0298 ctx->buffer[62] = ctx->hi >> 16;
0299 ctx->buffer[63] = ctx->hi >> 24;
0300
0301 body(ctx, ctx->buffer, 64);
0302
0303 result[0] = ctx->a;
0304 result[1] = ctx->a >> 8;
0305 result[2] = ctx->a >> 16;
0306 result[3] = ctx->a >> 24;
0307 result[4] = ctx->b;
0308 result[5] = ctx->b >> 8;
0309 result[6] = ctx->b >> 16;
0310 result[7] = ctx->b >> 24;
0311 result[8] = ctx->c;
0312 result[9] = ctx->c >> 8;
0313 result[10] = ctx->c >> 16;
0314 result[11] = ctx->c >> 24;
0315 result[12] = ctx->d;
0316 result[13] = ctx->d >> 8;
0317 result[14] = ctx->d >> 16;
0318 result[15] = ctx->d >> 24;
0319
0320 memset(ctx, 0, sizeof(*ctx));
0321 }
0322
0323 #endif