ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / cifs / md4.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    a implementation of MD4 designed for use in the SMB authentication protocol
5    Copyright (C) Andrew Tridgell 1997-1998.
6    Modified by Steve French (sfrench@us.ibm.com) 2002-2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 #include <linux/module.h>
23 #include <linux/fs.h>
24 /* NOTE: This code makes no attempt to be fast! */
25
26 static __u32
27 F(__u32 X, __u32 Y, __u32 Z)
28 {
29         return (X & Y) | ((~X) & Z);
30 }
31
32 static __u32
33 G(__u32 X, __u32 Y, __u32 Z)
34 {
35         return (X & Y) | (X & Z) | (Y & Z);
36 }
37
38 static __u32
39 H(__u32 X, __u32 Y, __u32 Z)
40 {
41         return X ^ Y ^ Z;
42 }
43
44 static __u32
45 lshift(__u32 x, int s)
46 {
47         x &= 0xFFFFFFFF;
48         return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
49 }
50
51 #define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
52 #define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
53 #define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
54
55 /* this applies md4 to 64 byte chunks */
56 static void
57 mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D)
58 {
59         int j;
60         __u32 AA, BB, CC, DD;
61         __u32 X[16];
62
63
64         for (j = 0; j < 16; j++)
65                 X[j] = M[j];
66
67         AA = *A;
68         BB = *B;
69         CC = *C;
70         DD = *D;
71
72         ROUND1(A, B, C, D, 0, 3);
73         ROUND1(D, A, B, C, 1, 7);
74         ROUND1(C, D, A, B, 2, 11);
75         ROUND1(B, C, D, A, 3, 19);
76         ROUND1(A, B, C, D, 4, 3);
77         ROUND1(D, A, B, C, 5, 7);
78         ROUND1(C, D, A, B, 6, 11);
79         ROUND1(B, C, D, A, 7, 19);
80         ROUND1(A, B, C, D, 8, 3);
81         ROUND1(D, A, B, C, 9, 7);
82         ROUND1(C, D, A, B, 10, 11);
83         ROUND1(B, C, D, A, 11, 19);
84         ROUND1(A, B, C, D, 12, 3);
85         ROUND1(D, A, B, C, 13, 7);
86         ROUND1(C, D, A, B, 14, 11);
87         ROUND1(B, C, D, A, 15, 19);
88
89         ROUND2(A, B, C, D, 0, 3);
90         ROUND2(D, A, B, C, 4, 5);
91         ROUND2(C, D, A, B, 8, 9);
92         ROUND2(B, C, D, A, 12, 13);
93         ROUND2(A, B, C, D, 1, 3);
94         ROUND2(D, A, B, C, 5, 5);
95         ROUND2(C, D, A, B, 9, 9);
96         ROUND2(B, C, D, A, 13, 13);
97         ROUND2(A, B, C, D, 2, 3);
98         ROUND2(D, A, B, C, 6, 5);
99         ROUND2(C, D, A, B, 10, 9);
100         ROUND2(B, C, D, A, 14, 13);
101         ROUND2(A, B, C, D, 3, 3);
102         ROUND2(D, A, B, C, 7, 5);
103         ROUND2(C, D, A, B, 11, 9);
104         ROUND2(B, C, D, A, 15, 13);
105
106         ROUND3(A, B, C, D, 0, 3);
107         ROUND3(D, A, B, C, 8, 9);
108         ROUND3(C, D, A, B, 4, 11);
109         ROUND3(B, C, D, A, 12, 15);
110         ROUND3(A, B, C, D, 2, 3);
111         ROUND3(D, A, B, C, 10, 9);
112         ROUND3(C, D, A, B, 6, 11);
113         ROUND3(B, C, D, A, 14, 15);
114         ROUND3(A, B, C, D, 1, 3);
115         ROUND3(D, A, B, C, 9, 9);
116         ROUND3(C, D, A, B, 5, 11);
117         ROUND3(B, C, D, A, 13, 15);
118         ROUND3(A, B, C, D, 3, 3);
119         ROUND3(D, A, B, C, 11, 9);
120         ROUND3(C, D, A, B, 7, 11);
121         ROUND3(B, C, D, A, 15, 15);
122
123         *A += AA;
124         *B += BB;
125         *C += CC;
126         *D += DD;
127
128         *A &= 0xFFFFFFFF;
129         *B &= 0xFFFFFFFF;
130         *C &= 0xFFFFFFFF;
131         *D &= 0xFFFFFFFF;
132
133         for (j = 0; j < 16; j++)
134                 X[j] = 0;
135 }
136
137 static void
138 copy64(__u32 * M, unsigned char *in)
139 {
140         int i;
141
142         for (i = 0; i < 16; i++)
143                 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
144                     (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
145 }
146
147 static void
148 copy4(unsigned char *out, __u32 x)
149 {
150         out[0] = x & 0xFF;
151         out[1] = (x >> 8) & 0xFF;
152         out[2] = (x >> 16) & 0xFF;
153         out[3] = (x >> 24) & 0xFF;
154 }
155
156 /* produce a md4 message digest from data of length n bytes */
157 void
158 mdfour(unsigned char *out, unsigned char *in, int n)
159 {
160         unsigned char buf[128];
161         __u32 M[16];
162         __u32 b = n * 8;
163         int i;
164         __u32 A = 0x67452301;
165         __u32 B = 0xefcdab89;
166         __u32 C = 0x98badcfe;
167         __u32 D = 0x10325476;
168
169         while (n > 64) {
170                 copy64(M, in);
171                 mdfour64(M,&A,&B, &C, &D);
172                 in += 64;
173                 n -= 64;
174         }
175
176         for (i = 0; i < 128; i++)
177                 buf[i] = 0;
178         memcpy(buf, in, n);
179         buf[n] = 0x80;
180
181         if (n <= 55) {
182                 copy4(buf + 56, b);
183                 copy64(M, buf);
184                 mdfour64(M, &A, &B, &C, &D);
185         } else {
186                 copy4(buf + 120, b);
187                 copy64(M, buf);
188                 mdfour64(M, &A, &B, &C, &D);
189                 copy64(M, buf + 64);
190                 mdfour64(M, &A, &B, &C, &D);
191         }
192
193         for (i = 0; i < 128; i++)
194                 buf[i] = 0;
195         copy64(M, buf);
196
197         copy4(out, A);
198         copy4(out + 4, B);
199         copy4(out + 8, C);
200         copy4(out + 12, D);
201
202         A = B = C = D = 0;
203 }