This is the ubiqx binary tree and linked list library.
[Samba.git] / source / libsmb / smbdes.c
blob1c38612b73992fa3f313a47ee58e8835f07dfdb7
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 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.
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)
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,
60 3, 28, 15, 6, 21, 10,
61 23, 19, 12, 4, 26, 8,
62 16, 7, 27, 20, 13, 2,
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,
78 4, 5, 6, 7, 8, 9,
79 8, 9, 10, 11, 12, 13,
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,
87 29, 12, 28, 17,
88 1, 15, 23, 26,
89 5, 18, 31, 10,
90 2, 8, 24, 14,
91 32, 27, 3, 9,
92 19, 13, 30, 6,
93 22, 11, 4, 25};
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)
151 int i;
152 for (i=0;i<n;i++)
153 out[i] = in[p[i]-1];
156 static void lshift(char *d, int count, int n)
158 char out[64];
159 int i;
160 for (i=0;i<n;i++)
161 out[i] = d[(i+count)%n];
162 for (i=0;i<n;i++)
163 d[i] = out[i];
166 static void concat(char *out, char *in1, char *in2, int l1, int l2)
168 while (l1--)
169 *out++ = *in1++;
170 while (l2--)
171 *out++ = *in2++;
174 static void xor(char *out, char *in1, char *in2, int n)
176 int i;
177 for (i=0;i<n;i++)
178 out[i] = in1[i] ^ in2[i];
181 static void dohash(char *out, char *in, char *key)
183 int i, j, k;
184 char pk1[56];
185 char c[28];
186 char d[28];
187 char cd[56];
188 char ki[16][48];
189 char pd1[64];
190 char l[32], r[32];
191 char rl[64];
193 permute(pk1, key, perm1, 56);
195 for (i=0;i<28;i++)
196 c[i] = pk1[i];
197 for (i=0;i<28;i++)
198 d[i] = pk1[i+28];
200 for (i=0;i<16;i++) {
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);
210 for (j=0;j<32;j++) {
211 l[j] = pd1[j];
212 r[j] = pd1[j+32];
215 for (i=0;i<16;i++) {
216 char er[48];
217 char erk[48];
218 char b[8][6];
219 char cb[32];
220 char pcb[32];
221 char r2[32];
223 permute(er, r, perm4, 48);
225 xor(erk, er, ki[i], 48);
227 for (j=0;j<8;j++)
228 for (k=0;k<6;k++)
229 b[j][k] = erk[j*6 + k];
231 for (j=0;j<8;j++) {
232 int m, n;
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];
237 for (k=0;k<4;k++)
238 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
241 for (j=0;j<8;j++)
242 for (k=0;k<4;k++)
243 cb[j*4+k] = b[j][k];
244 permute(pcb, cb, perm5, 32);
246 xor(r2, l, pcb, 32);
248 for (j=0;j<32;j++)
249 l[j] = r[j];
251 for (j=0;j<32;j++)
252 r[j] = r2[j];
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)
262 int i;
264 key[0] = str[0]>>1;
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;
272 for (i=0;i<8;i++) {
273 key[i] = (key[i]<<1);
278 static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key)
280 int i;
281 char outb[64];
282 char inb[64];
283 char keyb[64];
284 unsigned char key2[8];
286 str_to_key(key, key2);
288 for (i=0;i<64;i++) {
289 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
290 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
291 outb[i] = 0;
294 dohash(outb, inb, keyb);
296 for (i=0;i<8;i++) {
297 out[i] = 0;
300 for (i=0;i<64;i++) {
301 if (outb[i])
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);