1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // 64-bit MD5 (does full MD5 but returns 64 bits only).
6 // Translation of ../../pkg/crypto/md5/md5*.go.
7
8 #include "go.h"
9 #include "md5.h"
10
11 static int md5block(MD5 *dig, uchar *p, int nn);
12
13 enum {
14 _Chunk = 64
15 };
16
17 #define _Init0 0x67452301
18 #define _Init1 0xEFCDAB89
19 #define _Init2 0x98BADCFE
20 #define _Init3 0x10325476
21
22 void
23 md5reset(MD5 *d)
24 {
25 d->s[0] = _Init0;
26 d->s[1] = _Init1;
27 d->s[2] = _Init2;
28 d->s[3] = _Init3;
29 d->nx = 0;
30 d->len = 0;
31 }
32
33 void
34 md5write(MD5 *d, uchar *p, int nn)
35 {
36 int i, n;
37
38 d->len += nn;
39 if(d->nx > 0) {
40 n = nn;
41 if(n > _Chunk - d->nx)
42 n = _Chunk - d->nx;
43 for(i=0; i<n; i++)
44 d->x[d->nx+i] = p[i];
45 d->nx += n;
46 if(d->nx == _Chunk) {
47 md5block(d, d->x, _Chunk);
48 d->nx = 0;
49 }
50 p += n;
51 nn -= n;
52 }
53 n = md5block(d, p, nn);
54 p += n;
55 nn -= n;
56 if(nn > 0) {
57 for(i=0; i<nn; i++)
58 d->x[i] = p[i];
59 d->nx = nn;
60 }
61 }
62
63 uint64
64 md5sum(MD5 *d)
65 {
66 uchar tmp[64];
67 int i;
68 uint64 len;
69
70 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
71 len = d->len;
72 memset(tmp, 0, sizeof tmp);
73 tmp[0] = 0x80;
74 if(len%64 < 56)
75 md5write(d, tmp, 56-len%64);
76 else
77 md5write(d, tmp, 64+56-len%64);
78
79 // Length in bits.
80 len <<= 3;
81 for(i=0; i<8; i++)
82 tmp[i] = len>>(8*i);
83 md5write(d, tmp, 8);
84
85 if(d->nx != 0)
86 fatal("md5sum");
87
88 return d->s[0] | ((uint64)d->s[1]<<32);
89 }
90
91
92 // MD5 block step.
93 // In its own file so that a faster assembly or C version
94 // can be substituted easily.
95
96 // table[i] = int((1<<32) * abs(sin(i+1 radians))).
97 static uint32 table[64] = {
98 // round 1
99 0xd76aa478,
100 0xe8c7b756,
101 0x242070db,
102 0xc1bdceee,
103 0xf57c0faf,
104 0x4787c62a,
105 0xa8304613,
106 0xfd469501,
107 0x698098d8,
108 0x8b44f7af,
109 0xffff5bb1,
110 0x895cd7be,
111 0x6b901122,
112 0xfd987193,
113 0xa679438e,
114 0x49b40821,
115
116 // round 2
117 0xf61e2562,
118 0xc040b340,
119 0x265e5a51,
120 0xe9b6c7aa,
121 0xd62f105d,
122 0x2441453,
123 0xd8a1e681,
124 0xe7d3fbc8,
125 0x21e1cde6,
126 0xc33707d6,
127 0xf4d50d87,
128 0x455a14ed,
129 0xa9e3e905,
130 0xfcefa3f8,
131 0x676f02d9,
132 0x8d2a4c8a,
133
134 // round3
135 0xfffa3942,
136 0x8771f681,
137 0x6d9d6122,
138 0xfde5380c,
139 0xa4beea44,
140 0x4bdecfa9,
141 0xf6bb4b60,
142 0xbebfbc70,
143 0x289b7ec6,
144 0xeaa127fa,
145 0xd4ef3085,
146 0x4881d05,
147 0xd9d4d039,
148 0xe6db99e5,
149 0x1fa27cf8,
150 0xc4ac5665,
151
152 // round 4
153 0xf4292244,
154 0x432aff97,
155 0xab9423a7,
156 0xfc93a039,
157 0x655b59c3,
158 0x8f0ccc92,
159 0xffeff47d,
160 0x85845dd1,
161 0x6fa87e4f,
162 0xfe2ce6e0,
163 0xa3014314,
164 0x4e0811a1,
165 0xf7537e82,
166 0xbd3af235,
167 0x2ad7d2bb,
168 0xeb86d391,
169 };
170
171 static uint32 shift1[] = { 7, 12, 17, 22 };
172 static uint32 shift2[] = { 5, 9, 14, 20 };
173 static uint32 shift3[] = { 4, 11, 16, 23 };
174 static uint32 shift4[] = { 6, 10, 15, 21 };
175
176 static int
177 md5block(MD5 *dig, uchar *p, int nn)
178 {
179 uint32 a, b, c, d, aa, bb, cc, dd;
180 int i, j, n;
181 uint32 X[16];
182
183 a = dig->s[0];
184 b = dig->s[1];
185 c = dig->s[2];
186 d = dig->s[3];
187 n = 0;
188
189 while(nn >= _Chunk) {
190 aa = a;
191 bb = b;
192 cc = c;
193 dd = d;
194
195 for(i=0; i<16; i++) {
196 j = i*4;
197 X[i] = p[j] | (p[j+1]<<8) | (p[j+2]<<16) | (p[j+3]<<24);
198 }
199
200 // Round 1.
201 for(i=0; i<16; i++) {
202 uint32 x, t, s, f;
203 x = i;
204 t = i;
205 s = shift1[i%4];
206 f = ((c ^ d) & b) ^ d;
207 a += f + X[x] + table[t];
208 a = a<<s | a>>(32-s);
209 a += b;
210
211 t = d;
212 d = c;
213 c = b;
214 b = a;
215 a = t;
216 }
217
218 // Round 2.
219 for(i=0; i<16; i++) {
220 uint32 x, t, s, g;
221
222 x = (1+5*i)%16;
223 t = 16+i;
224 s = shift2[i%4];
225 g = ((b ^ c) & d) ^ c;
226 a += g + X[x] + table[t];
227 a = a<<s | a>>(32-s);
228 a += b;
229
230 t = d;
231 d = c;
232 c = b;
233 b = a;
234 a = t;
235 }
236
237 // Round 3.
238 for(i=0; i<16; i++) {
239 uint32 x, t, s, h;
240
241 x = (5+3*i)%16;
242 t = 32+i;
243 s = shift3[i%4];
244 h = b ^ c ^ d;
245 a += h + X[x] + table[t];
246 a = a<<s | a>>(32-s);
247 a += b;
248
249 t = d;
250 d = c;
251 c = b;
252 b = a;
253 a = t;
254 }
255
256 // Round 4.
257 for(i=0; i<16; i++) {
258 uint32 x, s, t, ii;
259
260 x = (7*i)%16;
261 s = shift4[i%4];
262 t = 48+i;
263 ii = c ^ (b | ~d);
264 a += ii + X[x] + table[t];
265 a = a<<s | a>>(32-s);
266 a += b;
267
268 t = d;
269 d = c;
270 c = b;
271 b = a;
272 a = t;
273 }
274
275 a += aa;
276 b += bb;
277 c += cc;
278 d += dd;
279
280 p += _Chunk;
281 n += _Chunk;
282 nn -= _Chunk;
283 }
284
285 dig->s[0] = a;
286 dig->s[1] = b;
287 dig->s[2] = c;
288 dig->s[3] = d;
289 return n;
290 }