xref: /plan9/sys/src/cmd/unix/drawterm/libsec/md5block.c (revision 9b943567965ba040fd275927fbe088656eb8ce4f)
1*9b943567SDavid du Colombier #include "../lib9.h"
2*9b943567SDavid du Colombier #include "../libsec/libsec.h"
3*9b943567SDavid du Colombier 
4*9b943567SDavid du Colombier /*
5*9b943567SDavid du Colombier  *  rfc1321 requires that I include this.  The code is new.  The constants
6*9b943567SDavid du Colombier  *  all come from the rfc (hence the copyright).  We trade a table for the
7*9b943567SDavid du Colombier  *  macros in rfc.  The total size is a lot less. -- presotto
8*9b943567SDavid du Colombier  *
9*9b943567SDavid du Colombier  *	Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
10*9b943567SDavid du Colombier  *	rights reserved.
11*9b943567SDavid du Colombier  *
12*9b943567SDavid du Colombier  *	License to copy and use this software is granted provided that it
13*9b943567SDavid du Colombier  *	is identified as the "RSA Data Security, Inc. MD5 Message-Digest
14*9b943567SDavid du Colombier  *	Algorithm" in all material mentioning or referencing this software
15*9b943567SDavid du Colombier  *	or this function.
16*9b943567SDavid du Colombier  *
17*9b943567SDavid du Colombier  *	License is also granted to make and use derivative works provided
18*9b943567SDavid du Colombier  *	that such works are identified as "derived from the RSA Data
19*9b943567SDavid du Colombier  *	Security, Inc. MD5 Message-Digest Algorithm" in all material
20*9b943567SDavid du Colombier  *	mentioning or referencing the derived work.
21*9b943567SDavid du Colombier  *
22*9b943567SDavid du Colombier  *	RSA Data Security, Inc. makes no representations concerning either
23*9b943567SDavid du Colombier  *	the merchantability of this software or the suitability of this
24*9b943567SDavid du Colombier  *	software forany particular purpose. It is provided "as is"
25*9b943567SDavid du Colombier  *	without express or implied warranty of any kind.
26*9b943567SDavid du Colombier  *	These notices must be retained in any copies of any part of this
27*9b943567SDavid du Colombier  *	documentation and/or software.
28*9b943567SDavid du Colombier  */
29*9b943567SDavid du Colombier 
30*9b943567SDavid du Colombier /*
31*9b943567SDavid du Colombier  *	Rotate ammounts used in the algorithm
32*9b943567SDavid du Colombier  */
33*9b943567SDavid du Colombier enum
34*9b943567SDavid du Colombier {
35*9b943567SDavid du Colombier 	S11=	7,
36*9b943567SDavid du Colombier 	S12=	12,
37*9b943567SDavid du Colombier 	S13=	17,
38*9b943567SDavid du Colombier 	S14=	22,
39*9b943567SDavid du Colombier 
40*9b943567SDavid du Colombier 	S21=	5,
41*9b943567SDavid du Colombier 	S22=	9,
42*9b943567SDavid du Colombier 	S23=	14,
43*9b943567SDavid du Colombier 	S24=	20,
44*9b943567SDavid du Colombier 
45*9b943567SDavid du Colombier 	S31=	4,
46*9b943567SDavid du Colombier 	S32=	11,
47*9b943567SDavid du Colombier 	S33=	16,
48*9b943567SDavid du Colombier 	S34=	23,
49*9b943567SDavid du Colombier 
50*9b943567SDavid du Colombier 	S41=	6,
51*9b943567SDavid du Colombier 	S42=	10,
52*9b943567SDavid du Colombier 	S43=	15,
53*9b943567SDavid du Colombier 	S44=	21,
54*9b943567SDavid du Colombier };
55*9b943567SDavid du Colombier 
56*9b943567SDavid du Colombier static u32int md5tab[] =
57*9b943567SDavid du Colombier {
58*9b943567SDavid du Colombier 	/* round 1 */
59*9b943567SDavid du Colombier /*[0]*/	0xd76aa478,
60*9b943567SDavid du Colombier 	0xe8c7b756,
61*9b943567SDavid du Colombier 	0x242070db,
62*9b943567SDavid du Colombier 	0xc1bdceee,
63*9b943567SDavid du Colombier 	0xf57c0faf,
64*9b943567SDavid du Colombier 	0x4787c62a,
65*9b943567SDavid du Colombier 	0xa8304613,
66*9b943567SDavid du Colombier 	0xfd469501,
67*9b943567SDavid du Colombier 	0x698098d8,
68*9b943567SDavid du Colombier 	0x8b44f7af,
69*9b943567SDavid du Colombier 	0xffff5bb1,
70*9b943567SDavid du Colombier 	0x895cd7be,
71*9b943567SDavid du Colombier 	0x6b901122,
72*9b943567SDavid du Colombier 	0xfd987193,
73*9b943567SDavid du Colombier 	0xa679438e,
74*9b943567SDavid du Colombier 	0x49b40821,
75*9b943567SDavid du Colombier 
76*9b943567SDavid du Colombier 	/* round 2 */
77*9b943567SDavid du Colombier /*[16]*/0xf61e2562,
78*9b943567SDavid du Colombier 	0xc040b340,
79*9b943567SDavid du Colombier 	0x265e5a51,
80*9b943567SDavid du Colombier 	0xe9b6c7aa,
81*9b943567SDavid du Colombier 	0xd62f105d,
82*9b943567SDavid du Colombier 	 0x2441453,
83*9b943567SDavid du Colombier 	0xd8a1e681,
84*9b943567SDavid du Colombier 	0xe7d3fbc8,
85*9b943567SDavid du Colombier 	0x21e1cde6,
86*9b943567SDavid du Colombier 	0xc33707d6,
87*9b943567SDavid du Colombier 	0xf4d50d87,
88*9b943567SDavid du Colombier 	0x455a14ed,
89*9b943567SDavid du Colombier 	0xa9e3e905,
90*9b943567SDavid du Colombier 	0xfcefa3f8,
91*9b943567SDavid du Colombier 	0x676f02d9,
92*9b943567SDavid du Colombier 	0x8d2a4c8a,
93*9b943567SDavid du Colombier 
94*9b943567SDavid du Colombier 	/* round 3 */
95*9b943567SDavid du Colombier /*[32]*/0xfffa3942,
96*9b943567SDavid du Colombier 	0x8771f681,
97*9b943567SDavid du Colombier 	0x6d9d6122,
98*9b943567SDavid du Colombier 	0xfde5380c,
99*9b943567SDavid du Colombier 	0xa4beea44,
100*9b943567SDavid du Colombier 	0x4bdecfa9,
101*9b943567SDavid du Colombier 	0xf6bb4b60,
102*9b943567SDavid du Colombier 	0xbebfbc70,
103*9b943567SDavid du Colombier 	0x289b7ec6,
104*9b943567SDavid du Colombier 	0xeaa127fa,
105*9b943567SDavid du Colombier 	0xd4ef3085,
106*9b943567SDavid du Colombier 	 0x4881d05,
107*9b943567SDavid du Colombier 	0xd9d4d039,
108*9b943567SDavid du Colombier 	0xe6db99e5,
109*9b943567SDavid du Colombier 	0x1fa27cf8,
110*9b943567SDavid du Colombier 	0xc4ac5665,
111*9b943567SDavid du Colombier 
112*9b943567SDavid du Colombier 	/* round 4 */
113*9b943567SDavid du Colombier /*[48]*/0xf4292244,
114*9b943567SDavid du Colombier 	0x432aff97,
115*9b943567SDavid du Colombier 	0xab9423a7,
116*9b943567SDavid du Colombier 	0xfc93a039,
117*9b943567SDavid du Colombier 	0x655b59c3,
118*9b943567SDavid du Colombier 	0x8f0ccc92,
119*9b943567SDavid du Colombier 	0xffeff47d,
120*9b943567SDavid du Colombier 	0x85845dd1,
121*9b943567SDavid du Colombier 	0x6fa87e4f,
122*9b943567SDavid du Colombier 	0xfe2ce6e0,
123*9b943567SDavid du Colombier 	0xa3014314,
124*9b943567SDavid du Colombier 	0x4e0811a1,
125*9b943567SDavid du Colombier 	0xf7537e82,
126*9b943567SDavid du Colombier 	0xbd3af235,
127*9b943567SDavid du Colombier 	0x2ad7d2bb,
128*9b943567SDavid du Colombier 	0xeb86d391,
129*9b943567SDavid du Colombier };
130*9b943567SDavid du Colombier 
131*9b943567SDavid du Colombier static void decode(u32int*, uchar*, ulong);
132*9b943567SDavid du Colombier extern void _md5block(uchar *p, ulong len, u32int *s);
133*9b943567SDavid du Colombier 
134*9b943567SDavid du Colombier void
135*9b943567SDavid du Colombier _md5block(uchar *p, ulong len, u32int *s)
136*9b943567SDavid du Colombier {
137*9b943567SDavid du Colombier 	u32int a, b, c, d, sh;
138*9b943567SDavid du Colombier 	u32int *t;
139*9b943567SDavid du Colombier 	uchar *end;
140*9b943567SDavid du Colombier 	u32int x[16];
141*9b943567SDavid du Colombier 
142*9b943567SDavid du Colombier 	for(end = p+len; p < end; p += 64){
143*9b943567SDavid du Colombier 		a = s[0];
144*9b943567SDavid du Colombier 		b = s[1];
145*9b943567SDavid du Colombier 		c = s[2];
146*9b943567SDavid du Colombier 		d = s[3];
147*9b943567SDavid du Colombier 
148*9b943567SDavid du Colombier 		decode(x, p, 64);
149*9b943567SDavid du Colombier 
150*9b943567SDavid du Colombier 		t = md5tab;
151*9b943567SDavid du Colombier 		sh = 0;
152*9b943567SDavid du Colombier 		for(; sh != 16; t += 4){
153*9b943567SDavid du Colombier 			a += ((c ^ d) & b) ^ d;
154*9b943567SDavid du Colombier 			a += x[sh] + t[0];
155*9b943567SDavid du Colombier 			a = (a << S11) | (a >> (32 - S11));
156*9b943567SDavid du Colombier 			a += b;
157*9b943567SDavid du Colombier 
158*9b943567SDavid du Colombier 			d += ((b ^ c) & a) ^ c;
159*9b943567SDavid du Colombier 			d += x[sh + 1] + t[1];
160*9b943567SDavid du Colombier 			d = (d << S12) | (d >> (32 - S12));
161*9b943567SDavid du Colombier 			d += a;
162*9b943567SDavid du Colombier 
163*9b943567SDavid du Colombier 			c += ((a ^ b) & d) ^ b;
164*9b943567SDavid du Colombier 			c += x[sh + 2] + t[2];
165*9b943567SDavid du Colombier 			c = (c << S13) | (c >> (32 - S13));
166*9b943567SDavid du Colombier 			c += d;
167*9b943567SDavid du Colombier 
168*9b943567SDavid du Colombier 			b += ((d ^ a) & c) ^ a;
169*9b943567SDavid du Colombier 			b += x[sh + 3] + t[3];
170*9b943567SDavid du Colombier 			b = (b << S14) | (b >> (32 - S14));
171*9b943567SDavid du Colombier 			b += c;
172*9b943567SDavid du Colombier 
173*9b943567SDavid du Colombier 			sh += 4;
174*9b943567SDavid du Colombier 		}
175*9b943567SDavid du Colombier 		sh = 1;
176*9b943567SDavid du Colombier 		for(; sh != 1+20*4; t += 4){
177*9b943567SDavid du Colombier 			a += ((b ^ c) & d) ^ c;
178*9b943567SDavid du Colombier 			a += x[sh & 0xf] + t[0];
179*9b943567SDavid du Colombier 			a = (a << S21) | (a >> (32 - S21));
180*9b943567SDavid du Colombier 			a += b;
181*9b943567SDavid du Colombier 
182*9b943567SDavid du Colombier 			d += ((a ^ b) & c) ^ b;
183*9b943567SDavid du Colombier 			d += x[(sh + 5) & 0xf] + t[1];
184*9b943567SDavid du Colombier 			d = (d << S22) | (d >> (32 - S22));
185*9b943567SDavid du Colombier 			d += a;
186*9b943567SDavid du Colombier 
187*9b943567SDavid du Colombier 			c += ((d ^ a) & b) ^ a;
188*9b943567SDavid du Colombier 			c += x[(sh + 10) & 0xf] + t[2];
189*9b943567SDavid du Colombier 			c = (c << S23) | (c >> (32 - S23));
190*9b943567SDavid du Colombier 			c += d;
191*9b943567SDavid du Colombier 
192*9b943567SDavid du Colombier 			b += ((c ^ d) & a) ^ d;
193*9b943567SDavid du Colombier 			b += x[(sh + 15) & 0xf] + t[3];
194*9b943567SDavid du Colombier 			b = (b << S24) | (b >> (32 - S24));
195*9b943567SDavid du Colombier 			b += c;
196*9b943567SDavid du Colombier 
197*9b943567SDavid du Colombier 			sh += 20;
198*9b943567SDavid du Colombier 		}
199*9b943567SDavid du Colombier 		sh = 5;
200*9b943567SDavid du Colombier 		for(; sh != 5+12*4; t += 4){
201*9b943567SDavid du Colombier 			a += b ^ c ^ d;
202*9b943567SDavid du Colombier 			a += x[sh & 0xf] + t[0];
203*9b943567SDavid du Colombier 			a = (a << S31) | (a >> (32 - S31));
204*9b943567SDavid du Colombier 			a += b;
205*9b943567SDavid du Colombier 
206*9b943567SDavid du Colombier 			d += a ^ b ^ c;
207*9b943567SDavid du Colombier 			d += x[(sh + 3) & 0xf] + t[1];
208*9b943567SDavid du Colombier 			d = (d << S32) | (d >> (32 - S32));
209*9b943567SDavid du Colombier 			d += a;
210*9b943567SDavid du Colombier 
211*9b943567SDavid du Colombier 			c += d ^ a ^ b;
212*9b943567SDavid du Colombier 			c += x[(sh + 6) & 0xf] + t[2];
213*9b943567SDavid du Colombier 			c = (c << S33) | (c >> (32 - S33));
214*9b943567SDavid du Colombier 			c += d;
215*9b943567SDavid du Colombier 
216*9b943567SDavid du Colombier 			b += c ^ d ^ a;
217*9b943567SDavid du Colombier 			b += x[(sh + 9) & 0xf] + t[3];
218*9b943567SDavid du Colombier 			b = (b << S34) | (b >> (32 - S34));
219*9b943567SDavid du Colombier 			b += c;
220*9b943567SDavid du Colombier 
221*9b943567SDavid du Colombier 			sh += 12;
222*9b943567SDavid du Colombier 		}
223*9b943567SDavid du Colombier 		sh = 0;
224*9b943567SDavid du Colombier 		for(; sh != 28*4; t += 4){
225*9b943567SDavid du Colombier 			a += c ^ (b | ~d);
226*9b943567SDavid du Colombier 			a += x[sh & 0xf] + t[0];
227*9b943567SDavid du Colombier 			a = (a << S41) | (a >> (32 - S41));
228*9b943567SDavid du Colombier 			a += b;
229*9b943567SDavid du Colombier 
230*9b943567SDavid du Colombier 			d += b ^ (a | ~c);
231*9b943567SDavid du Colombier 			d += x[(sh + 7) & 0xf] + t[1];
232*9b943567SDavid du Colombier 			d = (d << S42) | (d >> (32 - S42));
233*9b943567SDavid du Colombier 			d += a;
234*9b943567SDavid du Colombier 
235*9b943567SDavid du Colombier 			c += a ^ (d | ~b);
236*9b943567SDavid du Colombier 			c += x[(sh + 14) & 0xf] + t[2];
237*9b943567SDavid du Colombier 			c = (c << S43) | (c >> (32 - S43));
238*9b943567SDavid du Colombier 			c += d;
239*9b943567SDavid du Colombier 
240*9b943567SDavid du Colombier 			b += d ^ (c | ~a);
241*9b943567SDavid du Colombier 			b += x[(sh + 21) & 0xf] + t[3];
242*9b943567SDavid du Colombier 			b = (b << S44) | (b >> (32 - S44));
243*9b943567SDavid du Colombier 			b += c;
244*9b943567SDavid du Colombier 
245*9b943567SDavid du Colombier 			sh += 28;
246*9b943567SDavid du Colombier 		}
247*9b943567SDavid du Colombier 
248*9b943567SDavid du Colombier 		s[0] += a;
249*9b943567SDavid du Colombier 		s[1] += b;
250*9b943567SDavid du Colombier 		s[2] += c;
251*9b943567SDavid du Colombier 		s[3] += d;
252*9b943567SDavid du Colombier 	}
253*9b943567SDavid du Colombier }
254*9b943567SDavid du Colombier 
255*9b943567SDavid du Colombier /*
256*9b943567SDavid du Colombier  *	decodes input (uchar) into output (u32int). Assumes len is
257*9b943567SDavid du Colombier  *	a multiple of 4.
258*9b943567SDavid du Colombier  */
259*9b943567SDavid du Colombier static void
260*9b943567SDavid du Colombier decode(u32int *output, uchar *input, ulong len)
261*9b943567SDavid du Colombier {
262*9b943567SDavid du Colombier 	uchar *e;
263*9b943567SDavid du Colombier 
264*9b943567SDavid du Colombier 	for(e = input+len; input < e; input += 4)
265*9b943567SDavid du Colombier 		*output++ = input[0] | (input[1] << 8) |
266*9b943567SDavid du Colombier 			(input[2] << 16) | (input[3] << 24);
267*9b943567SDavid du Colombier }
268