xref: /minix3/external/bsd/dhcp/dist/dst/md5_dgst.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1 /*	$NetBSD: md5_dgst.c,v 1.1.1.3 2014/07/12 11:57:51 spz Exp $	*/
2 /* crypto/md/md5_dgst.c */
3 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
4  * All rights reserved.
5  *
6  * This package is an SSL implementation written
7  * by Eric Young (eay@cryptsoft.com).
8  * The implementation was written so as to conform with Netscapes SSL.
9  *
10  * This library is free for commercial and non-commercial use as long as
11  * the following conditions are aheared to.  The following conditions
12  * apply to all code found in this distribution, be it the RC4, RSA,
13  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
14  * included with this distribution is covered by the same copyright terms
15  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16  *
17  * Copyright remains Eric Young's, and as such any Copyright notices in
18  * the code are not to be removed.
19  * If this package is used in a product, Eric Young should be given attribution
20  * as the author of the parts of the library used.
21  * This can be in the form of a textual message at program startup or
22  * in documentation (online or textual) provided with the package.
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  * 1. Redistributions of source code must retain the copyright
28  *    notice, this list of conditions and the following disclaimer.
29  * 2. Redistributions in binary form must reproduce the above copyright
30  *    notice, this list of conditions and the following disclaimer in the
31  *    documentation and/or other materials provided with the distribution.
32  * 3. All advertising materials mentioning features or use of this software
33  *    must display the following acknowledgement:
34  *    "This product includes cryptographic software written by
35  *     Eric Young (eay@cryptsoft.com)"
36  *    The word 'cryptographic' can be left out if the rouines from the library
37  *    being used are not cryptographic related :-).
38  * 4. If you include any Windows specific code (or a derivative thereof) from
39  *    the apps directory (application code) you must include an acknowledgement:
40  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41  *
42  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  *
54  * The licence and distribution terms for any publically available version or
55  * derivative of this code cannot be changed.  i.e. this code cannot simply be
56  * copied and put under another distribution licence
57  * [including the GNU Public Licence.]
58  */
59 
60 /*
61  * Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC")
62  *
63  * Permission to use, copy, modify, and distribute this software for any
64  * purpose with or without fee is hereby granted, provided that the above
65  * copyright notice and this permission notice appear in all copies.
66  *
67  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
68  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
69  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
70  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
71  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
72  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
73  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
74  *
75  *   Internet Systems Consortium, Inc.
76  *   950 Charter Street
77  *   Redwood City, CA 94063
78  *   <info@isc.org>
79  *   https://www.isc.org/
80  */
81 
82 #include <sys/cdefs.h>
83 __RCSID("$NetBSD: md5_dgst.c,v 1.1.1.3 2014/07/12 11:57:51 spz Exp $");
84 
85 #include <stdio.h>
86 #include <sys/types.h>
87 #include <sys/socket.h>
88 #include <netinet/in.h>
89 #include "md5_locl.h"
90 #include "cdefs.h"
91 #include "osdep.h"
92 
93 #ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */
94 
95 const char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997";
96 
97 /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
98  */
99 
100 #define INIT_DATA_A (unsigned long)0x67452301L
101 #define INIT_DATA_B (unsigned long)0xefcdab89L
102 #define INIT_DATA_C (unsigned long)0x98badcfeL
103 #define INIT_DATA_D (unsigned long)0x10325476L
104 
105 #ifndef NOPROTO
106 static void md5_block(MD5_CTX *c, unsigned long *p);
107 #else
108 static void md5_block();
109 #endif
110 
MD5_Init(c)111 void MD5_Init(c)
112 MD5_CTX *c;
113 	{
114 	c->A=INIT_DATA_A;
115 	c->B=INIT_DATA_B;
116 	c->C=INIT_DATA_C;
117 	c->D=INIT_DATA_D;
118 	c->Nl=0;
119 	c->Nh=0;
120 	c->num=0;
121 	}
122 
MD5_Update(c,data,len)123 void MD5_Update(c, data, len)
124 MD5_CTX *c;
125 const register unsigned char *data;
126 unsigned long len;
127 	{
128 	register ULONG *p;
129 	int sw,sc;
130 	ULONG l;
131 
132 	if (len == 0) return;
133 
134 	l=(c->Nl+(len<<3))&0xffffffffL;
135 	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
136 	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
137 	if (l < c->Nl) /* overflow */
138 		c->Nh++;
139 	c->Nh+=(len>>29);
140 	c->Nl=l;
141 
142 	if (c->num != 0)
143 		{
144 		p=c->data;
145 		sw=c->num>>2;
146 		sc=c->num&0x03;
147 
148 		if ((c->num+len) >= MD5_CBLOCK)
149 			{
150 			l= p[sw];
151 			p_c2l(data,l,sc);
152 			p[sw++]=l;
153 			for (; sw<MD5_LBLOCK; sw++)
154 				{
155 				c2l(data,l);
156 				p[sw]=l;
157 				}
158 			len-=(MD5_CBLOCK-c->num);
159 
160 			md5_block(c,p);
161 			c->num=0;
162 			/* drop through and do the rest */
163 			}
164 		else
165 			{
166 			int ew,ec;
167 
168 			c->num+=(int)len;
169 			if ((sc+len) < 4) /* ugly, add char's to a word */
170 				{
171 				l= p[sw];
172 				p_c2l_p(data,l,sc,len);
173 				p[sw]=l;
174 				}
175 			else
176 				{
177 				ew=(c->num>>2);
178 				ec=(c->num&0x03);
179 				l= p[sw];
180 				p_c2l(data,l,sc);
181 				p[sw++]=l;
182 				for (; sw < ew; sw++)
183 					{ c2l(data,l); p[sw]=l; }
184 				if (ec)
185 					{
186 					c2l_p(data,l,ec);
187 					p[sw]=l;
188 					}
189 				}
190 			return;
191 			}
192 		}
193 	/* we now can process the input data in blocks of MD5_CBLOCK
194 	 * chars and save the leftovers to c->data. */
195 	p=c->data;
196 	while (len >= MD5_CBLOCK)
197 		{
198 #if defined(L_ENDIAN) || defined(B_ENDIAN)
199 		memcpy(p,data,MD5_CBLOCK);
200 		data+=MD5_CBLOCK;
201 #ifdef B_ENDIAN
202 		for (sw=(MD5_LBLOCK/4); sw; sw--)
203 			{
204 			Endian_Reverse32(p[0]);
205 			Endian_Reverse32(p[1]);
206 			Endian_Reverse32(p[2]);
207 			Endian_Reverse32(p[3]);
208 			p+=4;
209 			}
210 #endif
211 #else
212 		for (sw=(MD5_LBLOCK/4); sw; sw--)
213 			{
214 			c2l(data,l); *(p++)=l;
215 			c2l(data,l); *(p++)=l;
216 			c2l(data,l); *(p++)=l;
217 			c2l(data,l); *(p++)=l;
218 			}
219 #endif
220 		p=c->data;
221 		md5_block(c,p);
222 		len-=MD5_CBLOCK;
223 		}
224 	sc=(int)len;
225 	c->num=sc;
226 	if (sc)
227 		{
228 		sw=sc>>2;	/* words to copy */
229 #ifdef L_ENDIAN
230 		p[sw]=0;
231 		memcpy(p,data,sc);
232 #else
233 		sc&=0x03;
234 		for ( ; sw; sw--)
235 			{ c2l(data,l); *(p++)=l; }
236 		c2l_p(data,l,sc);
237 		*p=l;
238 #endif
239 		}
240 	}
241 
md5_block(c,X)242 static void md5_block(c, X)
243 MD5_CTX *c;
244 register ULONG *X;
245 	{
246 	register ULONG A,B,C,D;
247 
248 	A=c->A;
249 	B=c->B;
250 	C=c->C;
251 	D=c->D;
252 
253 	/* Round 0 */
254 	LOCL_R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
255 	LOCL_R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
256 	LOCL_R0(C,D,A,B,X[ 2],17,0x242070dbL);
257 	LOCL_R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
258 	LOCL_R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
259 	LOCL_R0(D,A,B,C,X[ 5],12,0x4787c62aL);
260 	LOCL_R0(C,D,A,B,X[ 6],17,0xa8304613L);
261 	LOCL_R0(B,C,D,A,X[ 7],22,0xfd469501L);
262 	LOCL_R0(A,B,C,D,X[ 8], 7,0x698098d8L);
263 	LOCL_R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
264 	LOCL_R0(C,D,A,B,X[10],17,0xffff5bb1L);
265 	LOCL_R0(B,C,D,A,X[11],22,0x895cd7beL);
266 	LOCL_R0(A,B,C,D,X[12], 7,0x6b901122L);
267 	LOCL_R0(D,A,B,C,X[13],12,0xfd987193L);
268 	LOCL_R0(C,D,A,B,X[14],17,0xa679438eL);
269 	LOCL_R0(B,C,D,A,X[15],22,0x49b40821L);
270 	/* Round 1 */
271 	LOCL_R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
272 	LOCL_R1(D,A,B,C,X[ 6], 9,0xc040b340L);
273 	LOCL_R1(C,D,A,B,X[11],14,0x265e5a51L);
274 	LOCL_R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
275 	LOCL_R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
276 	LOCL_R1(D,A,B,C,X[10], 9,0x02441453L);
277 	LOCL_R1(C,D,A,B,X[15],14,0xd8a1e681L);
278 	LOCL_R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
279 	LOCL_R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
280 	LOCL_R1(D,A,B,C,X[14], 9,0xc33707d6L);
281 	LOCL_R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
282 	LOCL_R1(B,C,D,A,X[ 8],20,0x455a14edL);
283 	LOCL_R1(A,B,C,D,X[13], 5,0xa9e3e905L);
284 	LOCL_R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
285 	LOCL_R1(C,D,A,B,X[ 7],14,0x676f02d9L);
286 	LOCL_R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
287 	/* Round 2 */
288 	LOCL_R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
289 	LOCL_R2(D,A,B,C,X[ 8],11,0x8771f681L);
290 	LOCL_R2(C,D,A,B,X[11],16,0x6d9d6122L);
291 	LOCL_R2(B,C,D,A,X[14],23,0xfde5380cL);
292 	LOCL_R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
293 	LOCL_R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
294 	LOCL_R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
295 	LOCL_R2(B,C,D,A,X[10],23,0xbebfbc70L);
296 	LOCL_R2(A,B,C,D,X[13], 4,0x289b7ec6L);
297 	LOCL_R2(D,A,B,C,X[ 0],11,0xeaa127faL);
298 	LOCL_R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
299 	LOCL_R2(B,C,D,A,X[ 6],23,0x04881d05L);
300 	LOCL_R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
301 	LOCL_R2(D,A,B,C,X[12],11,0xe6db99e5L);
302 	LOCL_R2(C,D,A,B,X[15],16,0x1fa27cf8L);
303 	LOCL_R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
304 	/* Round 3 */
305 	LOCL_R3(A,B,C,D,X[ 0], 6,0xf4292244L);
306 	LOCL_R3(D,A,B,C,X[ 7],10,0x432aff97L);
307 	LOCL_R3(C,D,A,B,X[14],15,0xab9423a7L);
308 	LOCL_R3(B,C,D,A,X[ 5],21,0xfc93a039L);
309 	LOCL_R3(A,B,C,D,X[12], 6,0x655b59c3L);
310 	LOCL_R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
311 	LOCL_R3(C,D,A,B,X[10],15,0xffeff47dL);
312 	LOCL_R3(B,C,D,A,X[ 1],21,0x85845dd1L);
313 	LOCL_R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
314 	LOCL_R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
315 	LOCL_R3(C,D,A,B,X[ 6],15,0xa3014314L);
316 	LOCL_R3(B,C,D,A,X[13],21,0x4e0811a1L);
317 	LOCL_R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
318 	LOCL_R3(D,A,B,C,X[11],10,0xbd3af235L);
319 	LOCL_R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
320 	LOCL_R3(B,C,D,A,X[ 9],21,0xeb86d391L);
321 
322 	c->A+=A&0xffffffffL;
323 	c->B+=B&0xffffffffL;
324 	c->C+=C&0xffffffffL;
325 	c->D+=D&0xffffffffL;
326 	}
327 
MD5_Final(md,c)328 void MD5_Final(md, c)
329 unsigned char *md;
330 MD5_CTX *c;
331 	{
332 	register int i,j;
333 	register ULONG l;
334 	register ULONG *p;
335 	static unsigned char end[4]={0x80,0x00,0x00,0x00};
336 	unsigned char *cp=end;
337 
338 	/* c->num should definitely have room for at least one more byte. */
339 	p=c->data;
340 	j=c->num;
341 	i=j>>2;
342 
343 	/* purify often complains about the following line as an
344 	 * Uninitialized Memory Read.  While this can be true, the
345 	 * following p_c2l macro will reset l when that case is true.
346 	 * This is because j&0x03 contains the number of 'valid' bytes
347 	 * already in p[i].  If and only if j&0x03 == 0, the UMR will
348 	 * occur but this is also the only time p_c2l will do
349 	 * l= *(cp++) instead of l|= *(cp++)
350 	 * Many thanks to Alex Tang <altitude@cic.net> for pickup this
351 	 * 'potential bug' */
352 #ifdef PURIFY
353 	if ((j&0x03) == 0) p[i]=0;
354 #endif
355 	l=p[i];
356 	p_c2l(cp,l,j&0x03);
357 	p[i]=l;
358 	i++;
359 	/* i is the next 'undefined word' */
360 	if (c->num >= MD5_LAST_BLOCK)
361 		{
362 		for (; i<MD5_LBLOCK; i++)
363 			p[i]=0;
364 		md5_block(c,p);
365 		i=0;
366 		}
367 	for (; i<(MD5_LBLOCK-2); i++)
368 		p[i]=0;
369 	p[MD5_LBLOCK-2]=c->Nl;
370 	p[MD5_LBLOCK-1]=c->Nh;
371 	md5_block(c,p);
372 	cp=md;
373 	l=c->A; l2c(l,cp);
374 	l=c->B; l2c(l,cp);
375 	l=c->C; l2c(l,cp);
376 	l=c->D; l2c(l,cp);
377 
378 	/* clear stuff, md5_block may be leaving some stuff on the stack
379 	 * but I'm not worried :-) */
380 	c->num=0;
381 /*	memset((char *)&c,0,sizeof(c));*/
382 	}
383 
384 #ifdef undef
printit(l)385 int printit(l)
386 unsigned long *l;
387 	{
388 	int i,ii;
389 
390 	for (i=0; i<2; i++)
391 		{
392 		for (ii=0; ii<8; ii++)
393 			{
394 			fprintf(stderr,"%08lx ",l[i*8+ii]);
395 			}
396 		fprintf(stderr,"\n");
397 		}
398 	}
399 #endif
400 #endif /* USE_MD5 */
401