GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/hash/md5.c Lines: 0 105 0.0 %
Date: 2017-11-13 Branches: 0 12 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: md5.c,v 1.11 2015/09/11 09:18:27 guenther Exp $	*/
2
3
/*
4
 * This code implements the MD5 message-digest algorithm.
5
 * The algorithm is due to Ron Rivest.	This code was
6
 * written by Colin Plumb in 1993, no copyright is claimed.
7
 * This code is in the public domain; do with it what you wish.
8
 *
9
 * Equivalent code is available from RSA Data Security, Inc.
10
 * This code has been tested against that, and is equivalent,
11
 * except that you don't need to include two pages of legalese
12
 * with every copy.
13
 *
14
 * To compute the message digest of a chunk of bytes, declare an
15
 * MD5Context structure, pass it to MD5Init, call MD5Update as
16
 * needed on buffers full of bytes, and then call MD5Final, which
17
 * will fill a supplied 16-byte array with the digest.
18
 */
19
20
#include <sys/types.h>
21
#include <string.h>
22
#include <md5.h>
23
24
#define PUT_64BIT_LE(cp, value) do {					\
25
	(cp)[7] = (value) >> 56;					\
26
	(cp)[6] = (value) >> 48;					\
27
	(cp)[5] = (value) >> 40;					\
28
	(cp)[4] = (value) >> 32;					\
29
	(cp)[3] = (value) >> 24;					\
30
	(cp)[2] = (value) >> 16;					\
31
	(cp)[1] = (value) >> 8;						\
32
	(cp)[0] = (value); } while (0)
33
34
#define PUT_32BIT_LE(cp, value) do {					\
35
	(cp)[3] = (value) >> 24;					\
36
	(cp)[2] = (value) >> 16;					\
37
	(cp)[1] = (value) >> 8;						\
38
	(cp)[0] = (value); } while (0)
39
40
static u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
41
	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
44
};
45
46
/*
47
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
48
 * initialization constants.
49
 */
50
void
51
MD5Init(MD5_CTX *ctx)
52
{
53
	ctx->count = 0;
54
	ctx->state[0] = 0x67452301;
55
	ctx->state[1] = 0xefcdab89;
56
	ctx->state[2] = 0x98badcfe;
57
	ctx->state[3] = 0x10325476;
58
}
59
DEF_WEAK(MD5Init);
60
61
/*
62
 * Update context to reflect the concatenation of another buffer full
63
 * of bytes.
64
 */
65
void
66
MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
67
{
68
	size_t have, need;
69
70
	/* Check how many bytes we already have and how many more we need. */
71
	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
72
	need = MD5_BLOCK_LENGTH - have;
73
74
	/* Update bitcount */
75
	ctx->count += (u_int64_t)len << 3;
76
77
	if (len >= need) {
78
		if (have != 0) {
79
			memcpy(ctx->buffer + have, input, need);
80
			MD5Transform(ctx->state, ctx->buffer);
81
			input += need;
82
			len -= need;
83
			have = 0;
84
		}
85
86
		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
87
		while (len >= MD5_BLOCK_LENGTH) {
88
			MD5Transform(ctx->state, input);
89
			input += MD5_BLOCK_LENGTH;
90
			len -= MD5_BLOCK_LENGTH;
91
		}
92
	}
93
94
	/* Handle any remaining bytes of data. */
95
	if (len != 0)
96
		memcpy(ctx->buffer + have, input, len);
97
}
98
DEF_WEAK(MD5Update);
99
100
/*
101
 * Pad pad to 64-byte boundary with the bit pattern
102
 * 1 0* (64-bit count of bits processed, MSB-first)
103
 */
104
void
105
MD5Pad(MD5_CTX *ctx)
106
{
107
	u_int8_t count[8];
108
	size_t padlen;
109
110
	/* Convert count to 8 bytes in little endian order. */
111
	PUT_64BIT_LE(count, ctx->count);
112
113
	/* Pad out to 56 mod 64. */
114
	padlen = MD5_BLOCK_LENGTH -
115
	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
116
	if (padlen < 1 + 8)
117
		padlen += MD5_BLOCK_LENGTH;
118
	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
119
	MD5Update(ctx, count, 8);
120
}
121
DEF_WEAK(MD5Pad);
122
123
/*
124
 * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
125
 */
126
void
127
MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
128
{
129
	int i;
130
131
	MD5Pad(ctx);
132
	for (i = 0; i < 4; i++)
133
		PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
134
	explicit_bzero(ctx, sizeof(*ctx));
135
}
136
DEF_WEAK(MD5Final);
137
138
139
/* The four core functions - F1 is optimized somewhat */
140
141
/* #define F1(x, y, z) (x & y | ~x & z) */
142
#define F1(x, y, z) (z ^ (x & (y ^ z)))
143
#define F2(x, y, z) F1(z, x, y)
144
#define F3(x, y, z) (x ^ y ^ z)
145
#define F4(x, y, z) (y ^ (x | ~z))
146
147
/* This is the central step in the MD5 algorithm. */
148
#define MD5STEP(f, w, x, y, z, data, s) \
149
	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
150
151
/*
152
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
153
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
154
 * the data and converts bytes into longwords for this routine.
155
 */
156
void
157
MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
158
{
159
	u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
160
161
#if BYTE_ORDER == LITTLE_ENDIAN
162
	memcpy(in, block, sizeof(in));
163
#else
164
	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
165
		in[a] = (u_int32_t)(
166
		    (u_int32_t)(block[a * 4 + 0]) |
167
		    (u_int32_t)(block[a * 4 + 1]) <<  8 |
168
		    (u_int32_t)(block[a * 4 + 2]) << 16 |
169
		    (u_int32_t)(block[a * 4 + 3]) << 24);
170
	}
171
#endif
172
173
	a = state[0];
174
	b = state[1];
175
	c = state[2];
176
	d = state[3];
177
178
	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
179
	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
180
	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
181
	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
182
	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
183
	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
184
	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
185
	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
186
	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
187
	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
188
	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
189
	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
190
	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
191
	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
192
	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
193
	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
194
195
	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
196
	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
197
	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
198
	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
199
	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
200
	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
201
	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
202
	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
203
	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
204
	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
205
	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
206
	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
207
	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
208
	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
209
	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
210
	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
211
212
	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
213
	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
214
	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
215
	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
216
	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
217
	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
218
	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
219
	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
220
	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
221
	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
222
	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
223
	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
224
	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
225
	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
226
	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
227
	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
228
229
	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
230
	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
231
	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
232
	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
233
	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
234
	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
235
	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
236
	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
237
	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
238
	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
239
	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
240
	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
241
	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
242
	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
243
	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
244
	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
245
246
	state[0] += a;
247
	state[1] += b;
248
	state[2] += c;
249
	state[3] += d;
250
}
251
DEF_WEAK(MD5Transform);