1*036a3c97Sguenther /* $OpenBSD: md5.c,v 1.12 2020/10/13 04:42:28 guenther Exp $ */
233693a73Smillert
333693a73Smillert /*
433693a73Smillert * This code implements the MD5 message-digest algorithm.
533693a73Smillert * The algorithm is due to Ron Rivest. This code was
633693a73Smillert * written by Colin Plumb in 1993, no copyright is claimed.
733693a73Smillert * This code is in the public domain; do with it what you wish.
833693a73Smillert *
933693a73Smillert * Equivalent code is available from RSA Data Security, Inc.
1033693a73Smillert * This code has been tested against that, and is equivalent,
1133693a73Smillert * except that you don't need to include two pages of legalese
1233693a73Smillert * with every copy.
1333693a73Smillert *
1433693a73Smillert * To compute the message digest of a chunk of bytes, declare an
1533693a73Smillert * MD5Context structure, pass it to MD5Init, call MD5Update as
1633693a73Smillert * needed on buffers full of bytes, and then call MD5Final, which
1733693a73Smillert * will fill a supplied 16-byte array with the digest.
1833693a73Smillert */
1933693a73Smillert
2033693a73Smillert #include <sys/types.h>
2133693a73Smillert #include <string.h>
2233693a73Smillert #include <md5.h>
2333693a73Smillert
24fb8f49c6Smillert #define PUT_64BIT_LE(cp, value) do { \
25fb8f49c6Smillert (cp)[7] = (value) >> 56; \
26fb8f49c6Smillert (cp)[6] = (value) >> 48; \
27fb8f49c6Smillert (cp)[5] = (value) >> 40; \
28fb8f49c6Smillert (cp)[4] = (value) >> 32; \
29fb8f49c6Smillert (cp)[3] = (value) >> 24; \
30fb8f49c6Smillert (cp)[2] = (value) >> 16; \
31fb8f49c6Smillert (cp)[1] = (value) >> 8; \
32fb8f49c6Smillert (cp)[0] = (value); } while (0)
33c0be0e2fSmillert
34fb8f49c6Smillert #define PUT_32BIT_LE(cp, value) do { \
35fb8f49c6Smillert (cp)[3] = (value) >> 24; \
36fb8f49c6Smillert (cp)[2] = (value) >> 16; \
37fb8f49c6Smillert (cp)[1] = (value) >> 8; \
38fb8f49c6Smillert (cp)[0] = (value); } while (0)
39c0be0e2fSmillert
40*036a3c97Sguenther static const u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
41fb8f49c6Smillert 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42fb8f49c6Smillert 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43fb8f49c6Smillert 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
44fb8f49c6Smillert };
4533693a73Smillert
4633693a73Smillert /*
4733693a73Smillert * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
4833693a73Smillert * initialization constants.
4933693a73Smillert */
5033693a73Smillert void
MD5Init(MD5_CTX * ctx)5133693a73Smillert MD5Init(MD5_CTX *ctx)
5233693a73Smillert {
53c0be0e2fSmillert ctx->count = 0;
54c0be0e2fSmillert ctx->state[0] = 0x67452301;
55c0be0e2fSmillert ctx->state[1] = 0xefcdab89;
56c0be0e2fSmillert ctx->state[2] = 0x98badcfe;
57c0be0e2fSmillert ctx->state[3] = 0x10325476;
5833693a73Smillert }
5989db3a20Sguenther DEF_WEAK(MD5Init);
6033693a73Smillert
6133693a73Smillert /*
6233693a73Smillert * Update context to reflect the concatenation of another buffer full
6333693a73Smillert * of bytes.
6433693a73Smillert */
6533693a73Smillert void
MD5Update(MD5_CTX * ctx,const unsigned char * input,size_t len)66fb8f49c6Smillert MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
6733693a73Smillert {
689dfc8d30Smillert size_t have, need;
69c0be0e2fSmillert
70fb8f49c6Smillert /* Check how many bytes we already have and how many more we need. */
719dfc8d30Smillert have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
72fb8f49c6Smillert need = MD5_BLOCK_LENGTH - have;
7333693a73Smillert
7433693a73Smillert /* Update bitcount */
75c0be0e2fSmillert ctx->count += (u_int64_t)len << 3;
7633693a73Smillert
77fb8f49c6Smillert if (len >= need) {
78fb8f49c6Smillert if (have != 0) {
79fb8f49c6Smillert memcpy(ctx->buffer + have, input, need);
80c0be0e2fSmillert MD5Transform(ctx->state, ctx->buffer);
81fb8f49c6Smillert input += need;
82fb8f49c6Smillert len -= need;
83fb8f49c6Smillert have = 0;
8433693a73Smillert }
8533693a73Smillert
86fb8f49c6Smillert /* Process data in MD5_BLOCK_LENGTH-byte chunks. */
87c0be0e2fSmillert while (len >= MD5_BLOCK_LENGTH) {
88fb8f49c6Smillert MD5Transform(ctx->state, input);
89fb8f49c6Smillert input += MD5_BLOCK_LENGTH;
90c0be0e2fSmillert len -= MD5_BLOCK_LENGTH;
9133693a73Smillert }
92fb8f49c6Smillert }
9333693a73Smillert
9433693a73Smillert /* Handle any remaining bytes of data. */
95fb8f49c6Smillert if (len != 0)
96fb8f49c6Smillert memcpy(ctx->buffer + have, input, len);
9733693a73Smillert }
9889db3a20Sguenther DEF_WEAK(MD5Update);
9933693a73Smillert
10033693a73Smillert /*
1019dfc8d30Smillert * Pad pad to 64-byte boundary with the bit pattern
10233693a73Smillert * 1 0* (64-bit count of bits processed, MSB-first)
10333693a73Smillert */
10433693a73Smillert void
MD5Pad(MD5_CTX * ctx)1059dfc8d30Smillert MD5Pad(MD5_CTX *ctx)
10633693a73Smillert {
107fb8f49c6Smillert u_int8_t count[8];
1089dfc8d30Smillert size_t padlen;
10933693a73Smillert
110fb8f49c6Smillert /* Convert count to 8 bytes in little endian order. */
111fb8f49c6Smillert PUT_64BIT_LE(count, ctx->count);
11233693a73Smillert
113fb8f49c6Smillert /* Pad out to 56 mod 64. */
114fb8f49c6Smillert padlen = MD5_BLOCK_LENGTH -
115fb8f49c6Smillert ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
116fb8f49c6Smillert if (padlen < 1 + 8)
117fb8f49c6Smillert padlen += MD5_BLOCK_LENGTH;
118fb8f49c6Smillert MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
119fb8f49c6Smillert MD5Update(ctx, count, 8);
1209dfc8d30Smillert }
12189db3a20Sguenther DEF_WEAK(MD5Pad);
12233693a73Smillert
1239dfc8d30Smillert /*
1249dfc8d30Smillert * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
1259dfc8d30Smillert */
1269dfc8d30Smillert void
MD5Final(unsigned char digest[MD5_DIGEST_LENGTH],MD5_CTX * ctx)1279dfc8d30Smillert MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
1289dfc8d30Smillert {
1299dfc8d30Smillert int i;
1309dfc8d30Smillert
1319dfc8d30Smillert MD5Pad(ctx);
132fb8f49c6Smillert for (i = 0; i < 4; i++)
133fb8f49c6Smillert PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
134b4c10efeSmillert explicit_bzero(ctx, sizeof(*ctx));
13533693a73Smillert }
13689db3a20Sguenther DEF_WEAK(MD5Final);
13733693a73Smillert
13833693a73Smillert
13933693a73Smillert /* The four core functions - F1 is optimized somewhat */
14033693a73Smillert
14133693a73Smillert /* #define F1(x, y, z) (x & y | ~x & z) */
14233693a73Smillert #define F1(x, y, z) (z ^ (x & (y ^ z)))
14333693a73Smillert #define F2(x, y, z) F1(z, x, y)
14433693a73Smillert #define F3(x, y, z) (x ^ y ^ z)
14533693a73Smillert #define F4(x, y, z) (y ^ (x | ~z))
14633693a73Smillert
14733693a73Smillert /* This is the central step in the MD5 algorithm. */
14833693a73Smillert #define MD5STEP(f, w, x, y, z, data, s) \
14933693a73Smillert ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
15033693a73Smillert
15133693a73Smillert /*
15233693a73Smillert * The core of the MD5 algorithm, this alters an existing MD5 hash to
15333693a73Smillert * reflect the addition of 16 longwords of new data. MD5Update blocks
15433693a73Smillert * the data and converts bytes into longwords for this routine.
15533693a73Smillert */
15633693a73Smillert void
MD5Transform(u_int32_t state[4],const u_int8_t block[MD5_BLOCK_LENGTH])157fb8f49c6Smillert MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
15833693a73Smillert {
159fb8f49c6Smillert u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
16033693a73Smillert
161fb8f49c6Smillert #if BYTE_ORDER == LITTLE_ENDIAN
162fb8f49c6Smillert memcpy(in, block, sizeof(in));
163fb8f49c6Smillert #else
164fb8f49c6Smillert for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
165fb8f49c6Smillert in[a] = (u_int32_t)(
166fb8f49c6Smillert (u_int32_t)(block[a * 4 + 0]) |
167fb8f49c6Smillert (u_int32_t)(block[a * 4 + 1]) << 8 |
168fb8f49c6Smillert (u_int32_t)(block[a * 4 + 2]) << 16 |
169fb8f49c6Smillert (u_int32_t)(block[a * 4 + 3]) << 24);
170fb8f49c6Smillert }
171fb8f49c6Smillert #endif
172fb8f49c6Smillert
173fb8f49c6Smillert a = state[0];
174fb8f49c6Smillert b = state[1];
175fb8f49c6Smillert c = state[2];
176fb8f49c6Smillert d = state[3];
17733693a73Smillert
17833693a73Smillert MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
17933693a73Smillert MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
18033693a73Smillert MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
18133693a73Smillert MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
18233693a73Smillert MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
18333693a73Smillert MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
18433693a73Smillert MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
18533693a73Smillert MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
18633693a73Smillert MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
18733693a73Smillert MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
18833693a73Smillert MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
18933693a73Smillert MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
19033693a73Smillert MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
19133693a73Smillert MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
19233693a73Smillert MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
19333693a73Smillert MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
19433693a73Smillert
19533693a73Smillert MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
19633693a73Smillert MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
19733693a73Smillert MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
19833693a73Smillert MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
19933693a73Smillert MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
20033693a73Smillert MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
20133693a73Smillert MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
20233693a73Smillert MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
20333693a73Smillert MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
20433693a73Smillert MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
20533693a73Smillert MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
20633693a73Smillert MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
20733693a73Smillert MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
20833693a73Smillert MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
20933693a73Smillert MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
21033693a73Smillert MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
21133693a73Smillert
21233693a73Smillert MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
21333693a73Smillert MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
21433693a73Smillert MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
21533693a73Smillert MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
21633693a73Smillert MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
21733693a73Smillert MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
21833693a73Smillert MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
21933693a73Smillert MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
22033693a73Smillert MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
22133693a73Smillert MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
22233693a73Smillert MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
22333693a73Smillert MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
22433693a73Smillert MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
22533693a73Smillert MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
22633693a73Smillert MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
22733693a73Smillert MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
22833693a73Smillert
22933693a73Smillert MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
23033693a73Smillert MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
23133693a73Smillert MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
23233693a73Smillert MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
23333693a73Smillert MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
23433693a73Smillert MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
23533693a73Smillert MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
23633693a73Smillert MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
23733693a73Smillert MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6);
23833693a73Smillert MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
23933693a73Smillert MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
24033693a73Smillert MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
24133693a73Smillert MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6);
24233693a73Smillert MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
24333693a73Smillert MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
24433693a73Smillert MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
24533693a73Smillert
246fb8f49c6Smillert state[0] += a;
247fb8f49c6Smillert state[1] += b;
248fb8f49c6Smillert state[2] += c;
249fb8f49c6Smillert state[3] += d;
25033693a73Smillert }
25189db3a20Sguenther DEF_WEAK(MD5Transform);
252