xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/md5c.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: md5c.c,v 1.1 2014/03/09 00:15:45 agc Exp $	*/
2 
3 /*
4  * This file is derived from the RSA Data Security, Inc. MD5 Message-Digest
5  * Algorithm and has been modified by Jason R. Thorpe <thorpej@NetBSD.org>
6  * for portability and formatting.
7  */
8 
9 /*
10  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
11  * rights reserved.
12  *
13  * License to copy and use this software is granted provided that it
14  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15  * Algorithm" in all material mentioning or referencing this software
16  * or this function.
17  *
18  * License is also granted to make and use derivative works provided
19  * that such works are identified as "derived from the RSA Data
20  * Security, Inc. MD5 Message-Digest Algorithm" in all material
21  * mentioning or referencing the derived work.
22  *
23  * RSA Data Security, Inc. makes no representations concerning either
24  * the merchantability of this software or the suitability of this
25  * software for any particular purpose. It is provided "as is"
26  * without express or implied warranty of any kind.
27  *
28  * These notices must be retained in any copies of any part of this
29  * documentation and/or software.
30  */
31 
32 #include <sys/cdefs.h>
33 #include <sys/types.h>
34 #include <assert.h>
35 #include <string.h>
36 
37 #include "md5.h"
38 
39 #if !HAVE_MD5_H
40 
41 #define	ZEROIZE(d, l)		memset((d), 0, (l))
42 
43 typedef unsigned char *POINTER;
44 typedef uint16_t UINT2;
45 typedef uint32_t UINT4;
46 
47 /*
48  * Constants for MD5Transform routine.
49  */
50 #define S11 7
51 #define S12 12
52 #define S13 17
53 #define S14 22
54 #define S21 5
55 #define S22 9
56 #define S23 14
57 #define S24 20
58 #define S31 4
59 #define S32 11
60 #define S33 16
61 #define S34 23
62 #define S41 6
63 #define S42 10
64 #define S43 15
65 #define S44 21
66 
67 static void MD5Transform(UINT4 [4], const unsigned char [64]);
68 
69 static void Encode(unsigned char *, UINT4 *, unsigned int);
70 static void Decode(UINT4 *, const unsigned char *, unsigned int);
71 
72 /*
73  * Encodes input (UINT4) into output (unsigned char).  Assumes len is
74  * a multiple of 4.
75  */
76 static void
77 Encode (unsigned char *output,
78 	UINT4 *input,
79 	unsigned int len)
80 {
81 	unsigned int i, j;
82 
83 	for (i = 0, j = 0; j < len; i++, j += 4) {
84 		output[j] = (unsigned char)(input[i] & 0xff);
85 		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
86 		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
87 		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
88 	}
89 }
90 
91 /*
92  * Decodes input (unsigned char) into output (UINT4).  Assumes len is
93  * a multiple of 4.
94  */
95 static void
96 Decode (UINT4 *output,
97 	const unsigned char *input,
98 	unsigned int len)
99 {
100 	unsigned int i, j;
101 
102 	for (i = 0, j = 0; j < len; i++, j += 4)
103 		output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
104 		    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
105 }
106 
107 static const unsigned char PADDING[64] = {
108 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
111 };
112 
113 /*
114  * F, G, H and I are basic MD5 functions.
115  */
116 #define F(x, y, z)	(((x) & (y)) | ((~x) & (z)))
117 #define G(x, y, z)	(((x) & (z)) | ((y) & (~z)))
118 #define H(x, y, z)	((x) ^ (y) ^ (z))
119 #define I(x, y, z)	((y) ^ ((x) | (~z)))
120 
121 /*
122  * ROTATE_LEFT rotates x left n bits.
123  */
124 #define ROTATE_LEFT(x, n)	(((x) << (n)) | ((x) >> (32-(n))))
125 
126 /*
127  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
128  * Rotation is separate from addition to prevent recomputation.
129  */
130 #define FF(a, b, c, d, x, s, ac) { \
131 	(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
132 	(a) = ROTATE_LEFT ((a), (s)); \
133 	(a) += (b); \
134 }
135 
136 #define GG(a, b, c, d, x, s, ac) { \
137 	(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
138 	(a) = ROTATE_LEFT ((a), (s)); \
139 	(a) += (b); \
140 }
141 
142 #define HH(a, b, c, d, x, s, ac) { \
143 	(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
144 	(a) = ROTATE_LEFT ((a), (s)); \
145 	(a) += (b); \
146 }
147 
148 #define II(a, b, c, d, x, s, ac) { \
149 	(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
150 	(a) = ROTATE_LEFT ((a), (s)); \
151 	(a) += (b); \
152 }
153 
154 /*
155  * MD5 initialization. Begins an MD5 operation, writing a new context.
156  */
157 void
158 MD5Init(MD5_CTX *context)
159 {
160 
161 	context->count[0] = context->count[1] = 0;
162 
163 	/* Load magic initialization constants. */
164 	context->state[0] = 0x67452301;
165 	context->state[1] = 0xefcdab89;
166 	context->state[2] = 0x98badcfe;
167 	context->state[3] = 0x10325476;
168 }
169 
170 /*
171  * MD5 block update operation.  Continues an MD5 message-digest
172  * operation, processing another message block, and updating the
173  * context.
174  */
175 void
176 MD5Update(MD5_CTX *context,
177 	const unsigned char *input,	/* input block */
178 	unsigned int inputLen)		/* length of input block */
179 {
180 	unsigned int i, idx, partLen;
181 
182 	/* Compute number of bytes mod 64 */
183 	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
184 
185 	/* Update number of bits */
186 	if ((context->count[0] += ((UINT4)inputLen << 3))
187 	    < ((UINT4)inputLen << 3))
188 		context->count[1]++;
189 	context->count[1] += ((UINT4)inputLen >> 29);
190 
191 	partLen = 64 - idx;
192 
193 	/* Transform as many times as possible. */
194 	if (inputLen >= partLen) {
195 		memcpy((POINTER)&context->buffer[idx], input, partLen);
196 		MD5Transform(context->state, context->buffer);
197 
198 		for (i = partLen; i + 63 < inputLen; i += 64)
199 			MD5Transform(context->state, &input[i]);
200 
201 		idx = 0;
202 	} else
203 		i = 0;
204 
205 	/* Buffer remaining input */
206 	memcpy(&context->buffer[idx], &input[i], inputLen - i);
207 }
208 
209 /*
210  * MD5 finalization.  Ends an MD5 message-digest operation, writing the
211  * message digest and zeroing the context.
212  */
213 void
214 MD5Final(unsigned char digest[16],	/* message digest */
215 	MD5_CTX *context)		/* context */
216 {
217 	unsigned char bits[8];
218 	unsigned int idx, padLen;
219 
220 	/* Save number of bits */
221 	Encode(bits, context->count, 8);
222 
223 	/* Pad out to 56 mod 64. */
224 	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
225 	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
226 	MD5Update (context, PADDING, padLen);
227 
228 	/* Append length (before padding) */
229 	MD5Update(context, bits, 8);
230 
231 	/* Store state in digest */
232 	Encode(digest, context->state, 16);
233 
234 	/* Zeroize sensitive information. */
235 	ZEROIZE((POINTER)(void *)context, sizeof(*context));
236 }
237 
238 /*
239  * MD5 basic transformation. Transforms state based on block.
240  */
241 static void
242 MD5Transform(UINT4 state[4], const unsigned char block[64])
243 {
244 	UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
245 
246 	Decode(x, block, 64);
247 
248 	/* Round 1 */
249 	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
250 	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
251 	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
252 	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
253 	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
254 	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
255 	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
256 	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
257 	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
258 	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
259 	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
260 	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
261 	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
262 	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
263 	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
264 	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
265 
266 	/* Round 2 */
267 	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
268 	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
269 	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
270 	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
271 	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
272 	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
273 	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
274 	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
275 	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
276 	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
277 	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
278 	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
279 	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
280 	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
281 	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
282 	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
283 
284 	/* Round 3 */
285 	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
286 	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
287 	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
288 	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
289 	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
290 	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
291 	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
292 	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
293 	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
294 	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
295 	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
296 	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
297 	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
298 	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
299 	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
300 	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
301 
302 	/* Round 4 */
303 	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
304 	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
305 	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
306 	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
307 	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
308 	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
309 	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
310 	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
311 	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
312 	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
313 	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
314 	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
315 	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
316 	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
317 	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
318 	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
319 
320 	state[0] += a;
321 	state[1] += b;
322 	state[2] += c;
323 	state[3] += d;
324 
325 	/* Zeroize sensitive information. */
326 	ZEROIZE((POINTER)(void *)x, sizeof (x));
327 }
328 
329 #endif /* HAVE_MD5_H */
330