2
* Simple DES hash algorithm to create (weak) LanManager passwords
5
* string lanman_hash ( string password )
7
* Adapted to pike from C code. The original source code is the file
8
* smbdes.c from the following package:
9
* http://www.nomis52.net/data/mkntpwd.tar.gz
11
* The original author is: Andrew Tridgell
12
* The code was adapted from C to pike by: exodus@uni-paderborn.de
14
* The original file header follows (this file is under the same
15
* license [GNU General Public License]):
16
* --------------------------------------------------------------------
18
Unix SMB/Netbios implementation.
21
a partial implementation of DES designed for use in the
22
SMB authentication protocol
24
Copyright (C) Andrew Tridgell 1997
26
This program is free software; you can redistribute it and/or modify
27
it under the terms of the GNU General Public License as published by
28
the Free Software Foundation; either version 2 of the License, or
29
(at your option) any later version.
31
This program is distributed in the hope that it will be useful,
32
but WITHOUT ANY WARRANTY; without even the implied warranty of
33
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
GNU General Public License for more details.
36
You should have received a copy of the GNU General Public License
37
along with this program; if not, write to the Free Software
38
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40
* --------------------------------------------------------------------
44
This code makes no attempt to be fast! In fact, it is a very
47
This code is NOT a complete DES implementation. It implements only
48
the minimum necessary for SMB authentication, as used by all SMB
49
products (including every copy of Microsoft Windows95 ever sold)
51
In particular, it can only do a unchained forward DES pass. This
52
means it is not possible to use this code for encryption/decryption
53
of data, instead it is only useful as a "hash" algorithm.
55
There is no entry point into this code that allows normal DES operation.
57
I believe this means that this code does not come under ITAR
58
regulations but this is NOT a legal opinion. If you are concerned
59
about the applicability of ITAR regulations to this code then you
60
should confirm it for yourself (and maybe let me know if you come
61
up with a different answer to the one above)
63
* --------------------------------------------------------------------
66
static array perm1 = ({ 57, 49, 41, 33, 25, 17, 9,
67
1, 58, 50, 42, 34, 26, 18,
68
10, 2, 59, 51, 43, 35, 27,
69
19, 11, 3, 60, 52, 44, 36,
70
63, 55, 47, 39, 31, 23, 15,
71
7, 62, 54, 46, 38, 30, 22,
72
14, 6, 61, 53, 45, 37, 29,
73
21, 13, 5, 28, 20, 12, 4 });
75
static array perm2 = ({ 14, 17, 11, 24, 1, 5,
79
41, 52, 31, 37, 47, 55,
80
30, 40, 51, 45, 33, 48,
81
44, 49, 39, 56, 34, 53,
82
46, 42, 50, 36, 29, 32 });
84
static array perm3 = ({ 58, 50, 42, 34, 26, 18, 10, 2,
85
60, 52, 44, 36, 28, 20, 12, 4,
86
62, 54, 46, 38, 30, 22, 14, 6,
87
64, 56, 48, 40, 32, 24, 16, 8,
88
57, 49, 41, 33, 25, 17, 9, 1,
89
59, 51, 43, 35, 27, 19, 11, 3,
90
61, 53, 45, 37, 29, 21, 13, 5,
91
63, 55, 47, 39, 31, 23, 15, 7 });
93
static array perm4 = ({ 32, 1, 2, 3, 4, 5,
96
12, 13, 14, 15, 16, 17,
97
16, 17, 18, 19, 20, 21,
98
20, 21, 22, 23, 24, 25,
99
24, 25, 26, 27, 28, 29,
100
28, 29, 30, 31, 32, 1 });
102
static array perm5 = ({ 16, 7, 20, 21,
112
static array perm6 = ({ 40, 8, 48, 16, 56, 24, 64, 32,
113
39, 7, 47, 15, 55, 23, 63, 31,
114
38, 6, 46, 14, 54, 22, 62, 30,
115
37, 5, 45, 13, 53, 21, 61, 29,
116
36, 4, 44, 12, 52, 20, 60, 28,
117
35, 3, 43, 11, 51, 19, 59, 27,
118
34, 2, 42, 10, 50, 18, 58, 26,
119
33, 1, 41, 9, 49, 17, 57, 25 });
122
static array sc = ({ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 });
124
static array sbox = ({
125
({ ({14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}),
126
({0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}),
127
({4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}),
128
({15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}) }),
130
({ ({15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}),
131
({3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}),
132
({0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}),
133
({13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}) }),
135
({ ({10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}),
136
({13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}),
137
({13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}),
138
({1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}) }),
140
({ ({7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}),
141
({13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}),
142
({10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}),
143
({3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}) }),
145
({ ({2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}),
146
({14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}),
147
({4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}),
148
({11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}) }),
150
({ ({12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}),
151
({10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}),
152
({9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}),
153
({4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}) }),
155
({ ({4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}),
156
({13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}),
157
({1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}),
158
({6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}) }),
160
({ ({13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}),
161
({1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}),
162
({7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}),
163
({2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}) })
166
static string make_string ( int size ) {
168
for ( int i=0; i<size; i++ ) out += " ";
172
static string permute ( string in, array(int) p, int n)
174
string out = make_string(n);
175
for (int i=0;i<n;i++)
180
static string lshift(string d, int count, int n)
182
string out = make_string(64);
183
for ( int i=0; i<n; i++ ) out[i] = d[(i+count)%n];
187
static string concat ( string in1, string in2, int l1, int l2 )
189
string out = make_string( l1 + l2 );
190
for ( int i=0; i<l1; i++ ) out[i] = in1[i];
191
for ( int i=0; i<l2; i++ ) out[l1+i] = in2[i];
195
static string xor(string in1, string in2, int n)
197
string out = make_string(n);
198
for (int i=0;i<n;i++)
199
out[i] = in1[i] ^ in2[i];
203
static string dohash(string in, string key)
205
string out = make_string(64);
207
string pk1 = make_string(56);
208
string c = make_string(28);
209
string d = make_string(28);
210
string cd = make_string(56);
212
for ( int z=0; z<16; z++ ) ki += ({ make_string(48) });
213
string pd1 = make_string(64);
214
string l = make_string(32), r = make_string(32);
215
string rl = make_string(64);
217
pk1 = permute( key, perm1, 56);
225
c = lshift(c, sc[i], 28);
226
d = lshift(d, sc[i], 28);
228
cd = concat( c, d, 28, 28);
229
ki[i] = permute( cd, perm2, 48);
232
pd1 = permute( in, perm3, 64);
240
string er = make_string(48);
241
string erk = make_string(48);
243
for ( int z=0; z<8; z++ ) {
244
b += ({ make_string(6) });
246
string cb = make_string(32);
247
string pcb = make_string(32);
248
string r2 = make_string(32);
250
er = permute( r, perm4, 48);
252
erk = xor( er, ki[i], 48);
256
b[j][k] = erk[j*6 + k];
260
m = (b[j][0]<<1) | b[j][5];
262
n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
265
b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
271
pcb = permute( cb, perm5, 32);
273
r2 = xor( l, pcb, 32);
282
rl = concat( r, l, 32, 32);
284
out = permute( rl, perm6, 64);
288
static string str_to_key(string str)
290
string key = "12345678";
294
key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
295
key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
296
key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
297
key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
298
key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
299
key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
300
key[7] = str[6]&0x7F;
302
key[i] = (key[i]<<1);
307
static string smbhash( string in, string key)
309
string out = make_string(8);
310
string outb = make_string(64);
311
string inb = make_string(64);
312
string keyb = make_string(64);
313
string key2 = make_string(8);
316
key2 = str_to_key(key);
319
inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
320
keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
324
outb = dohash( inb, keyb);
332
out[i/8] |= (1<<(7-(i%8)));
337
static string string_to_hex ( string str ) {
339
for ( int i=0; i<sizeof(str); i++ )
340
out += sprintf( "%02x", str[i] );
344
string lanman_hash ( string password ) {
345
if ( !stringp( password ) ) return 0;
346
string pw = upper_case( password );
347
if ( sizeof( pw ) > 14 ) pw = pw[0..13];
348
else while ( sizeof( pw ) < 14 ) pw += "\0";
351
array tmp = ({ 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 });
352
string sp8 = "12345678";
353
for ( int i=0; i<8; i++ ) sp8[i] = tmp[i];
354
out += smbhash( sp8, pw[0..6] );
355
out += smbhash( sp8, pw[7..13] );
356
return upper_case( string_to_hex( out ) );