~ubuntu-branches/ubuntu/hardy/steam/hardy

« back to all changes in this revision

Viewing changes to server/libraries/LanManHash.pmod

  • Committer: Bazaar Package Importer
  • Author(s): Alain Schroeder
  • Date: 2006-11-21 16:03:12 UTC
  • mfrom: (2.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061121160312-nf96y6nihzsyd2uv
Tags: 2.2.31-3
Add patch to prevent inconsistent data after shutdown.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Simple DES hash algorithm to create (weak) LanManager passwords
 
3
 *
 
4
 * Interface:
 
5
 *   string lanman_hash ( string password )
 
6
 *
 
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
 
10
 *
 
11
 * The original author is: Andrew Tridgell
 
12
 * The code was adapted from C to pike by: exodus@uni-paderborn.de
 
13
 *
 
14
 * The original file header follows (this file is under the same
 
15
 * license [GNU General Public License]):
 
16
 * --------------------------------------------------------------------
 
17
 
 
18
   Unix SMB/Netbios implementation.
 
19
   Version 1.9.
 
20
 
 
21
   a partial implementation of DES designed for use in the
 
22
   SMB authentication protocol
 
23
 
 
24
   Copyright (C) Andrew Tridgell 1997
 
25
 
 
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.
 
30
 
 
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.
 
35
 
 
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.
 
39
 
 
40
 * --------------------------------------------------------------------
 
41
 
 
42
   NOTES:
 
43
 
 
44
   This code makes no attempt to be fast! In fact, it is a very
 
45
   slow implementation
 
46
 
 
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)
 
50
 
 
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.
 
54
 
 
55
   There is no entry point into this code that allows normal DES operation.
 
56
 
 
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)
 
62
 
 
63
 * --------------------------------------------------------------------
 
64
 */
 
65
 
 
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 });
 
74
 
 
75
static array perm2 = ({ 14, 17, 11, 24,  1,  5,
 
76
                         3, 28, 15,  6, 21, 10,
 
77
                        23, 19, 12,  4, 26,  8,
 
78
                        16,  7, 27, 20, 13,  2,
 
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 });
 
83
 
 
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 });
 
92
 
 
93
static array perm4 = ({ 32,  1,  2,  3,  4,  5,
 
94
                         4,  5,  6,  7,  8,  9,
 
95
                         8,  9, 10, 11, 12, 13,
 
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 });
 
101
 
 
102
static array perm5 = ({ 16,  7, 20, 21,
 
103
                        29, 12, 28, 17,
 
104
                         1, 15, 23, 26,
 
105
                         5, 18, 31, 10,
 
106
                         2,  8, 24, 14,
 
107
                        32, 27,  3,  9,
 
108
                        19, 13, 30,  6,
 
109
                        22, 11,  4, 25});
 
110
 
 
111
 
 
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 });
 
120
 
 
121
 
 
122
static array sc = ({ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 });
 
123
 
 
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}) }),
 
129
 
 
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}) }),
 
134
 
 
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}) }),
 
139
 
 
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}) }),
 
144
 
 
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}) }),
 
149
 
 
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}) }),
 
154
 
 
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}) }),
 
159
 
 
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}) })
 
164
});
 
165
 
 
166
static string make_string ( int size ) {
 
167
  string out = "";
 
168
  for ( int i=0; i<size; i++ ) out += " ";
 
169
  return out;
 
170
}
 
171
 
 
172
static string permute ( string in, array(int) p, int n)
 
173
{
 
174
  string out = make_string(n);
 
175
  for (int i=0;i<n;i++)
 
176
    out[i] = in[p[i]-1];
 
177
  return out;
 
178
}
 
179
 
 
180
static string lshift(string d, int count, int n)
 
181
{
 
182
  string out = make_string(64);
 
183
  for ( int i=0; i<n; i++ ) out[i] = d[(i+count)%n];
 
184
  return out;
 
185
}
 
186
 
 
187
static string concat ( string in1, string in2, int l1, int l2 )
 
188
{
 
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];
 
192
  return out;
 
193
}
 
194
 
 
195
static string xor(string in1, string in2, int n)
 
196
{
 
197
  string out = make_string(n);
 
198
        for (int i=0;i<n;i++)
 
199
                out[i] = in1[i] ^ in2[i];
 
200
  return out;
 
201
}
 
202
 
 
203
static string dohash(string in, string key)
 
204
{
 
205
  string out = make_string(64);
 
206
        int i, j, k;
 
207
  string pk1 = make_string(56);
 
208
  string c = make_string(28);
 
209
  string d = make_string(28);
 
210
  string cd = make_string(56);
 
211
  array ki = ({ }); 
 
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);
 
216
 
 
217
        pk1 = permute( key, perm1, 56);
 
218
 
 
219
        for (i=0;i<28;i++)
 
220
                c[i] = pk1[i];
 
221
        for (i=0;i<28;i++)
 
222
                d[i] = pk1[i+28];
 
223
 
 
224
        for (i=0;i<16;i++) {
 
225
                c = lshift(c, sc[i], 28);
 
226
                d = lshift(d, sc[i], 28);
 
227
 
 
228
                cd = concat( c, d, 28, 28);
 
229
                ki[i] = permute( cd, perm2, 48);
 
230
        }
 
231
 
 
232
        pd1 = permute( in, perm3, 64);
 
233
 
 
234
        for (j=0;j<32;j++) {
 
235
                l[j] = pd1[j];
 
236
                r[j] = pd1[j+32];
 
237
        }
 
238
 
 
239
        for (i=0;i<16;i++) {
 
240
    string er = make_string(48);
 
241
    string erk = make_string(48);
 
242
    array b = ({ });
 
243
    for ( int z=0; z<8; z++ ) {
 
244
      b += ({ make_string(6) });
 
245
    }
 
246
    string cb = make_string(32);
 
247
    string pcb = make_string(32);
 
248
    string r2 = make_string(32);
 
249
 
 
250
                er = permute( r, perm4, 48);
 
251
 
 
252
                erk = xor( er, ki[i], 48);
 
253
 
 
254
                for (j=0;j<8;j++)
 
255
                        for (k=0;k<6;k++)
 
256
                                b[j][k] = erk[j*6 + k];
 
257
 
 
258
                for (j=0;j<8;j++) {
 
259
                        int m, n;
 
260
                        m = (b[j][0]<<1) | b[j][5];
 
261
 
 
262
                        n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
 
263
 
 
264
                        for (k=0;k<4;k++)
 
265
                                b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
 
266
                }
 
267
 
 
268
                for (j=0;j<8;j++)
 
269
                        for (k=0;k<4;k++)
 
270
                                cb[j*4+k] = b[j][k];
 
271
                pcb = permute( cb, perm5, 32);
 
272
 
 
273
                r2 = xor( l, pcb, 32);
 
274
 
 
275
                for (j=0;j<32;j++)
 
276
                        l[j] = r[j];
 
277
 
 
278
                for (j=0;j<32;j++)
 
279
                        r[j] = r2[j];
 
280
        }
 
281
 
 
282
        rl = concat( r, l, 32, 32);
 
283
 
 
284
        out = permute( rl, perm6, 64);
 
285
  return out;
 
286
}
 
287
 
 
288
static string str_to_key(string str)
 
289
{
 
290
  string key = "12345678";
 
291
        int i;
 
292
 
 
293
        key[0] = str[0]>>1;
 
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;
 
301
        for (i=0;i<8;i++) {
 
302
                key[i] = (key[i]<<1);
 
303
        }
 
304
  return key;
 
305
}
 
306
 
 
307
static string smbhash( string in, string key)
 
308
{
 
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);
 
314
        int i;
 
315
 
 
316
        key2 = str_to_key(key);
 
317
 
 
318
        for (i=0;i<64;i++) {
 
319
                inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
 
320
                keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
 
321
                outb[i] = 0;
 
322
        }
 
323
 
 
324
        outb = dohash( inb, keyb);
 
325
 
 
326
        for (i=0;i<8;i++) {
 
327
                out[i] = 0;
 
328
        }
 
329
 
 
330
        for (i=0;i<64;i++) {
 
331
                if (outb[i])
 
332
                        out[i/8] |= (1<<(7-(i%8)));
 
333
        }
 
334
  return out;
 
335
}
 
336
 
 
337
static string string_to_hex ( string str ) {
 
338
  string out = "";
 
339
  for ( int i=0; i<sizeof(str); i++ )
 
340
    out += sprintf( "%02x", str[i] );
 
341
  return out;
 
342
}
 
343
 
 
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";
 
349
 
 
350
  string out = "";
 
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 ) );
 
357
}
 
358