2 Unix SMB/Netbios implementation.
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.
28 This code makes no attempt to be fast! In fact, it is a very
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 #define uchar unsigned char
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
60 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
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
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
80 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
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,
90 static uchar perm5[32] = { 16, 7, 20, 21,
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
110 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
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}},
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}},
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}},
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}},
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}},
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}},
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}},
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}}
155 permute(char *out, char *in, uchar * p, int n)
158 for (i = 0; i < n; i++)
159 out[i] = in[p[i] - 1];
163 lshift(char *d, int count, int n)
167 for (i = 0; i < n; i++)
168 out[i] = d[(i + count) % n];
169 for (i = 0; i < n; i++)
174 concat(char *out, char *in1, char *in2, int l1, int l2)
183 xor(char *out, char *in1, char *in2, int n)
186 for (i = 0; i < n; i++)
187 out[i] = in1[i] ^ in2[i];
191 dohash(char *out, char *in, char *key, int forw)
203 /* Have to reduce stack usage */
204 pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
212 permute(pk1, key, perm1, 56);
214 for (i = 0; i < 28; i++)
216 for (i = 0; i < 28; i++)
219 for (i = 0; i < 16; i++) {
220 lshift(c, sc[i], 28);
221 lshift(d, sc[i], 28);
223 concat(cd, c, d, 28, 28);
224 permute(ki[i], cd, perm2, 48);
227 permute(pd1, in, perm3, 64);
229 for (j = 0; j < 32; j++) {
234 for (i = 0; i < 16; i++) {
235 char *er; /* er[48] */
236 char *erk; /* erk[48] */
238 char *cb; /* cb[32] */
239 char *pcb; /* pcb[32] */
240 char *r2; /* r2[32] */
242 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
252 permute(er, r, perm4, 48);
254 xor(erk, er, ki[forw ? i : 15 - i], 48);
256 for (j = 0; j < 8; j++)
257 for (k = 0; k < 6; k++)
258 b[j][k] = erk[j * 6 + k];
260 for (j = 0; j < 8; j++) {
262 m = (b[j][0] << 1) | b[j][5];
264 n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
267 for (k = 0; k < 4; k++)
269 (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
272 for (j = 0; j < 8; j++)
273 for (k = 0; k < 4; k++)
274 cb[j * 4 + k] = b[j][k];
275 permute(pcb, cb, perm5, 32);
279 for (j = 0; j < 32; j++)
282 for (j = 0; j < 32; j++)
288 concat(rl, r, l, 32, 32);
290 permute(out, rl, perm6, 64);
295 str_to_key(unsigned char *str, unsigned char *key)
299 key[0] = str[0] >> 1;
300 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
301 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
302 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
303 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
304 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
305 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
306 key[7] = str[6] & 0x7F;
307 for (i = 0; i < 8; i++) {
308 key[i] = (key[i] << 1);
313 smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
316 char *outb; /* outb[64] */
317 char *inb; /* inb[64] */
318 char *keyb; /* keyb[64] */
319 unsigned char key2[8];
321 outb = kmalloc(64 * 3,GFP_KERNEL);
328 str_to_key(key, key2);
330 for (i = 0; i < 64; i++) {
331 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
332 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
336 dohash(outb, inb, keyb, forw);
338 for (i = 0; i < 8; i++) {
342 for (i = 0; i < 64; i++) {
344 out[i / 8] |= (1 << (7 - (i % 8)));
350 E_P16(unsigned char *p14, unsigned char *p16)
352 unsigned char sp8[8] =
353 { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
354 smbhash(p16, sp8, p14, 1);
355 smbhash(p16 + 8, sp8, p14 + 7, 1);
359 E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
361 smbhash(p24, c8, p21, 1);
362 smbhash(p24 + 8, c8, p21 + 7, 1);
363 smbhash(p24 + 16, c8, p21 + 14, 1);
367 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
369 smbhash(out, in, p14, 0);
370 smbhash(out + 8, in + 8, p14 + 7, 0);
374 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
376 smbhash(out, in, p14, 1);
377 smbhash(out + 8, in + 8, p14 + 7, 1);
381 cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
383 unsigned char buf[8];
385 smbhash(buf, in, key, 1);
386 smbhash(out, buf, key + 9, 1);
390 cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
392 unsigned char buf[8];
393 static unsigned char key2[8];
395 smbhash(buf, in, key, 1);
397 smbhash(out, buf, key2, 1);
401 cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
403 static unsigned char key2[8];
405 smbhash(out, in, key, forw);
407 smbhash(out + 8, in + 8, key2, forw);