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 "md4.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 1182 : MD4_Init (struct md4 *m)
48 : {
49 1182 : m->sz[0] = 0;
50 1182 : m->sz[1] = 0;
51 1182 : D = 0x10325476;
52 1182 : C = 0x98badcfe;
53 1182 : B = 0xefcdab89;
54 1182 : A = 0x67452301;
55 1182 : return 1;
56 : }
57 :
58 : #define F(x,y,z) CRAYFIX((x & y) | (~x & z))
59 : #define G(x,y,z) ((x & y) | (x & z) | (y & z))
60 : #define H(x,y,z) (x ^ y ^ z)
61 :
62 : #define DOIT(a,b,c,d,k,s,i,OP) \
63 : a = cshift(a + OP(b,c,d) + X[k] + i, s)
64 :
65 : #define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)
66 : #define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)
67 : #define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)
68 :
69 : static inline void
70 1580 : calc (struct md4 *m, uint32_t *data)
71 : {
72 38 : uint32_t AA, BB, CC, DD;
73 :
74 1580 : AA = A;
75 1580 : BB = B;
76 1580 : CC = C;
77 1580 : DD = D;
78 :
79 : /* Round 1 */
80 :
81 1580 : DO1(A,B,C,D,0,3,0);
82 1580 : DO1(D,A,B,C,1,7,0);
83 1580 : DO1(C,D,A,B,2,11,0);
84 1580 : DO1(B,C,D,A,3,19,0);
85 :
86 1580 : DO1(A,B,C,D,4,3,0);
87 1580 : DO1(D,A,B,C,5,7,0);
88 1580 : DO1(C,D,A,B,6,11,0);
89 1580 : DO1(B,C,D,A,7,19,0);
90 :
91 1580 : DO1(A,B,C,D,8,3,0);
92 1580 : DO1(D,A,B,C,9,7,0);
93 1580 : DO1(C,D,A,B,10,11,0);
94 1580 : DO1(B,C,D,A,11,19,0);
95 :
96 1580 : DO1(A,B,C,D,12,3,0);
97 1580 : DO1(D,A,B,C,13,7,0);
98 1580 : DO1(C,D,A,B,14,11,0);
99 1580 : DO1(B,C,D,A,15,19,0);
100 :
101 : /* Round 2 */
102 :
103 1580 : DO2(A,B,C,D,0,3,0x5A827999);
104 1580 : DO2(D,A,B,C,4,5,0x5A827999);
105 1580 : DO2(C,D,A,B,8,9,0x5A827999);
106 1580 : DO2(B,C,D,A,12,13,0x5A827999);
107 :
108 1580 : DO2(A,B,C,D,1,3,0x5A827999);
109 1580 : DO2(D,A,B,C,5,5,0x5A827999);
110 1580 : DO2(C,D,A,B,9,9,0x5A827999);
111 1580 : DO2(B,C,D,A,13,13,0x5A827999);
112 :
113 1580 : DO2(A,B,C,D,2,3,0x5A827999);
114 1580 : DO2(D,A,B,C,6,5,0x5A827999);
115 1580 : DO2(C,D,A,B,10,9,0x5A827999);
116 1580 : DO2(B,C,D,A,14,13,0x5A827999);
117 :
118 1580 : DO2(A,B,C,D,3,3,0x5A827999);
119 1580 : DO2(D,A,B,C,7,5,0x5A827999);
120 1580 : DO2(C,D,A,B,11,9,0x5A827999);
121 1580 : DO2(B,C,D,A,15,13,0x5A827999);
122 :
123 : /* Round 3 */
124 :
125 1580 : DO3(A,B,C,D,0,3,0x6ED9EBA1);
126 1580 : DO3(D,A,B,C,8,9,0x6ED9EBA1);
127 1580 : DO3(C,D,A,B,4,11,0x6ED9EBA1);
128 1580 : DO3(B,C,D,A,12,15,0x6ED9EBA1);
129 :
130 1580 : DO3(A,B,C,D,2,3,0x6ED9EBA1);
131 1580 : DO3(D,A,B,C,10,9,0x6ED9EBA1);
132 1580 : DO3(C,D,A,B,6,11,0x6ED9EBA1);
133 1580 : DO3(B,C,D,A,14,15,0x6ED9EBA1);
134 :
135 1580 : DO3(A,B,C,D,1,3,0x6ED9EBA1);
136 1580 : DO3(D,A,B,C,9,9,0x6ED9EBA1);
137 1580 : DO3(C,D,A,B,5,11,0x6ED9EBA1);
138 1580 : DO3(B,C,D,A,13,15,0x6ED9EBA1);
139 :
140 1580 : DO3(A,B,C,D,3,3,0x6ED9EBA1);
141 1580 : DO3(D,A,B,C,11,9,0x6ED9EBA1);
142 1580 : DO3(C,D,A,B,7,11,0x6ED9EBA1);
143 1580 : DO3(B,C,D,A,15,15,0x6ED9EBA1);
144 :
145 1580 : A += AA;
146 1580 : B += BB;
147 1580 : C += CC;
148 1580 : D += DD;
149 1580 : }
150 :
151 : /*
152 : * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
153 : */
154 :
155 : #if defined(WORDS_BIGENDIAN)
156 : static inline uint32_t
157 : swap_uint32_t (uint32_t t)
158 : {
159 : uint32_t temp1, temp2;
160 :
161 : temp1 = cshift(t, 16);
162 : temp2 = temp1 >> 8;
163 : temp1 &= 0x00ff00ff;
164 : temp2 &= 0x00ff00ff;
165 : temp1 <<= 8;
166 : return temp1 | temp2;
167 : }
168 : #endif
169 :
170 : struct x32{
171 : unsigned int a:32;
172 : unsigned int b:32;
173 : };
174 :
175 : int
176 57740 : MD4_Update (struct md4 *m, const void *v, size_t len)
177 : {
178 57740 : const unsigned char *p = v;
179 57740 : size_t old_sz = m->sz[0];
180 2114 : size_t offset;
181 :
182 57740 : m->sz[0] += len * 8;
183 57740 : if (m->sz[0] < old_sz)
184 0 : ++m->sz[1];
185 57740 : offset = (old_sz / 8) % 64;
186 115488 : while(len > 0) {
187 57748 : size_t l = min(len, 64 - offset);
188 57748 : memcpy(m->save + offset, p, l);
189 57748 : offset += l;
190 57748 : p += l;
191 57748 : len -= l;
192 57748 : if(offset == 64) {
193 : #if defined(WORDS_BIGENDIAN)
194 : int i;
195 : uint32_t current[16];
196 : struct x32 *us = (struct x32*)m->save;
197 : for(i = 0; i < 8; i++){
198 : current[2*i+0] = swap_uint32_t(us[i].a);
199 : current[2*i+1] = swap_uint32_t(us[i].b);
200 : }
201 : calc(m, current);
202 : #else
203 1580 : calc(m, (uint32_t*)m->save);
204 : #endif
205 1580 : offset = 0;
206 : }
207 : }
208 57740 : return 1;
209 : }
210 :
211 : int
212 1182 : MD4_Final (void *res, struct md4 *m)
213 : {
214 6 : unsigned char zeros[72];
215 1182 : unsigned offset = (m->sz[0] / 8) % 64;
216 1182 : unsigned int dstart = (120 - offset - 1) % 64 + 1;
217 :
218 1182 : *zeros = 0x80;
219 1182 : memset (zeros + 1, 0, sizeof(zeros) - 1);
220 1182 : zeros[dstart+0] = (m->sz[0] >> 0) & 0xff;
221 1182 : zeros[dstart+1] = (m->sz[0] >> 8) & 0xff;
222 1182 : zeros[dstart+2] = (m->sz[0] >> 16) & 0xff;
223 1182 : zeros[dstart+3] = (m->sz[0] >> 24) & 0xff;
224 1182 : zeros[dstart+4] = (m->sz[1] >> 0) & 0xff;
225 1182 : zeros[dstart+5] = (m->sz[1] >> 8) & 0xff;
226 1182 : zeros[dstart+6] = (m->sz[1] >> 16) & 0xff;
227 1182 : zeros[dstart+7] = (m->sz[1] >> 24) & 0xff;
228 1182 : MD4_Update (m, zeros, dstart + 8);
229 : {
230 6 : int i;
231 1182 : unsigned char *r = (unsigned char *)res;
232 :
233 5916 : for (i = 0; i < 4; ++i) {
234 4728 : r[4*i] = m->counter[i] & 0xFF;
235 4728 : r[4*i+1] = (m->counter[i] >> 8) & 0xFF;
236 4728 : r[4*i+2] = (m->counter[i] >> 16) & 0xFF;
237 4728 : r[4*i+3] = (m->counter[i] >> 24) & 0xFF;
238 : }
239 : }
240 : #if 0
241 : {
242 : int i;
243 : uint32_t *r = (uint32_t *)res;
244 :
245 : for (i = 0; i < 4; ++i)
246 : r[i] = swap_uint32_t (m->counter[i]);
247 : }
248 : #endif
249 1182 : return 1;
250 : }
|