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