Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / fs / cifs / smbdes.c
blob53a72a82cd0d4218fd2d3e142a5bc95c99f85550
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
5 a partial implementation of DES designed for use in the
6 SMB authentication protocol
8 Copyright (C) Andrew Tridgell 1998
9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004
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.
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.
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.
26 /* NOTES:
28 This code makes no attempt to be fast! In fact, it is a very
29 slow implementation
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)
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.
39 There is no entry point into this code that allows normal DES operation.
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)
47 #include <linux/slab.h>
48 #include "cifsencrypt.h"
49 #define uchar unsigned char
51 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
52 1, 58, 50, 42, 34, 26, 18,
53 10, 2, 59, 51, 43, 35, 27,
54 19, 11, 3, 60, 52, 44, 36,
55 63, 55, 47, 39, 31, 23, 15,
56 7, 62, 54, 46, 38, 30, 22,
57 14, 6, 61, 53, 45, 37, 29,
58 21, 13, 5, 28, 20, 12, 4
61 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
62 3, 28, 15, 6, 21, 10,
63 23, 19, 12, 4, 26, 8,
64 16, 7, 27, 20, 13, 2,
65 41, 52, 31, 37, 47, 55,
66 30, 40, 51, 45, 33, 48,
67 44, 49, 39, 56, 34, 53,
68 46, 42, 50, 36, 29, 32
71 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
72 60, 52, 44, 36, 28, 20, 12, 4,
73 62, 54, 46, 38, 30, 22, 14, 6,
74 64, 56, 48, 40, 32, 24, 16, 8,
75 57, 49, 41, 33, 25, 17, 9, 1,
76 59, 51, 43, 35, 27, 19, 11, 3,
77 61, 53, 45, 37, 29, 21, 13, 5,
78 63, 55, 47, 39, 31, 23, 15, 7
81 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
82 4, 5, 6, 7, 8, 9,
83 8, 9, 10, 11, 12, 13,
84 12, 13, 14, 15, 16, 17,
85 16, 17, 18, 19, 20, 21,
86 20, 21, 22, 23, 24, 25,
87 24, 25, 26, 27, 28, 29,
88 28, 29, 30, 31, 32, 1
91 static uchar perm5[32] = { 16, 7, 20, 21,
92 29, 12, 28, 17,
93 1, 15, 23, 26,
94 5, 18, 31, 10,
95 2, 8, 24, 14,
96 32, 27, 3, 9,
97 19, 13, 30, 6,
98 22, 11, 4, 25
101 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
102 39, 7, 47, 15, 55, 23, 63, 31,
103 38, 6, 46, 14, 54, 22, 62, 30,
104 37, 5, 45, 13, 53, 21, 61, 29,
105 36, 4, 44, 12, 52, 20, 60, 28,
106 35, 3, 43, 11, 51, 19, 59, 27,
107 34, 2, 42, 10, 50, 18, 58, 26,
108 33, 1, 41, 9, 49, 17, 57, 25
111 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
113 static uchar sbox[8][4][16] = {
114 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
115 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
116 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
117 <<<<<<< HEAD:fs/cifs/smbdes.c
118 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
119 =======
120 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },
121 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
123 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
124 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
125 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
126 <<<<<<< HEAD:fs/cifs/smbdes.c
127 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
128 =======
129 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },
130 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
132 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
133 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
134 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
135 <<<<<<< HEAD:fs/cifs/smbdes.c
136 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
137 =======
138 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },
139 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
141 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
142 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
143 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
144 <<<<<<< HEAD:fs/cifs/smbdes.c
145 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
146 =======
147 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },
148 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
150 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
151 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
152 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
153 <<<<<<< HEAD:fs/cifs/smbdes.c
154 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
155 =======
156 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },
157 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
159 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
160 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
161 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
162 <<<<<<< HEAD:fs/cifs/smbdes.c
163 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
164 =======
165 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },
166 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
168 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
169 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
170 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
171 <<<<<<< HEAD:fs/cifs/smbdes.c
172 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
173 =======
174 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },
175 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
177 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
178 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
179 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
180 <<<<<<< HEAD:fs/cifs/smbdes.c
181 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
182 =======
183 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }
184 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
187 static void
188 permute(char *out, char *in, uchar *p, int n)
190 int i;
191 for (i = 0; i < n; i++)
192 out[i] = in[p[i] - 1];
195 static void
196 lshift(char *d, int count, int n)
198 char out[64];
199 int i;
200 for (i = 0; i < n; i++)
201 out[i] = d[(i + count) % n];
202 for (i = 0; i < n; i++)
203 d[i] = out[i];
206 static void
207 concat(char *out, char *in1, char *in2, int l1, int l2)
209 while (l1--)
210 *out++ = *in1++;
211 while (l2--)
212 *out++ = *in2++;
215 static void
216 xor(char *out, char *in1, char *in2, int n)
218 int i;
219 for (i = 0; i < n; i++)
220 out[i] = in1[i] ^ in2[i];
223 static void
224 dohash(char *out, char *in, char *key, int forw)
226 int i, j, k;
227 char *pk1;
228 char c[28];
229 char d[28];
230 char *cd;
231 char (*ki)[48];
232 char *pd1;
233 char l[32], r[32];
234 char *rl;
236 /* Have to reduce stack usage */
237 pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
238 if (pk1 == NULL)
239 return;
241 ki = kmalloc(16*48, GFP_KERNEL);
242 if (ki == NULL) {
243 kfree(pk1);
244 return;
247 cd = pk1 + 56;
248 pd1 = cd + 56;
249 rl = pd1 + 64;
251 permute(pk1, key, perm1, 56);
253 for (i = 0; i < 28; i++)
254 c[i] = pk1[i];
255 for (i = 0; i < 28; i++)
256 d[i] = pk1[i + 28];
258 for (i = 0; i < 16; i++) {
259 lshift(c, sc[i], 28);
260 lshift(d, sc[i], 28);
262 concat(cd, c, d, 28, 28);
263 permute(ki[i], cd, perm2, 48);
266 permute(pd1, in, perm3, 64);
268 for (j = 0; j < 32; j++) {
269 l[j] = pd1[j];
270 r[j] = pd1[j + 32];
273 for (i = 0; i < 16; i++) {
274 char *er; /* er[48] */
275 char *erk; /* erk[48] */
276 char b[8][6];
277 char *cb; /* cb[32] */
278 char *pcb; /* pcb[32] */
279 char *r2; /* r2[32] */
281 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
282 if (er == NULL) {
283 kfree(pk1);
284 kfree(ki);
285 return;
287 erk = er+48;
288 cb = erk+48;
289 pcb = cb+32;
290 r2 = pcb+32;
292 permute(er, r, perm4, 48);
294 xor(erk, er, ki[forw ? i : 15 - i], 48);
296 for (j = 0; j < 8; j++)
297 for (k = 0; k < 6; k++)
298 b[j][k] = erk[j * 6 + k];
300 for (j = 0; j < 8; j++) {
301 int m, n;
302 m = (b[j][0] << 1) | b[j][5];
304 n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
305 1) | b[j][4];
307 for (k = 0; k < 4; k++)
308 b[j][k] =
309 (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
312 for (j = 0; j < 8; j++)
313 for (k = 0; k < 4; k++)
314 cb[j * 4 + k] = b[j][k];
315 permute(pcb, cb, perm5, 32);
317 xor(r2, l, pcb, 32);
319 for (j = 0; j < 32; j++)
320 l[j] = r[j];
322 for (j = 0; j < 32; j++)
323 r[j] = r2[j];
325 kfree(er);
328 concat(rl, r, l, 32, 32);
330 permute(out, rl, perm6, 64);
331 kfree(pk1);
332 kfree(ki);
335 static void
336 str_to_key(unsigned char *str, unsigned char *key)
338 int i;
340 key[0] = str[0] >> 1;
341 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
342 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
343 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
344 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
345 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
346 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
347 key[7] = str[6] & 0x7F;
348 <<<<<<< HEAD:fs/cifs/smbdes.c
349 for (i = 0; i < 8; i++) {
350 =======
351 for (i = 0; i < 8; i++)
352 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
353 key[i] = (key[i] << 1);
354 <<<<<<< HEAD:fs/cifs/smbdes.c
356 =======
357 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
360 static void
361 smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
363 int i;
364 char *outb; /* outb[64] */
365 char *inb; /* inb[64] */
366 char *keyb; /* keyb[64] */
367 unsigned char key2[8];
369 outb = kmalloc(64 * 3, GFP_KERNEL);
370 if (outb == NULL)
371 return;
373 inb = outb + 64;
374 keyb = inb + 64;
376 str_to_key(key, key2);
378 for (i = 0; i < 64; i++) {
379 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
380 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
381 outb[i] = 0;
384 dohash(outb, inb, keyb, forw);
386 <<<<<<< HEAD:fs/cifs/smbdes.c
387 for (i = 0; i < 8; i++) {
388 =======
389 for (i = 0; i < 8; i++)
390 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
391 out[i] = 0;
392 <<<<<<< HEAD:fs/cifs/smbdes.c
394 =======
395 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:fs/cifs/smbdes.c
397 for (i = 0; i < 64; i++) {
398 if (outb[i])
399 out[i / 8] |= (1 << (7 - (i % 8)));
401 kfree(outb);
404 void
405 E_P16(unsigned char *p14, unsigned char *p16)
407 unsigned char sp8[8] =
408 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
409 smbhash(p16, sp8, p14, 1);
410 smbhash(p16 + 8, sp8, p14 + 7, 1);
413 void
414 E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
416 smbhash(p24, c8, p21, 1);
417 smbhash(p24 + 8, c8, p21 + 7, 1);
418 smbhash(p24 + 16, c8, p21 + 14, 1);
421 #if 0 /* currently unsued */
422 static void
423 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
425 smbhash(out, in, p14, 0);
426 smbhash(out + 8, in + 8, p14 + 7, 0);
429 static void
430 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
432 smbhash(out, in, p14, 1);
433 smbhash(out + 8, in + 8, p14 + 7, 1);
435 /* these routines are currently unneeded, but may be
436 needed later */
437 void
438 cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
440 unsigned char buf[8];
442 smbhash(buf, in, key, 1);
443 smbhash(out, buf, key + 9, 1);
446 void
447 cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
449 unsigned char buf[8];
450 static unsigned char key2[8];
452 smbhash(buf, in, key, 1);
453 key2[0] = key[7];
454 smbhash(out, buf, key2, 1);
457 void
458 cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
460 static unsigned char key2[8];
462 smbhash(out, in, key, forw);
463 key2[0] = key[7];
464 smbhash(out + 8, in + 8, key2, forw);
466 #endif /* unneeded routines */