15static inline uint32_t rotl(uint32_t v,
unsigned n)
17 return (v << n) | (v >> (32 - n));
19static inline uint32_t rd32le(
const uint8_t *p)
21 return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
23static inline void wr32le(uint8_t *p, uint32_t v)
26 p[1] = (uint8_t)(v >> 8);
27 p[2] = (uint8_t)(v >> 16);
28 p[3] = (uint8_t)(v >> 24);
33static const uint32_t MD5_K[64] = {
34 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
35 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
36 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
37 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
38 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
39 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
40 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
41 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
43static const uint8_t MD5_S[64] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
44 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
45 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
46 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
48static void md5_compress(uint32_t s[4],
const uint8_t block[64])
51 for (
int i = 0; i < 16; i++)
52 m[i] = rd32le(block + i * 4);
57 for (
int i = 0; i < 64; i++)
63 f = (b & c) | (~b & d);
68 f = (d & b) | (~d & c);
81 f += a + MD5_K[i] + m[g];
85 b += rotl(f, MD5_S[i]);
93void md5_init(MdCtx *c)
95 c->state[0] = 0x67452301;
96 c->state[1] = 0xefcdab89;
97 c->state[2] = 0x98badcfe;
98 c->state[3] = 0x10325476;
105static void md4_compress(uint32_t s[4],
const uint8_t block[64])
108 for (
int i = 0; i < 16; i++)
109 x[i] = rd32le(block + i * 4);
114#define F4(X, Y, Z) (((X) & (Y)) | (~(X) & (Z)))
115#define G4(X, Y, Z) (((X) & (Y)) | ((X) & (Z)) | ((Y) & (Z)))
116#define H4(X, Y, Z) ((X) ^ (Y) ^ (Z))
117#define R1(A, B, C, D, K, S) A = rotl((uint32_t)(A + F4(B, C, D) + x[K]), S)
118#define R2(A, B, C, D, K, S) A = rotl((uint32_t)(A + G4(B, C, D) + x[K] + 0x5a827999u), S)
119#define R3(A, B, C, D, K, S) A = rotl((uint32_t)(A + H4(B, C, D) + x[K] + 0x6ed9eba1u), S)
120 R1(a, b, c, d, 0, 3);
121 R1(d, a, b, c, 1, 7);
122 R1(c, d, a, b, 2, 11);
123 R1(b, c, d, a, 3, 19);
124 R1(a, b, c, d, 4, 3);
125 R1(d, a, b, c, 5, 7);
126 R1(c, d, a, b, 6, 11);
127 R1(b, c, d, a, 7, 19);
128 R1(a, b, c, d, 8, 3);
129 R1(d, a, b, c, 9, 7);
130 R1(c, d, a, b, 10, 11);
131 R1(b, c, d, a, 11, 19);
132 R1(a, b, c, d, 12, 3);
133 R1(d, a, b, c, 13, 7);
134 R1(c, d, a, b, 14, 11);
135 R1(b, c, d, a, 15, 19);
136 R2(a, b, c, d, 0, 3);
137 R2(d, a, b, c, 4, 5);
138 R2(c, d, a, b, 8, 9);
139 R2(b, c, d, a, 12, 13);
140 R2(a, b, c, d, 1, 3);
141 R2(d, a, b, c, 5, 5);
142 R2(c, d, a, b, 9, 9);
143 R2(b, c, d, a, 13, 13);
144 R2(a, b, c, d, 2, 3);
145 R2(d, a, b, c, 6, 5);
146 R2(c, d, a, b, 10, 9);
147 R2(b, c, d, a, 14, 13);
148 R2(a, b, c, d, 3, 3);
149 R2(d, a, b, c, 7, 5);
150 R2(c, d, a, b, 11, 9);
151 R2(b, c, d, a, 15, 13);
152 R3(a, b, c, d, 0, 3);
153 R3(d, a, b, c, 8, 9);
154 R3(c, d, a, b, 4, 11);
155 R3(b, c, d, a, 12, 15);
156 R3(a, b, c, d, 2, 3);
157 R3(d, a, b, c, 10, 9);
158 R3(c, d, a, b, 6, 11);
159 R3(b, c, d, a, 14, 15);
160 R3(a, b, c, d, 1, 3);
161 R3(d, a, b, c, 9, 9);
162 R3(c, d, a, b, 5, 11);
163 R3(b, c, d, a, 13, 15);
164 R3(a, b, c, d, 3, 3);
165 R3(d, a, b, c, 11, 9);
166 R3(c, d, a, b, 7, 11);
167 R3(b, c, d, a, 15, 15);
180void md4_init(MdCtx *c)
182 c->state[0] = 0x67452301;
183 c->state[1] = 0xefcdab89;
184 c->state[2] = 0x98badcfe;
185 c->state[3] = 0x10325476;
192using md_compress_fn = void (*)(uint32_t[4],
const uint8_t[64]);
194static void md_absorb(MdCtx *c,
const uint8_t *data,
size_t len, md_compress_fn compress)
196 c->bits += (uint64_t)len * 8;
199 uint32_t take = 64 - c->buf_len;
200 if ((
size_t)take > len)
201 take = (uint32_t)len;
202 memcpy(c->buf + c->buf_len, data, take);
206 if (c->buf_len == 64)
208 compress(c->state, c->buf);
214static void md_finish(MdCtx *c, uint8_t out[16], md_compress_fn compress)
216 uint64_t bits = c->bits;
218 md_absorb(c, &pad, 1, compress);
220 while (c->buf_len != 56)
221 md_absorb(c, &zero, 1, compress);
223 for (
int i = 0; i < 8; i++)
224 lenbuf[i] = (uint8_t)(bits >> (8 * i));
225 md_absorb(c, lenbuf, 8, compress);
226 for (
int i = 0; i < 4; i++)
227 wr32le(out + i * 4, c->state[i]);
230void md5_update(MdCtx *c,
const uint8_t *data,
size_t len)
232 md_absorb(c, data, len, md5_compress);
234void md5_final(MdCtx *c, uint8_t out[16])
236 md_finish(c, out, md5_compress);
238void md4_update(MdCtx *c,
const uint8_t *data,
size_t len)
240 md_absorb(c, data, len, md4_compress);
242void md4_final(MdCtx *c, uint8_t out[16])
244 md_finish(c, out, md4_compress);
247void md5(
const uint8_t *data,
size_t len, uint8_t out[16])
251 md5_update(&c, data, len);
254void md4(
const uint8_t *data,
size_t len, uint8_t out[16])
258 md4_update(&c, data, len);
264void hmac_md5(
const uint8_t *key,
size_t key_len,
const uint8_t *msg,
size_t msg_len, uint8_t out[16])
267 memset(k, 0,
sizeof(k));
269 md5(key, key_len, k);
271 memcpy(k, key, key_len);
275 for (
int i = 0; i < 64; i++)
277 ipad[i] = (uint8_t)(k[i] ^ 0x36);
278 opad[i] = (uint8_t)(k[i] ^ 0x5c);
284 md5_update(&c, ipad, 64);
285 md5_update(&c, msg, msg_len);
286 md5_final(&c, inner);
289 md5_update(&c, opad, 64);
290 md5_update(&c, inner, 16);
void wr32le(uint8_t *p, uint32_t v)
MD4 (RFC 1320), MD5 (RFC 1321), and HMAC-MD5 (RFC 2104) - the legacy digests NTLM needs,...