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 : #include <roken.h>
36 :
37 : #include "hash.h"
38 : #include "md5.h"
39 :
40 : #define A m->counter[0]
41 : #define B m->counter[1]
42 : #define C m->counter[2]
43 : #define D m->counter[3]
44 : #define X data
45 :
46 : int
47 2447172 : MD5_Init (struct md5 *m)
48 : {
49 2447172 : m->sz[0] = 0;
50 2447172 : m->sz[1] = 0;
51 2447172 : D = 0x10325476;
52 2447172 : C = 0x98badcfe;
53 2447172 : B = 0xefcdab89;
54 2447172 : A = 0x67452301;
55 2447172 : return 1;
56 : }
57 :
58 : #define F(x,y,z) CRAYFIX((x & y) | (~x & z))
59 : #define G(x,y,z) CRAYFIX((x & z) | (y & ~z))
60 : #define H(x,y,z) (x ^ y ^ z)
61 : #define I(x,y,z) CRAYFIX(y ^ (x | ~z))
62 :
63 : #define DOIT(a,b,c,d,k,s,i,OP) \
64 : a = b + cshift(a + OP(b,c,d) + X[k] + (i), s)
65 :
66 : #define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
67 : #define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
68 : #define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
69 : #define DO4(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,I)
70 :
71 : static inline void
72 7558980 : calc (struct md5 *m, uint32_t *data)
73 : {
74 1062 : uint32_t AA, BB, CC, DD;
75 :
76 7558980 : AA = A;
77 7558980 : BB = B;
78 7558980 : CC = C;
79 7558980 : DD = D;
80 :
81 : /* Round 1 */
82 :
83 7558980 : DO1(A,B,C,D,0,7,0xd76aa478);
84 7558980 : DO1(D,A,B,C,1,12,0xe8c7b756);
85 7558980 : DO1(C,D,A,B,2,17,0x242070db);
86 7558980 : DO1(B,C,D,A,3,22,0xc1bdceee);
87 :
88 7558980 : DO1(A,B,C,D,4,7,0xf57c0faf);
89 7558980 : DO1(D,A,B,C,5,12,0x4787c62a);
90 7558980 : DO1(C,D,A,B,6,17,0xa8304613);
91 7558980 : DO1(B,C,D,A,7,22,0xfd469501);
92 :
93 7558980 : DO1(A,B,C,D,8,7,0x698098d8);
94 7558980 : DO1(D,A,B,C,9,12,0x8b44f7af);
95 7558980 : DO1(C,D,A,B,10,17,0xffff5bb1);
96 7558980 : DO1(B,C,D,A,11,22,0x895cd7be);
97 :
98 7558980 : DO1(A,B,C,D,12,7,0x6b901122);
99 7558980 : DO1(D,A,B,C,13,12,0xfd987193);
100 7558980 : DO1(C,D,A,B,14,17,0xa679438e);
101 7558980 : DO1(B,C,D,A,15,22,0x49b40821);
102 :
103 : /* Round 2 */
104 :
105 7558980 : DO2(A,B,C,D,1,5,0xf61e2562);
106 7558980 : DO2(D,A,B,C,6,9,0xc040b340);
107 7558980 : DO2(C,D,A,B,11,14,0x265e5a51);
108 7558980 : DO2(B,C,D,A,0,20,0xe9b6c7aa);
109 :
110 7558980 : DO2(A,B,C,D,5,5,0xd62f105d);
111 7558980 : DO2(D,A,B,C,10,9,0x2441453);
112 7558980 : DO2(C,D,A,B,15,14,0xd8a1e681);
113 7558980 : DO2(B,C,D,A,4,20,0xe7d3fbc8);
114 :
115 7558980 : DO2(A,B,C,D,9,5,0x21e1cde6);
116 7558980 : DO2(D,A,B,C,14,9,0xc33707d6);
117 7558980 : DO2(C,D,A,B,3,14,0xf4d50d87);
118 7558980 : DO2(B,C,D,A,8,20,0x455a14ed);
119 :
120 7558980 : DO2(A,B,C,D,13,5,0xa9e3e905);
121 7558980 : DO2(D,A,B,C,2,9,0xfcefa3f8);
122 7558980 : DO2(C,D,A,B,7,14,0x676f02d9);
123 7558980 : DO2(B,C,D,A,12,20,0x8d2a4c8a);
124 :
125 : /* Round 3 */
126 :
127 7558980 : DO3(A,B,C,D,5,4,0xfffa3942);
128 7558980 : DO3(D,A,B,C,8,11,0x8771f681);
129 7558980 : DO3(C,D,A,B,11,16,0x6d9d6122);
130 7558980 : DO3(B,C,D,A,14,23,0xfde5380c);
131 :
132 7558980 : DO3(A,B,C,D,1,4,0xa4beea44);
133 7558980 : DO3(D,A,B,C,4,11,0x4bdecfa9);
134 7558980 : DO3(C,D,A,B,7,16,0xf6bb4b60);
135 7558980 : DO3(B,C,D,A,10,23,0xbebfbc70);
136 :
137 7558980 : DO3(A,B,C,D,13,4,0x289b7ec6);
138 7558980 : DO3(D,A,B,C,0,11,0xeaa127fa);
139 7558980 : DO3(C,D,A,B,3,16,0xd4ef3085);
140 7558980 : DO3(B,C,D,A,6,23,0x4881d05);
141 :
142 7558980 : DO3(A,B,C,D,9,4,0xd9d4d039);
143 7558980 : DO3(D,A,B,C,12,11,0xe6db99e5);
144 7558980 : DO3(C,D,A,B,15,16,0x1fa27cf8);
145 7558980 : DO3(B,C,D,A,2,23,0xc4ac5665);
146 :
147 : /* Round 4 */
148 :
149 7558980 : DO4(A,B,C,D,0,6,0xf4292244);
150 7558980 : DO4(D,A,B,C,7,10,0x432aff97);
151 7558980 : DO4(C,D,A,B,14,15,0xab9423a7);
152 7558980 : DO4(B,C,D,A,5,21,0xfc93a039);
153 :
154 7558980 : DO4(A,B,C,D,12,6,0x655b59c3);
155 7558980 : DO4(D,A,B,C,3,10,0x8f0ccc92);
156 7558980 : DO4(C,D,A,B,10,15,0xffeff47d);
157 7558980 : DO4(B,C,D,A,1,21,0x85845dd1);
158 :
159 7558980 : DO4(A,B,C,D,8,6,0x6fa87e4f);
160 7558980 : DO4(D,A,B,C,15,10,0xfe2ce6e0);
161 7558980 : DO4(C,D,A,B,6,15,0xa3014314);
162 7558980 : DO4(B,C,D,A,13,21,0x4e0811a1);
163 :
164 7558980 : DO4(A,B,C,D,4,6,0xf7537e82);
165 7558980 : DO4(D,A,B,C,11,10,0xbd3af235);
166 7558980 : DO4(C,D,A,B,2,15,0x2ad7d2bb);
167 7558980 : DO4(B,C,D,A,9,21,0xeb86d391);
168 :
169 7558980 : A += AA;
170 7558980 : B += BB;
171 7558980 : C += CC;
172 7558980 : D += DD;
173 7558980 : }
174 :
175 : /*
176 : * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
177 : */
178 :
179 : #if defined(WORDS_BIGENDIAN)
180 : static inline uint32_t
181 : swap_uint32_t (uint32_t t)
182 : {
183 : uint32_t temp1, temp2;
184 :
185 : temp1 = cshift(t, 16);
186 : temp2 = temp1 >> 8;
187 : temp1 &= 0x00ff00ff;
188 : temp2 &= 0x00ff00ff;
189 : temp1 <<= 8;
190 : return temp1 | temp2;
191 : }
192 : #endif
193 :
194 : struct x32{
195 : unsigned int a:32;
196 : unsigned int b:32;
197 : };
198 :
199 : int
200 6210674 : MD5_Update (struct md5 *m, const void *v, size_t len)
201 : {
202 6210674 : const unsigned char *p = v;
203 6210674 : size_t old_sz = m->sz[0];
204 1112 : size_t offset;
205 :
206 6210674 : m->sz[0] += len * 8;
207 6210674 : if (m->sz[0] < old_sz)
208 0 : ++m->sz[1];
209 6210674 : offset = (old_sz / 8) % 64;
210 16405944 : while(len > 0){
211 10195270 : size_t l = min(len, 64 - offset);
212 10195270 : memcpy(m->save + offset, p, l);
213 10195270 : offset += l;
214 10195270 : p += l;
215 10195270 : len -= l;
216 10195270 : if(offset == 64){
217 : #if defined(WORDS_BIGENDIAN)
218 : int i;
219 : uint32_t swapped[16];
220 : struct x32 *us = (struct x32*)m->save;
221 : for(i = 0; i < 8; i++){
222 : swapped[2*i+0] = swap_uint32_t(us[i].a);
223 : swapped[2*i+1] = swap_uint32_t(us[i].b);
224 : }
225 : calc(m, swapped);
226 : #else
227 7558980 : calc(m, (uint32_t*)m->save);
228 : #endif
229 7558980 : offset = 0;
230 : }
231 : }
232 6210674 : return 1;
233 : }
234 :
235 : int
236 2447172 : MD5_Final (void *res, struct md5 *m)
237 : {
238 436 : unsigned char zeros[72];
239 2447172 : unsigned offset = (m->sz[0] / 8) % 64;
240 2447172 : unsigned int dstart = (120 - offset - 1) % 64 + 1;
241 :
242 2447172 : *zeros = 0x80;
243 2447172 : memset (zeros + 1, 0, sizeof(zeros) - 1);
244 2447172 : zeros[dstart+0] = (m->sz[0] >> 0) & 0xff;
245 2447172 : zeros[dstart+1] = (m->sz[0] >> 8) & 0xff;
246 2447172 : zeros[dstart+2] = (m->sz[0] >> 16) & 0xff;
247 2447172 : zeros[dstart+3] = (m->sz[0] >> 24) & 0xff;
248 2447172 : zeros[dstart+4] = (m->sz[1] >> 0) & 0xff;
249 2447172 : zeros[dstart+5] = (m->sz[1] >> 8) & 0xff;
250 2447172 : zeros[dstart+6] = (m->sz[1] >> 16) & 0xff;
251 2447172 : zeros[dstart+7] = (m->sz[1] >> 24) & 0xff;
252 2447172 : MD5_Update (m, zeros, dstart + 8);
253 : {
254 436 : int i;
255 2447172 : unsigned char *r = (unsigned char *)res;
256 :
257 12236296 : for (i = 0; i < 4; ++i) {
258 9788688 : r[4*i] = m->counter[i] & 0xFF;
259 9788688 : r[4*i+1] = (m->counter[i] >> 8) & 0xFF;
260 9788688 : r[4*i+2] = (m->counter[i] >> 16) & 0xFF;
261 9788688 : r[4*i+3] = (m->counter[i] >> 24) & 0xFF;
262 : }
263 : }
264 : #if 0
265 : {
266 : int i;
267 : uint32_t *r = (uint32_t *)res;
268 :
269 : for (i = 0; i < 4; ++i)
270 : r[i] = swap_uint32_t (m->counter[i]);
271 : }
272 : #endif
273 2447172 : return 1;
274 : }
|