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