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 1997
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 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)
50 static int 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};
59 static int perm2[48] = {14, 17, 11, 24, 1, 5,
63 41, 52, 31, 37, 47, 55,
64 30, 40, 51, 45, 33, 48,
65 44, 49, 39, 56, 34, 53,
66 46, 42, 50, 36, 29, 32};
68 static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
69 60, 52, 44, 36, 28, 20, 12, 4,
70 62, 54, 46, 38, 30, 22, 14, 6,
71 64, 56, 48, 40, 32, 24, 16, 8,
72 57, 49, 41, 33, 25, 17, 9, 1,
73 59, 51, 43, 35, 27, 19, 11, 3,
74 61, 53, 45, 37, 29, 21, 13, 5,
75 63, 55, 47, 39, 31, 23, 15, 7};
77 static int perm4[48] = { 32, 1, 2, 3, 4, 5,
80 12, 13, 14, 15, 16, 17,
81 16, 17, 18, 19, 20, 21,
82 20, 21, 22, 23, 24, 25,
83 24, 25, 26, 27, 28, 29,
84 28, 29, 30, 31, 32, 1};
86 static int perm5[32] = { 16, 7, 20, 21,
96 static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
97 39, 7, 47, 15, 55, 23, 63, 31,
98 38, 6, 46, 14, 54, 22, 62, 30,
99 37, 5, 45, 13, 53, 21, 61, 29,
100 36, 4, 44, 12, 52, 20, 60, 28,
101 35, 3, 43, 11, 51, 19, 59, 27,
102 34, 2, 42, 10, 50, 18, 58, 26,
103 33, 1, 41, 9, 49, 17, 57, 25};
106 static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
108 static int sbox[8][4][16] = {
109 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
110 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
111 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
112 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
114 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
115 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
116 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
117 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
119 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
120 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
121 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
122 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
124 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
125 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
126 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
127 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
129 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
130 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
131 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
132 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
134 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
135 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
136 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
137 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
139 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
140 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
141 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
142 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
144 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
145 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
146 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
147 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
149 static void permute(char *out, char *in, int *p, int n)
156 static void lshift(char *d, int count, int n)
161 out[i] = d[(i+count)%n];
166 static void concat(char *out, char *in1, char *in2, int l1, int l2)
174 static void xor(char *out, char *in1, char *in2, int n)
178 out[i] = in1[i] ^ in2[i];
181 static void dohash(char *out, char *in, char *key)
193 permute(pk1, key, perm1, 56);
201 lshift(c, sc[i], 28);
202 lshift(d, sc[i], 28);
204 concat(cd, c, d, 28, 28);
205 permute(ki[i], cd, perm2, 48);
208 permute(pd1, in, perm3, 64);
223 permute(er, r, perm4, 48);
225 xor(erk, er, ki[i], 48);
229 b[j][k] = erk[j*6 + k];
233 m = (b[j][0]<<1) | b[j][5];
235 n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
238 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
244 permute(pcb, cb, perm5, 32);
255 concat(rl, r, l, 32, 32);
257 permute(out, rl, perm6, 64);
260 static void str_to_key(unsigned char *str,unsigned char *key)
265 key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
266 key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
267 key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
268 key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
269 key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
270 key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
271 key[7] = str[6]&0x7F;
273 key[i] = (key[i]<<1);
278 static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key)
284 unsigned char key2[8];
286 str_to_key(key, key2);
289 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
290 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
294 dohash(outb, inb, keyb);
302 out[i/8] |= (1<<(7-(i%8)));
306 void E_P16(unsigned char *p14,unsigned char *p16)
308 unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
309 smbhash(p16, sp8, p14);
310 smbhash(p16+8, sp8, p14+7);
313 void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
315 smbhash(p24, c8, p21);
316 smbhash(p24+8, c8, p21+7);
317 smbhash(p24+16, c8, p21+14);
320 void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
322 unsigned char buf[8];
324 smbhash(buf, in, key);
325 smbhash(out, buf, key+9);
328 void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
330 unsigned char buf[8];
331 static unsigned char key2[8];
333 smbhash(buf, in, key);
335 smbhash(out, buf, key2);