~ubuntu-branches/ubuntu/maverick/fetchmail/maverick-updates

1 by Nathaniel McCallum
Import upstream version 6.2.5
1
/* 
2
   Unix SMB/Netbios implementation.
3
   Version 1.9.
4
5
   a partial implementation of DES designed for use in the 
6
   SMB authentication protocol
7
8
   Copyright (C) Andrew Tridgell 1998
9
   
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 2 of the License, or
13
   (at your option) any later version.
14
   
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
   
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
*/
24
25
#include "smbdes.h"
26
27
/* NOTES: 
28
29
   This code makes no attempt to be fast! In fact, it is a very
30
   slow implementation 
31
32
   This code is NOT a complete DES implementation. It implements only
33
   the minimum necessary for SMB authentication, as used by all SMB
34
   products (including every copy of Microsoft Windows95 ever sold)
35
36
   In particular, it can only do a unchained forward DES pass. This
37
   means it is not possible to use this code for encryption/decryption
38
   of data, instead it is only useful as a "hash" algorithm.
39
40
   There is no entry point into this code that allows normal DES operation.
41
42
   I believe this means that this code does not come under ITAR
43
   regulations but this is NOT a legal opinion. If you are concerned
44
   about the applicability of ITAR regulations to this code then you
45
   should confirm it for yourself (and maybe let me know if you come
46
   up with a different answer to the one above)
47
*/
48
49
50
#define uchar unsigned char
51
52
static uchar perm1[56] = {57, 49, 41, 33, 25, 17,  9,
53
			 1, 58, 50, 42, 34, 26, 18,
54
			10,  2, 59, 51, 43, 35, 27,
55
			19, 11,  3, 60, 52, 44, 36,
56
			63, 55, 47, 39, 31, 23, 15,
57
			 7, 62, 54, 46, 38, 30, 22,
58
			14,  6, 61, 53, 45, 37, 29,
59
			21, 13,  5, 28, 20, 12,  4};
60
61
static uchar perm2[48] = {14, 17, 11, 24,  1,  5,
62
                         3, 28, 15,  6, 21, 10,
63
                        23, 19, 12,  4, 26,  8,
64
                        16,  7, 27, 20, 13,  2,
65
                        41, 52, 31, 37, 47, 55,
66
                        30, 40, 51, 45, 33, 48,
67
                        44, 49, 39, 56, 34, 53,
68
                        46, 42, 50, 36, 29, 32};
69
70
static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10,  2,
71
			60, 52, 44, 36, 28, 20, 12,  4,
72
			62, 54, 46, 38, 30, 22, 14,  6,
73
			64, 56, 48, 40, 32, 24, 16,  8,
74
			57, 49, 41, 33, 25, 17,  9,  1,
75
			59, 51, 43, 35, 27, 19, 11,  3,
76
			61, 53, 45, 37, 29, 21, 13,  5,
77
			63, 55, 47, 39, 31, 23, 15,  7};
78
79
static uchar perm4[48] = {   32,  1,  2,  3,  4,  5,
80
                            4,  5,  6,  7,  8,  9,
81
                            8,  9, 10, 11, 12, 13,
82
                           12, 13, 14, 15, 16, 17,
83
                           16, 17, 18, 19, 20, 21,
84
                           20, 21, 22, 23, 24, 25,
85
                           24, 25, 26, 27, 28, 29,
86
                           28, 29, 30, 31, 32,  1};
87
88
static uchar perm5[32] = {      16,  7, 20, 21,
89
                              29, 12, 28, 17,
90
                               1, 15, 23, 26,
91
                               5, 18, 31, 10,
92
                               2,  8, 24, 14,
93
                              32, 27,  3,  9,
94
                              19, 13, 30,  6,
95
                              22, 11,  4, 25};
96
97
98
static uchar perm6[64] ={ 40,  8, 48, 16, 56, 24, 64, 32,
99
                        39,  7, 47, 15, 55, 23, 63, 31,
100
                        38,  6, 46, 14, 54, 22, 62, 30,
101
                        37,  5, 45, 13, 53, 21, 61, 29,
102
                        36,  4, 44, 12, 52, 20, 60, 28,
103
                        35,  3, 43, 11, 51, 19, 59, 27,
104
                        34,  2, 42, 10, 50, 18, 58, 26,
105
                        33,  1, 41,  9, 49, 17, 57, 25};
106
107
108
static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
109
110
static uchar sbox[8][4][16] = {
111
	{{14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
112
	 {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
113
	 {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
114
	 {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
115
116
	{{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
117
	 {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
118
	 {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
119
	 {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
120
121
	{{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
122
	 {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
123
	 {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
124
	 {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
125
126
	{{7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
127
	 {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
128
	 {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
129
	 {3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14}},
130
131
	{{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
132
	 {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
133
	 {4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
134
	 {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
135
136
	{{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
137
	 {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
138
	 {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
139
	 {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
140
141
	{{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
142
	 {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
143
	 {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
144
	 {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
145
146
	{{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
147
	 {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
148
	 {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
149
	 {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
150
151
static void permute(char *out, char *in, uchar *p, int n)
152
{
153
	int i;
154
	for (i=0;i<n;i++)
155
		out[i] = in[p[i]-1];
156
}
157
158
static void lshift(char *d, int count, int n)
159
{
160
	char out[64];
161
	int i;
162
	for (i=0;i<n;i++)
163
		out[i] = d[(i+count)%n];
164
	for (i=0;i<n;i++)
165
		d[i] = out[i];
166
}
167
168
static void concat(char *out, char *in1, char *in2, int l1, int l2)
169
{
170
	while (l1--)
171
		*out++ = *in1++;
172
	while (l2--)
173
		*out++ = *in2++;
174
}
175
1.1.3 by Scott James Remnant
Import upstream version 6.3.4
176
static void exor(char *out, char *in1, char *in2, int n)
1 by Nathaniel McCallum
Import upstream version 6.2.5
177
{
178
	int i;
179
	for (i=0;i<n;i++)
180
		out[i] = in1[i] ^ in2[i];
181
}
182
183
static void dohash(char *out, char *in, char *key, int forw)
184
{
185
	int i, j, k;
186
	char pk1[56];
187
	char c[28];
188
	char d[28];
189
	char cd[56];
190
	char ki[16][48];
191
	char pd1[64];
192
	char l[32], r[32];
193
	char rl[64];
194
195
	permute(pk1, key, perm1, 56);
196
197
	for (i=0;i<28;i++)
198
		c[i] = pk1[i];
199
	for (i=0;i<28;i++)
200
		d[i] = pk1[i+28];
201
202
	for (i=0;i<16;i++) {
203
		lshift(c, sc[i], 28);
204
		lshift(d, sc[i], 28);
205
206
		concat(cd, c, d, 28, 28); 
207
		permute(ki[i], cd, perm2, 48); 
208
	}
209
210
	permute(pd1, in, perm3, 64);
211
212
	for (j=0;j<32;j++) {
213
		l[j] = pd1[j];
214
		r[j] = pd1[j+32];
215
	}
216
217
	for (i=0;i<16;i++) {
218
		char er[48];
219
		char erk[48];
220
		char b[8][6];
221
		char cb[32];
222
		char pcb[32];
223
		char r2[32];
224
225
		permute(er, r, perm4, 48);
226
1.1.3 by Scott James Remnant
Import upstream version 6.3.4
227
		exor(erk, er, ki[forw ? i : 15 - i], 48);
1 by Nathaniel McCallum
Import upstream version 6.2.5
228
229
		for (j=0;j<8;j++)
230
			for (k=0;k<6;k++)
231
				b[j][k] = erk[j*6 + k];
232
233
		for (j=0;j<8;j++) {
234
			int m, n;
235
			m = (b[j][0]<<1) | b[j][5];
236
237
			n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; 
238
239
			for (k=0;k<4;k++) 
240
				b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; 
241
		}
242
243
		for (j=0;j<8;j++)
244
			for (k=0;k<4;k++)
245
				cb[j*4+k] = b[j][k];
246
		permute(pcb, cb, perm5, 32);
247
1.1.3 by Scott James Remnant
Import upstream version 6.3.4
248
		exor(r2, l, pcb, 32);
1 by Nathaniel McCallum
Import upstream version 6.2.5
249
250
		for (j=0;j<32;j++)
251
			l[j] = r[j];
252
253
		for (j=0;j<32;j++)
254
			r[j] = r2[j];
255
	}
256
257
	concat(rl, r, l, 32, 32);
258
259
	permute(out, rl, perm6, 64);
260
}
261
262
static void str_to_key(unsigned char *str,unsigned char *key)
263
{
264
	int i;
265
266
	key[0] = str[0]>>1;
267
	key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
268
	key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
269
	key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
270
	key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
271
	key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
272
	key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
273
	key[7] = str[6]&0x7F;
274
	for (i=0;i<8;i++) {
275
		key[i] = (key[i]<<1);
276
	}
277
}
278
279
280
static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
281
{
282
	int i;
283
	char outb[64];
284
	char inb[64];
285
	char keyb[64];
286
	unsigned char key2[8];
287
288
	str_to_key(key, key2);
289
290
	for (i=0;i<64;i++) {
291
		inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
292
		keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
293
		outb[i] = 0;
294
	}
295
296
	dohash(outb, inb, keyb, forw);
297
298
	for (i=0;i<8;i++) {
299
		out[i] = 0;
300
	}
301
302
	for (i=0;i<64;i++) {
303
		if (outb[i])
304
			out[i/8] |= (1<<(7-(i%8)));
305
	}
306
}
307
308
void E_P16(unsigned char *p14,unsigned char *p16)
309
{
310
	unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
311
	smbhash(p16, sp8, p14, 1);
312
	smbhash(p16+8, sp8, p14+7, 1);
313
}
314
315
void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
316
{
317
	smbhash(p24, c8, p21, 1);
318
	smbhash(p24+8, c8, p21+7, 1);
319
	smbhash(p24+16, c8, p21+14, 1);
320
}
321
322
void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
323
{
324
	smbhash(out, in, p14, 0);
325
        smbhash(out+8, in+8, p14+7, 0);
326
}
327
328
void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
329
{
330
        smbhash(out, in, p14, 1);
331
        smbhash(out+8, in+8, p14+7, 1);
332
}
333
334
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
335
{
336
	unsigned char buf[8];
337
338
	smbhash(buf, in, key, 1);
339
	smbhash(out, buf, key+9, 1);
340
}
341
342
void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
343
{
344
	unsigned char buf[8];
345
	static unsigned char key2[8];
346
347
	smbhash(buf, in, key, 1);
348
	key2[0] = key[7];
349
	smbhash(out, buf, key2, 1);
350
}
351
352
void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
353
{
354
        static unsigned char key2[8];
355
356
        smbhash(out, in, key, forw);
357
        key2[0] = key[7];
358
        smbhash(out + 8, in + 8, key2, forw);
359
}
360
361
void SamOEMhash( unsigned char *data, unsigned char *key, int val)
362
{
363
  unsigned char s_box[256];
364
  unsigned char index_i = 0;
365
  unsigned char index_j = 0;
366
  unsigned char j = 0;
367
  int ind;
368
369
  for (ind = 0; ind < 256; ind++)
370
  {
371
    s_box[ind] = (unsigned char)ind;
372
  }
373
374
  for( ind = 0; ind < 256; ind++)
375
  {
376
     unsigned char tc;
377
378
     j += (s_box[ind] + key[ind%16]);
379
380
     tc = s_box[ind];
381
     s_box[ind] = s_box[j];
382
     s_box[j] = tc;
383
  }
384
  for( ind = 0; ind < (val ? 516 : 16); ind++)
385
  {
386
    unsigned char tc;
387
    unsigned char t;
388
389
    index_i++;
390
    index_j += s_box[index_i];
391
392
    tc = s_box[index_i];
393
    s_box[index_i] = s_box[index_j];
394
    s_box[index_j] = tc;
395
396
    t = s_box[index_i] + s_box[index_j];
397
    data[ind] = data[ind] ^ s_box[t];
398
  }
399
}