2 Unix SMB/CIFS implementation.
4 a partial implementation of DES designed for use in the
5 SMB authentication protocol
7 Copyright (C) Andrew Tridgell 1998
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.
31 #include <epan/crypt-des.h>
35 This code makes no attempt to be fast! In fact, it is a very
38 This code is NOT a complete DES implementation. It implements only
39 the minimum necessary for SMB authentication, as used by all SMB
40 products (including every copy of Microsoft Windows95 ever sold)
42 In particular, it can only do a unchained forward DES pass. This
43 means it is not possible to use this code for encryption/decryption
44 of data, instead it is only useful as a "hash" algorithm.
46 There is no entry point into this code that allows normal DES operation.
48 I believe this means that this code does not come under ITAR
49 regulations but this is NOT a legal opinion. If you are concerned
50 about the applicability of ITAR regulations to this code then you
51 should confirm it for yourself (and maybe let me know if you come
52 up with a different answer to the one above)
56 #define uchar unsigned char
58 static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
59 1, 58, 50, 42, 34, 26, 18,
60 10, 2, 59, 51, 43, 35, 27,
61 19, 11, 3, 60, 52, 44, 36,
62 63, 55, 47, 39, 31, 23, 15,
63 7, 62, 54, 46, 38, 30, 22,
64 14, 6, 61, 53, 45, 37, 29,
65 21, 13, 5, 28, 20, 12, 4};
67 static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
71 41, 52, 31, 37, 47, 55,
72 30, 40, 51, 45, 33, 48,
73 44, 49, 39, 56, 34, 53,
74 46, 42, 50, 36, 29, 32};
76 static const 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};
85 static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
88 12, 13, 14, 15, 16, 17,
89 16, 17, 18, 19, 20, 21,
90 20, 21, 22, 23, 24, 25,
91 24, 25, 26, 27, 28, 29,
92 28, 29, 30, 31, 32, 1};
94 static const uchar perm5[32] = { 16, 7, 20, 21,
104 static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
105 39, 7, 47, 15, 55, 23, 63, 31,
106 38, 6, 46, 14, 54, 22, 62, 30,
107 37, 5, 45, 13, 53, 21, 61, 29,
108 36, 4, 44, 12, 52, 20, 60, 28,
109 35, 3, 43, 11, 51, 19, 59, 27,
110 34, 2, 42, 10, 50, 18, 58, 26,
111 33, 1, 41, 9, 49, 17, 57, 25};
114 static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
116 static const uchar sbox[8][4][16] = {
117 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
118 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
119 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
120 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
122 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
123 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
124 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
125 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
127 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
128 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
129 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
130 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
132 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
133 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
134 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
135 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
137 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
138 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
139 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
140 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
142 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
143 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
144 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
145 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
147 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
148 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
149 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
150 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
152 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
153 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
154 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
155 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
157 static void permute(char *out, const char *in, const uchar *p, int n)
164 static void lshift(char *d, int count, int n)
169 out[i] = d[(i+count)%n];
174 static void concat(char *out, char *in1, char *in2, int l1, int l2)
182 static void xor(char *out, char *in1, char *in2, int n)
186 out[i] = in1[i] ^ in2[i];
189 static void dohash(char *out, char *in, char *key, int forw)
201 permute(pk1, key, perm1, 56);
209 lshift(c, sc[i], 28);
210 lshift(d, sc[i], 28);
212 concat(cd, c, d, 28, 28);
213 permute(ki[i], cd, perm2, 48);
216 permute(pd1, in, perm3, 64);
231 permute(er, r, perm4, 48);
233 xor(erk, er, ki[forw ? i : 15 - i], 48);
237 b[j][k] = erk[j*6 + k];
241 m = (b[j][0]<<1) | b[j][5];
243 n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
246 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
252 permute(pcb, cb, perm5, 32);
263 concat(rl, r, l, 32, 32);
265 permute(out, rl, perm6, 64);
268 static void str_to_key(const unsigned char *str,unsigned char *key)
273 key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
274 key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
275 key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
276 key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
277 key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
278 key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
279 key[7] = str[6]&0x7F;
281 key[i] = (key[i]<<1);
286 void crypt_des_ecb(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
292 unsigned char key2[8];
294 str_to_key(key, key2);
297 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
298 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
302 dohash(outb, inb, keyb, forw);
310 out[i/8] |= (1<<(7-(i%8)));