135df7fbb4428465110064c71b23b42332310241
[samba.git] / source3 / libsmb / smbdes.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    a implementation of DES designed for use in the SMB authentication protocol
5    Copyright (C) Andrew Tridgell 1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 /* NOTE: This code makes no attempt to be fast! In fact, it is a very
24    slow DES implementation */
25
26 static int perm1[56] = {57, 49, 41, 33, 25, 17,  9,
27                          1, 58, 50, 42, 34, 26, 18,
28                         10,  2, 59, 51, 43, 35, 27,
29                         19, 11,  3, 60, 52, 44, 36,
30                         63, 55, 47, 39, 31, 23, 15,
31                          7, 62, 54, 46, 38, 30, 22,
32                         14,  6, 61, 53, 45, 37, 29,
33                         21, 13,  5, 28, 20, 12,  4};
34
35 static int perm2[48] = {14, 17, 11, 24,  1,  5,
36                          3, 28, 15,  6, 21, 10,
37                         23, 19, 12,  4, 26,  8,
38                         16,  7, 27, 20, 13,  2,
39                         41, 52, 31, 37, 47, 55,
40                         30, 40, 51, 45, 33, 48,
41                         44, 49, 39, 56, 34, 53,
42                         46, 42, 50, 36, 29, 32};
43
44 static int perm3[64] = {58, 50, 42, 34, 26, 18, 10,  2,
45                         60, 52, 44, 36, 28, 20, 12,  4,
46                         62, 54, 46, 38, 30, 22, 14,  6,
47                         64, 56, 48, 40, 32, 24, 16,  8,
48                         57, 49, 41, 33, 25, 17,  9,  1,
49                         59, 51, 43, 35, 27, 19, 11,  3,
50                         61, 53, 45, 37, 29, 21, 13,  5,
51                         63, 55, 47, 39, 31, 23, 15,  7};
52
53 static int perm4[48] = {   32,  1,  2,  3,  4,  5,
54                             4,  5,  6,  7,  8,  9,
55                             8,  9, 10, 11, 12, 13,
56                            12, 13, 14, 15, 16, 17,
57                            16, 17, 18, 19, 20, 21,
58                            20, 21, 22, 23, 24, 25,
59                            24, 25, 26, 27, 28, 29,
60                            28, 29, 30, 31, 32,  1};
61
62 static int perm5[32] = {      16,  7, 20, 21,
63                               29, 12, 28, 17,
64                                1, 15, 23, 26,
65                                5, 18, 31, 10,
66                                2,  8, 24, 14,
67                               32, 27,  3,  9,
68                               19, 13, 30,  6,
69                               22, 11,  4, 25};
70
71
72 static int perm6[64] ={ 40,  8, 48, 16, 56, 24, 64, 32,
73                         39,  7, 47, 15, 55, 23, 63, 31,
74                         38,  6, 46, 14, 54, 22, 62, 30,
75                         37,  5, 45, 13, 53, 21, 61, 29,
76                         36,  4, 44, 12, 52, 20, 60, 28,
77                         35,  3, 43, 11, 51, 19, 59, 27,
78                         34,  2, 42, 10, 50, 18, 58, 26,
79                         33,  1, 41,  9, 49, 17, 57, 25};
80
81
82 static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
83
84 static int sbox[8][4][16] = {
85         {{14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
86          {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
87          {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
88          {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
89
90         {{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
91          {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
92          {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
93          {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
94
95         {{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
96          {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
97          {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
98          {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
99
100         {{7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
101          {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
102          {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
103          {3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14}},
104
105         {{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
106          {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
107          {4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
108          {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
109
110         {{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
111          {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
112          {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
113          {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
114
115         {{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
116          {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
117          {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
118          {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
119
120         {{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
121          {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
122          {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
123          {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
124
125 static void permute(char *out, char *in, int *p, int n)
126 {
127         int i;
128         for (i=0;i<n;i++)
129                 out[i] = in[p[i]-1];
130 }
131
132 static void lshift(char *d, int count, int n)
133 {
134         char out[64];
135         int i;
136         for (i=0;i<n;i++)
137                 out[i] = d[(i+count)%n];
138         for (i=0;i<n;i++)
139                 d[i] = out[i];
140 }
141
142 static void concat(char *out, char *in1, char *in2, int l1, int l2)
143 {
144         while (l1--)
145                 *out++ = *in1++;
146         while (l2--)
147                 *out++ = *in2++;
148 }
149
150 static void xor(char *out, char *in1, char *in2, int n)
151 {
152         int i;
153         for (i=0;i<n;i++)
154                 out[i] = in1[i] ^ in2[i];
155 }
156
157 static void dodes(char *out, char *in, char *key)
158 {
159         int i, j, k;
160         char pk1[56];
161         char c[28];
162         char d[28];
163         char cd[56];
164         char ki[16][48];
165         char pd1[64];
166         char l[32], r[32];
167         char rl[64];
168
169         permute(pk1, key, perm1, 56);
170
171         for (i=0;i<28;i++)
172                 c[i] = pk1[i];
173         for (i=0;i<28;i++)
174                 d[i] = pk1[i+28];
175
176         for (i=0;i<16;i++) {
177                 lshift(c, sc[i], 28);
178                 lshift(d, sc[i], 28);
179
180                 concat(cd, c, d, 28, 28); 
181                 permute(ki[i], cd, perm2, 48); 
182         }
183
184         permute(pd1, in, perm3, 64);
185
186         for (j=0;j<32;j++) {
187                 l[j] = pd1[j];
188                 r[j] = pd1[j+32];
189         }
190
191         for (i=0;i<16;i++) {
192                 char er[48];
193                 char erk[48];
194                 char b[8][6];
195                 char cb[32];
196                 char pcb[32];
197                 char r2[32];
198
199                 permute(er, r, perm4, 48);
200
201                 xor(erk, er, ki[i], 48);
202
203                 for (j=0;j<8;j++)
204                         for (k=0;k<6;k++)
205                                 b[j][k] = erk[j*6 + k];
206
207                 for (j=0;j<8;j++) {
208                         int m, n;
209                         m = (b[j][0]<<1) | b[j][5];
210
211                         n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; 
212
213                         for (k=0;k<4;k++) 
214                                 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; 
215                 }
216
217                 for (j=0;j<8;j++)
218                         for (k=0;k<4;k++)
219                                 cb[j*4+k] = b[j][k];
220                 permute(pcb, cb, perm5, 32);
221
222                 xor(r2, l, pcb, 32);
223
224                 for (j=0;j<32;j++)
225                         l[j] = r[j];
226
227                 for (j=0;j<32;j++)
228                         r[j] = r2[j];
229         }
230
231         concat(rl, r, l, 32, 32);
232
233         permute(out, rl, perm6, 64);
234 }
235
236 static void str_to_key(unsigned char *str,unsigned char *key)
237 {
238         int i;
239
240         key[0] = str[0]>>1;
241         key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
242         key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
243         key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
244         key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
245         key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
246         key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
247         key[7] = str[6]&0x7F;
248         for (i=0;i<8;i++) {
249                 key[i] = (key[i]<<1);
250         }
251 }
252
253
254 /* this is the entry point to the DES routine. The key is 56 bits (no parity) */
255 void smbdes(unsigned char *out, unsigned char *in, unsigned char *key)
256 {
257         int i;
258         char outb[64];
259         char inb[64];
260         char keyb[64];
261         unsigned char key2[8];
262
263         str_to_key(key, key2);
264
265         for (i=0;i<64;i++) {
266                 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
267                 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
268                 outb[i] = 0;
269         }
270
271         dodes(outb, inb, keyb);
272
273         for (i=0;i<8;i++) {
274                 out[i] = 0;
275         }
276
277         for (i=0;i<64;i++) {
278                 if (outb[i])
279                         out[i/8] |= (1<<(7-(i%8)));
280         }
281 }
282