Code indentation.
[midnight-commander.git] / src / vfs / smbfs / helpers / libsmb / smbdes.c
blobbac091a9024fcd1354bb7ed62e255d50d500f2cb
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
10 Copyright (C) 2011
11 The Free Software Foundation, Inc.
13 This file is part of the Midnight Commander.
15 The Midnight Commander is free software: you can redistribute it
16 and/or modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation, either version 3 of the License,
18 or (at your option) any later version.
20 The Midnight Commander is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include "includes.h"
31 /* NOTES:
33 This code makes no attempt to be fast! In fact, it is a very
34 slow implementation
36 This code is NOT a complete DES implementation. It implements only
37 the minimum necessary for SMB authentication, as used by all SMB
38 products (including every copy of Microsoft Windows95 ever sold)
40 In particular, it can only do a unchained forward DES pass. This
41 means it is not possible to use this code for encryption/decryption
42 of data, instead it is only useful as a "hash" algorithm.
44 There is no entry point into this code that allows normal DES operation.
46 I believe this means that this code does not come under ITAR
47 regulations but this is NOT a legal opinion. If you are concerned
48 about the applicability of ITAR regulations to this code then you
49 should confirm it for yourself (and maybe let me know if you come
50 up with a different answer to the one above)
53 #undef uchar
54 #define uchar const unsigned char
56 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
57 1, 58, 50, 42, 34, 26, 18,
58 10, 2, 59, 51, 43, 35, 27,
59 19, 11, 3, 60, 52, 44, 36,
60 63, 55, 47, 39, 31, 23, 15,
61 7, 62, 54, 46, 38, 30, 22,
62 14, 6, 61, 53, 45, 37, 29,
63 21, 13, 5, 28, 20, 12, 4
66 static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
67 3, 28, 15, 6, 21, 10,
68 23, 19, 12, 4, 26, 8,
69 16, 7, 27, 20, 13, 2,
70 41, 52, 31, 37, 47, 55,
71 30, 40, 51, 45, 33, 48,
72 44, 49, 39, 56, 34, 53,
73 46, 42, 50, 36, 29, 32
76 static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
77 60, 52, 44, 36, 28, 20, 12, 4,
78 62, 54, 46, 38, 30, 22, 14, 6,
79 64, 56, 48, 40, 32, 24, 16, 8,
80 57, 49, 41, 33, 25, 17, 9, 1,
81 59, 51, 43, 35, 27, 19, 11, 3,
82 61, 53, 45, 37, 29, 21, 13, 5,
83 63, 55, 47, 39, 31, 23, 15, 7
86 static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
87 4, 5, 6, 7, 8, 9,
88 8, 9, 10, 11, 12, 13,
89 12, 13, 14, 15, 16, 17,
90 16, 17, 18, 19, 20, 21,
91 20, 21, 22, 23, 24, 25,
92 24, 25, 26, 27, 28, 29,
93 28, 29, 30, 31, 32, 1
96 static uchar perm5[32] = { 16, 7, 20, 21,
97 29, 12, 28, 17,
98 1, 15, 23, 26,
99 5, 18, 31, 10,
100 2, 8, 24, 14,
101 32, 27, 3, 9,
102 19, 13, 30, 6,
103 22, 11, 4, 25
107 static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
108 39, 7, 47, 15, 55, 23, 63, 31,
109 38, 6, 46, 14, 54, 22, 62, 30,
110 37, 5, 45, 13, 53, 21, 61, 29,
111 36, 4, 44, 12, 52, 20, 60, 28,
112 35, 3, 43, 11, 51, 19, 59, 27,
113 34, 2, 42, 10, 50, 18, 58, 26,
114 33, 1, 41, 9, 49, 17, 57, 25
118 static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
120 static uchar sbox[8][4][16] = {
121 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
122 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
123 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
124 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
126 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
127 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
128 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
129 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
131 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
132 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
133 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
134 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
136 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
137 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
138 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
139 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
141 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
142 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
143 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
144 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
146 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
147 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
148 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
149 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
151 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
152 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
153 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
154 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
156 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
157 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
158 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
159 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
162 static void
163 permute (char *out, char *in, uchar * p, int n)
165 int i;
166 for (i = 0; i < n; i++)
167 out[i] = in[p[i] - 1];
170 static void
171 lshift (char *d, int count, int n)
173 char out[64];
174 int i;
175 for (i = 0; i < n; i++)
176 out[i] = d[(i + count) % n];
177 for (i = 0; i < n; i++)
178 d[i] = out[i];
181 static void
182 concat (char *out, char *in1, char *in2, int l1, int l2)
184 while (l1--)
185 *out++ = *in1++;
186 while (l2--)
187 *out++ = *in2++;
190 static void
191 xor (char *out, char *in1, char *in2, int n)
193 int i;
194 for (i = 0; i < n; i++)
195 out[i] = in1[i] ^ in2[i];
198 static void
199 dohash (char *out, char *in, char *key, int forw)
201 int i, j, k;
202 char pk1[56];
203 char c[28];
204 char d[28];
205 char cd[56];
206 char ki[16][48];
207 char pd1[64];
208 char l[32], r[32];
209 char rl[64];
211 permute (pk1, key, perm1, 56);
213 for (i = 0; i < 28; i++)
214 c[i] = pk1[i];
215 for (i = 0; i < 28; i++)
216 d[i] = pk1[i + 28];
218 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++)
231 l[j] = pd1[j];
232 r[j] = pd1[j + 32];
235 for (i = 0; i < 16; i++)
237 char er[48];
238 char erk[48];
239 char b[8][6];
240 char cb[32];
241 char pcb[32];
242 char r2[32];
244 permute (er, r, perm4, 48);
246 xor (erk, er, ki[forw ? i : 15 - i], 48);
248 for (j = 0; j < 8; j++)
249 for (k = 0; k < 6; k++)
250 b[j][k] = erk[j * 6 + k];
252 for (j = 0; j < 8; j++)
254 int m, n;
255 m = (b[j][0] << 1) | b[j][5];
257 n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4];
259 for (k = 0; k < 4; k++)
260 b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
263 for (j = 0; j < 8; j++)
264 for (k = 0; k < 4; k++)
265 cb[j * 4 + k] = b[j][k];
266 permute (pcb, cb, perm5, 32);
268 xor (r2, l, pcb, 32);
270 for (j = 0; j < 32; j++)
271 l[j] = r[j];
273 for (j = 0; j < 32; j++)
274 r[j] = r2[j];
277 concat (rl, r, l, 32, 32);
279 permute (out, rl, perm6, 64);
282 static void
283 str_to_key (unsigned char *str, unsigned char *key)
285 int i;
287 key[0] = str[0] >> 1;
288 key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
289 key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
290 key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
291 key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
292 key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
293 key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
294 key[7] = str[6] & 0x7F;
295 for (i = 0; i < 8; i++)
297 key[i] = (key[i] << 1);
302 static void
303 smbhash (unsigned char *out, unsigned char *in, unsigned char *key, int forw)
305 int i;
306 char outb[64];
307 char inb[64];
308 char keyb[64];
309 unsigned char key2[8];
311 str_to_key (key, key2);
313 for (i = 0; i < 64; i++)
315 inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
316 keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
317 outb[i] = 0;
320 dohash (outb, inb, keyb, forw);
322 for (i = 0; i < 8; i++)
324 out[i] = 0;
327 for (i = 0; i < 64; i++)
329 if (outb[i])
330 out[i / 8] |= (1 << (7 - (i % 8)));
334 void
335 E_P16 (unsigned char *p14, unsigned char *p16)
337 unsigned char sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
338 smbhash (p16, sp8, p14, 1);
339 smbhash (p16 + 8, sp8, p14 + 7, 1);
342 void
343 E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24)
345 smbhash (p24, c8, p21, 1);
346 smbhash (p24 + 8, c8, p21 + 7, 1);
347 smbhash (p24 + 16, c8, p21 + 14, 1);
350 void
351 D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out)
353 smbhash (out, in, p14, 0);
354 smbhash (out + 8, in + 8, p14 + 7, 0);
357 void
358 E_old_pw_hash (unsigned char *p14, unsigned char *in, unsigned char *out)
360 smbhash (out, in, p14, 1);
361 smbhash (out + 8, in + 8, p14 + 7, 1);
364 void
365 cred_hash1 (unsigned char *out, unsigned char *in, unsigned char *key)
367 unsigned char buf[8];
369 smbhash (buf, in, key, 1);
370 smbhash (out, buf, key + 9, 1);
373 void
374 cred_hash2 (unsigned char *out, unsigned char *in, unsigned char *key)
376 unsigned char buf[8];
377 static unsigned char key2[8];
379 smbhash (buf, in, key, 1);
380 key2[0] = key[7];
381 smbhash (out, buf, key2, 1);
384 void
385 cred_hash3 (unsigned char *out, unsigned char *in, unsigned char *key, int forw)
387 static unsigned char key2[8];
389 smbhash (out, in, key, forw);
390 key2[0] = key[7];
391 smbhash (out + 8, in + 8, key2, forw);
394 void
395 SamOEMhash (unsigned char *data, unsigned char *key, int val)
397 unsigned char s_box[256];
398 unsigned char index_i = 0;
399 unsigned char index_j = 0;
400 unsigned char j = 0;
401 int ind;
403 for (ind = 0; ind < 256; ind++)
405 s_box[ind] = (unsigned char) ind;
408 for (ind = 0; ind < 256; ind++)
410 unsigned char tc;
412 j += (s_box[ind] + key[ind % 16]);
414 tc = s_box[ind];
415 s_box[ind] = s_box[j];
416 s_box[j] = tc;
418 for (ind = 0; ind < (val ? 516 : 16); ind++)
420 unsigned char tc;
421 unsigned char t;
423 index_i++;
424 index_j += s_box[index_i];
426 tc = s_box[index_i];
427 s_box[index_i] = s_box[index_j];
428 s_box[index_j] = tc;
430 t = s_box[index_i] + s_box[index_j];
431 data[ind] = data[ind] ^ s_box[t];