Line data Source code
1 : /*
2 : * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "config.h"
35 :
36 : #include "hash.h"
37 : #include "md5.h"
38 :
39 : #define A m->counter[0]
40 : #define B m->counter[1]
41 : #define C m->counter[2]
42 : #define D m->counter[3]
43 : #define X data
44 :
45 : void
46 2046550 : MD5_Init (struct md5 *m)
47 : {
48 2046550 : m->sz[0] = 0;
49 2046550 : m->sz[1] = 0;
50 2046550 : D = 0x10325476;
51 2046550 : C = 0x98badcfe;
52 2046550 : B = 0xefcdab89;
53 2046550 : A = 0x67452301;
54 2046550 : }
55 :
56 : #define F(x,y,z) CRAYFIX((x & y) | (~x & z))
57 : #define G(x,y,z) CRAYFIX((x & z) | (y & ~z))
58 : #define H(x,y,z) (x ^ y ^ z)
59 : #define I(x,y,z) CRAYFIX(y ^ (x | ~z))
60 :
61 : #define DOIT(a,b,c,d,k,s,i,OP) \
62 : a = b + cshift(a + OP(b,c,d) + X[k] + (i), s)
63 :
64 : #define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
65 : #define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
66 : #define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
67 : #define DO4(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,I)
68 :
69 : static inline void
70 6484591 : calc (struct md5 *m, uint32_t *data)
71 : {
72 : uint32_t AA, BB, CC, DD;
73 :
74 6484591 : AA = A;
75 6484591 : BB = B;
76 6484591 : CC = C;
77 6484591 : DD = D;
78 :
79 : /* Round 1 */
80 :
81 6493341 : DO1(A,B,C,D,0,7,0xd76aa478);
82 6493341 : DO1(D,A,B,C,1,12,0xe8c7b756);
83 6493341 : DO1(C,D,A,B,2,17,0x242070db);
84 6493341 : DO1(B,C,D,A,3,22,0xc1bdceee);
85 :
86 6493341 : DO1(A,B,C,D,4,7,0xf57c0faf);
87 6493341 : DO1(D,A,B,C,5,12,0x4787c62a);
88 6493341 : DO1(C,D,A,B,6,17,0xa8304613);
89 6493341 : DO1(B,C,D,A,7,22,0xfd469501);
90 :
91 6493341 : DO1(A,B,C,D,8,7,0x698098d8);
92 6493341 : DO1(D,A,B,C,9,12,0x8b44f7af);
93 6493341 : DO1(C,D,A,B,10,17,0xffff5bb1);
94 6493341 : DO1(B,C,D,A,11,22,0x895cd7be);
95 :
96 6493341 : DO1(A,B,C,D,12,7,0x6b901122);
97 6493341 : DO1(D,A,B,C,13,12,0xfd987193);
98 6493341 : DO1(C,D,A,B,14,17,0xa679438e);
99 6493341 : DO1(B,C,D,A,15,22,0x49b40821);
100 :
101 : /* Round 2 */
102 :
103 6493341 : DO2(A,B,C,D,1,5,0xf61e2562);
104 6493341 : DO2(D,A,B,C,6,9,0xc040b340);
105 6493341 : DO2(C,D,A,B,11,14,0x265e5a51);
106 6493341 : DO2(B,C,D,A,0,20,0xe9b6c7aa);
107 :
108 6493341 : DO2(A,B,C,D,5,5,0xd62f105d);
109 6493341 : DO2(D,A,B,C,10,9,0x2441453);
110 6493341 : DO2(C,D,A,B,15,14,0xd8a1e681);
111 6493341 : DO2(B,C,D,A,4,20,0xe7d3fbc8);
112 :
113 6493341 : DO2(A,B,C,D,9,5,0x21e1cde6);
114 6493341 : DO2(D,A,B,C,14,9,0xc33707d6);
115 6493341 : DO2(C,D,A,B,3,14,0xf4d50d87);
116 6493341 : DO2(B,C,D,A,8,20,0x455a14ed);
117 :
118 6493341 : DO2(A,B,C,D,13,5,0xa9e3e905);
119 6493341 : DO2(D,A,B,C,2,9,0xfcefa3f8);
120 6493341 : DO2(C,D,A,B,7,14,0x676f02d9);
121 6493341 : DO2(B,C,D,A,12,20,0x8d2a4c8a);
122 :
123 : /* Round 3 */
124 :
125 6493341 : DO3(A,B,C,D,5,4,0xfffa3942);
126 6493341 : DO3(D,A,B,C,8,11,0x8771f681);
127 6493341 : DO3(C,D,A,B,11,16,0x6d9d6122);
128 6493341 : DO3(B,C,D,A,14,23,0xfde5380c);
129 :
130 6493341 : DO3(A,B,C,D,1,4,0xa4beea44);
131 6493341 : DO3(D,A,B,C,4,11,0x4bdecfa9);
132 6493341 : DO3(C,D,A,B,7,16,0xf6bb4b60);
133 6493341 : DO3(B,C,D,A,10,23,0xbebfbc70);
134 :
135 6493341 : DO3(A,B,C,D,13,4,0x289b7ec6);
136 6493341 : DO3(D,A,B,C,0,11,0xeaa127fa);
137 6493341 : DO3(C,D,A,B,3,16,0xd4ef3085);
138 6493341 : DO3(B,C,D,A,6,23,0x4881d05);
139 :
140 6493341 : DO3(A,B,C,D,9,4,0xd9d4d039);
141 6493341 : DO3(D,A,B,C,12,11,0xe6db99e5);
142 6493341 : DO3(C,D,A,B,15,16,0x1fa27cf8);
143 6493341 : DO3(B,C,D,A,2,23,0xc4ac5665);
144 :
145 : /* Round 4 */
146 :
147 6493341 : DO4(A,B,C,D,0,6,0xf4292244);
148 6493341 : DO4(D,A,B,C,7,10,0x432aff97);
149 6493341 : DO4(C,D,A,B,14,15,0xab9423a7);
150 6493341 : DO4(B,C,D,A,5,21,0xfc93a039);
151 :
152 6493341 : DO4(A,B,C,D,12,6,0x655b59c3);
153 6493341 : DO4(D,A,B,C,3,10,0x8f0ccc92);
154 6493341 : DO4(C,D,A,B,10,15,0xffeff47d);
155 6493341 : DO4(B,C,D,A,1,21,0x85845dd1);
156 :
157 6493341 : DO4(A,B,C,D,8,6,0x6fa87e4f);
158 6493341 : DO4(D,A,B,C,15,10,0xfe2ce6e0);
159 6493341 : DO4(C,D,A,B,6,15,0xa3014314);
160 6493341 : DO4(B,C,D,A,13,21,0x4e0811a1);
161 :
162 6493341 : DO4(A,B,C,D,4,6,0xf7537e82);
163 6493341 : DO4(D,A,B,C,11,10,0xbd3af235);
164 6493341 : DO4(C,D,A,B,2,15,0x2ad7d2bb);
165 6493341 : DO4(B,C,D,A,9,21,0xeb86d391);
166 :
167 6484591 : A += AA;
168 6484591 : B += BB;
169 6484591 : C += CC;
170 6484591 : D += DD;
171 6484591 : }
172 :
173 : /*
174 : * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
175 : */
176 :
177 : #if defined(WORDS_BIGENDIAN)
178 : static inline uint32_t
179 : swap_uint32_t (uint32_t t)
180 : {
181 : uint32_t temp1, temp2;
182 :
183 : temp1 = cshift(t, 16);
184 : temp2 = temp1 >> 8;
185 : temp1 &= 0x00ff00ff;
186 : temp2 &= 0x00ff00ff;
187 : temp1 <<= 8;
188 : return temp1 | temp2;
189 : }
190 : #endif
191 :
192 : struct x32{
193 : unsigned int a:32;
194 : unsigned int b:32;
195 : };
196 :
197 : void
198 4242681 : MD5_Update (struct md5 *m, const void *v, size_t len)
199 : {
200 4242681 : const unsigned char *p = v;
201 4242681 : size_t old_sz = m->sz[0];
202 : size_t offset;
203 :
204 4242681 : m->sz[0] += len * 8;
205 4242681 : if (m->sz[0] < old_sz)
206 0 : ++m->sz[1];
207 4242681 : offset = (old_sz / 8) % 64;
208 17162668 : while(len > 0){
209 8677306 : size_t l = min(len, 64 - offset);
210 8689886 : memcpy(m->save + offset, p, l);
211 8677306 : offset += l;
212 8677306 : p += l;
213 8677306 : len -= l;
214 8677306 : if(offset == 64){
215 : #if defined(WORDS_BIGENDIAN)
216 : int i;
217 : uint32_t current[16];
218 : struct x32 *us = (struct x32*)m->save;
219 : for(i = 0; i < 8; i++){
220 : current[2*i+0] = swap_uint32_t(us[i].a);
221 : current[2*i+1] = swap_uint32_t(us[i].b);
222 : }
223 : calc(m, current);
224 : #else
225 6484591 : calc(m, (uint32_t*)m->save);
226 : #endif
227 6484591 : offset = 0;
228 : }
229 : }
230 4242681 : }
231 :
232 : void
233 2046550 : MD5_Final (void *res, struct md5 *m)
234 : {
235 : unsigned char zeros[72];
236 2046550 : unsigned offset = (m->sz[0] / 8) % 64;
237 2046550 : unsigned int dstart = (120 - offset - 1) % 64 + 1;
238 :
239 2046550 : *zeros = 0x80;
240 2050360 : memset (zeros + 1, 0, sizeof(zeros) - 1);
241 2046550 : zeros[dstart+0] = (m->sz[0] >> 0) & 0xff;
242 2046550 : zeros[dstart+1] = (m->sz[0] >> 8) & 0xff;
243 2046550 : zeros[dstart+2] = (m->sz[0] >> 16) & 0xff;
244 2046550 : zeros[dstart+3] = (m->sz[0] >> 24) & 0xff;
245 2046550 : zeros[dstart+4] = (m->sz[1] >> 0) & 0xff;
246 2046550 : zeros[dstart+5] = (m->sz[1] >> 8) & 0xff;
247 2046550 : zeros[dstart+6] = (m->sz[1] >> 16) & 0xff;
248 2046550 : zeros[dstart+7] = (m->sz[1] >> 24) & 0xff;
249 2046550 : MD5_Update (m, zeros, dstart + 8);
250 : {
251 : int i;
252 2046550 : unsigned char *r = (unsigned char *)res;
253 :
254 10232750 : for (i = 0; i < 4; ++i) {
255 8186200 : r[4*i] = m->counter[i] & 0xFF;
256 8186200 : r[4*i+1] = (m->counter[i] >> 8) & 0xFF;
257 8186200 : r[4*i+2] = (m->counter[i] >> 16) & 0xFF;
258 8186200 : r[4*i+3] = (m->counter[i] >> 24) & 0xFF;
259 : }
260 : }
261 : #if 0
262 : {
263 : int i;
264 : uint32_t *r = (uint32_t *)res;
265 :
266 : for (i = 0; i < 4; ++i)
267 : r[i] = swap_uint32_t (m->counter[i]);
268 : }
269 : #endif
270 2046550 : }
|