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