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