Merge branch 'spi/merge' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / fs / cifs / smbdes.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4
5    a partial implementation of DES designed for use in the
6    SMB authentication protocol
7
8    Copyright (C) Andrew Tridgell 1998
9    Modified by Steve French (sfrench@us.ibm.com) 2002,2004
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 /* NOTES:
27
28    This code makes no attempt to be fast! In fact, it is a very
29    slow implementation
30
31    This code is NOT a complete DES implementation. It implements only
32    the minimum necessary for SMB authentication, as used by all SMB
33    products (including every copy of Microsoft Windows95 ever sold)
34
35    In particular, it can only do a unchained forward DES pass. This
36    means it is not possible to use this code for encryption/decryption
37    of data, instead it is only useful as a "hash" algorithm.
38
39    There is no entry point into this code that allows normal DES operation.
40
41    I believe this means that this code does not come under ITAR
42    regulations but this is NOT a legal opinion. If you are concerned
43    about the applicability of ITAR regulations to this code then you
44    should confirm it for yourself (and maybe let me know if you come
45    up with a different answer to the one above)
46 */
47 #include <linux/slab.h>
48 #define uchar unsigned char
49
50 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
51         1, 58, 50, 42, 34, 26, 18,
52         10, 2, 59, 51, 43, 35, 27,
53         19, 11, 3, 60, 52, 44, 36,
54         63, 55, 47, 39, 31, 23, 15,
55         7, 62, 54, 46, 38, 30, 22,
56         14, 6, 61, 53, 45, 37, 29,
57         21, 13, 5, 28, 20, 12, 4
58 };
59
60 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
61         3, 28, 15, 6, 21, 10,
62         23, 19, 12, 4, 26, 8,
63         16, 7, 27, 20, 13, 2,
64         41, 52, 31, 37, 47, 55,
65         30, 40, 51, 45, 33, 48,
66         44, 49, 39, 56, 34, 53,
67         46, 42, 50, 36, 29, 32
68 };
69
70 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
71         60, 52, 44, 36, 28, 20, 12, 4,
72         62, 54, 46, 38, 30, 22, 14, 6,
73         64, 56, 48, 40, 32, 24, 16, 8,
74         57, 49, 41, 33, 25, 17, 9, 1,
75         59, 51, 43, 35, 27, 19, 11, 3,
76         61, 53, 45, 37, 29, 21, 13, 5,
77         63, 55, 47, 39, 31, 23, 15, 7
78 };
79
80 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
81         4, 5, 6, 7, 8, 9,
82         8, 9, 10, 11, 12, 13,
83         12, 13, 14, 15, 16, 17,
84         16, 17, 18, 19, 20, 21,
85         20, 21, 22, 23, 24, 25,
86         24, 25, 26, 27, 28, 29,
87         28, 29, 30, 31, 32, 1
88 };
89
90 static uchar perm5[32] = { 16, 7, 20, 21,
91         29, 12, 28, 17,
92         1, 15, 23, 26,
93         5, 18, 31, 10,
94         2, 8, 24, 14,
95         32, 27, 3, 9,
96         19, 13, 30, 6,
97         22, 11, 4, 25
98 };
99
100 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
101         39, 7, 47, 15, 55, 23, 63, 31,
102         38, 6, 46, 14, 54, 22, 62, 30,
103         37, 5, 45, 13, 53, 21, 61, 29,
104         36, 4, 44, 12, 52, 20, 60, 28,
105         35, 3, 43, 11, 51, 19, 59, 27,
106         34, 2, 42, 10, 50, 18, 58, 26,
107         33, 1, 41, 9, 49, 17, 57, 25
108 };
109
110 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
111
112 static uchar sbox[8][4][16] = {
113         {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
114          {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
115          {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
116          {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },
117
118         {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
119          {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
120          {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
121          {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },
122
123         {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
124          {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
125          {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
126          {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },
127
128         {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
129          {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
130          {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
131          {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },
132
133         {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
134          {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
135          {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
136          {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },
137
138         {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
139          {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
140          {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
141          {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },
142
143         {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
144          {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
145          {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
146          {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },
147
148         {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
149          {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
150          {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
151          {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }
152 };
153
154 static void
155 permute(char *out, char *in, uchar *p, int n)
156 {
157         int i;
158         for (i = 0; i < n; i++)
159                 out[i] = in[p[i] - 1];
160 }
161
162 static void
163 lshift(char *d, int count, int n)
164 {
165         char out[64];
166         int i;
167         for (i = 0; i < n; i++)
168                 out[i] = d[(i + count) % n];
169         for (i = 0; i < n; i++)
170                 d[i] = out[i];
171 }
172
173 static void
174 concat(char *out, char *in1, char *in2, int l1, int l2)
175 {
176         while (l1--)
177                 *out++ = *in1++;
178         while (l2--)
179                 *out++ = *in2++;
180 }
181
182 static void
183 xor(char *out, char *in1, char *in2, int n)
184 {
185         int i;
186         for (i = 0; i < n; i++)
187                 out[i] = in1[i] ^ in2[i];
188 }
189
190 static void
191 dohash(char *out, char *in, char *key, int forw)
192 {
193         int i, j, k;
194         char *pk1;
195         char c[28];
196         char d[28];
197         char *cd;
198         char (*ki)[48];
199         char *pd1;
200         char l[32], r[32];
201         char *rl;
202
203         /* Have to reduce stack usage */
204         pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
205         if (pk1 == NULL)
206                 return;
207
208         ki = kmalloc(16*48, GFP_KERNEL);
209         if (ki == NULL) {
210                 kfree(pk1);
211                 return;
212         }
213
214         cd = pk1 + 56;
215         pd1 = cd  + 56;
216         rl = pd1 + 64;
217
218         permute(pk1, key, perm1, 56);
219
220         for (i = 0; i < 28; i++)
221                 c[i] = pk1[i];
222         for (i = 0; i < 28; i++)
223                 d[i] = pk1[i + 28];
224
225         for (i = 0; i < 16; i++) {
226                 lshift(c, sc[i], 28);
227                 lshift(d, sc[i], 28);
228
229                 concat(cd, c, d, 28, 28);
230                 permute(ki[i], cd, perm2, 48);
231         }
232
233         permute(pd1, in, perm3, 64);
234
235         for (j = 0; j < 32; j++) {
236                 l[j] = pd1[j];
237                 r[j] = pd1[j + 32];
238         }
239
240         for (i = 0; i < 16; i++) {
241                 char *er;  /* er[48]  */
242                 char *erk; /* erk[48] */
243                 char b[8][6];
244                 char *cb;  /* cb[32]  */
245                 char *pcb; /* pcb[32] */
246                 char *r2;  /* r2[32]  */
247
248                 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
249                 if (er == NULL) {
250                         kfree(pk1);
251                         kfree(ki);
252                         return;
253                 }
254                 erk = er+48;
255                 cb  = erk+48;
256                 pcb = cb+32;
257                 r2  = pcb+32;
258
259                 permute(er, r, perm4, 48);
260
261                 xor(erk, er, ki[forw ? i : 15 - i], 48);
262
263                 for (j = 0; j < 8; j++)
264                         for (k = 0; k < 6; k++)
265                                 b[j][k] = erk[j * 6 + k];
266
267                 for (j = 0; j < 8; j++) {
268                         int m, n;
269                         m = (b[j][0] << 1) | b[j][5];
270
271                         n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
272                                                                1) | b[j][4];
273
274                         for (k = 0; k < 4; k++)
275                                 b[j][k] =
276                                     (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
277                 }
278
279                 for (j = 0; j < 8; j++)
280                         for (k = 0; k < 4; k++)
281                                 cb[j * 4 + k] = b[j][k];
282                 permute(pcb, cb, perm5, 32);
283
284                 xor(r2, l, pcb, 32);
285
286                 for (j = 0; j < 32; j++)
287                         l[j] = r[j];
288
289                 for (j = 0; j < 32; j++)
290                         r[j] = r2[j];
291
292                 kfree(er);
293         }
294
295         concat(rl, r, l, 32, 32);
296
297         permute(out, rl, perm6, 64);
298         kfree(pk1);
299         kfree(ki);
300 }
301
302 static void
303 str_to_key(unsigned char *str, unsigned char *key)
304 {
305         int i;
306
307         key[0] = str[0] >> 1;
308         key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
309         key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
310         key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
311         key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
312         key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
313         key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
314         key[7] = str[6] & 0x7F;
315         for (i = 0; i < 8; i++)
316                 key[i] = (key[i] << 1);
317 }
318
319 static void
320 smbhash(unsigned char *out, const unsigned char *in, unsigned char *key,
321         int forw)
322 {
323         int i;
324         char *outb; /* outb[64] */
325         char *inb;  /* inb[64]  */
326         char *keyb; /* keyb[64] */
327         unsigned char key2[8];
328
329         outb = kmalloc(64 * 3, GFP_KERNEL);
330         if (outb == NULL)
331                 return;
332
333         inb  = outb + 64;
334         keyb = inb +  64;
335
336         str_to_key(key, key2);
337
338         for (i = 0; i < 64; i++) {
339                 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
340                 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
341                 outb[i] = 0;
342         }
343
344         dohash(outb, inb, keyb, forw);
345
346         for (i = 0; i < 8; i++)
347                 out[i] = 0;
348
349         for (i = 0; i < 64; i++) {
350                 if (outb[i])
351                         out[i / 8] |= (1 << (7 - (i % 8)));
352         }
353         kfree(outb);
354 }
355
356 void
357 E_P16(unsigned char *p14, unsigned char *p16)
358 {
359         unsigned char sp8[8] =
360             { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
361         smbhash(p16, sp8, p14, 1);
362         smbhash(p16 + 8, sp8, p14 + 7, 1);
363 }
364
365 void
366 E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
367 {
368         smbhash(p24, c8, p21, 1);
369         smbhash(p24 + 8, c8, p21 + 7, 1);
370         smbhash(p24 + 16, c8, p21 + 14, 1);
371 }
372
373 #if 0 /* currently unused */
374 static void
375 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
376 {
377         smbhash(out, in, p14, 0);
378         smbhash(out + 8, in + 8, p14 + 7, 0);
379 }
380
381 static void
382 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
383 {
384         smbhash(out, in, p14, 1);
385         smbhash(out + 8, in + 8, p14 + 7, 1);
386 }
387 /* these routines are currently unneeded, but may be
388         needed later */
389 void
390 cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
391 {
392         unsigned char buf[8];
393
394         smbhash(buf, in, key, 1);
395         smbhash(out, buf, key + 9, 1);
396 }
397
398 void
399 cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
400 {
401         unsigned char buf[8];
402         static unsigned char key2[8];
403
404         smbhash(buf, in, key, 1);
405         key2[0] = key[7];
406         smbhash(out, buf, key2, 1);
407 }
408
409 void
410 cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
411 {
412         static unsigned char key2[8];
413
414         smbhash(out, in, key, forw);
415         key2[0] = key[7];
416         smbhash(out + 8, in + 8, key2, forw);
417 }
418 #endif /* unneeded routines */