The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
smbdes.c
Go to the documentation of this file.
1/*
2 Unix SMB/CIFS implementation.
3
4 a partial implementation of DES designed for use in the
5 SMB authentication protocol
6
7 @copyright Andrew Tridgell 1998
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23 @copyright 2006 The FreeRADIUS server project
24*/
25
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
49RCSID("$Id: 70f03133ef8a81fda0d2040c5942ba861a872734 $")
50
51#include <stdint.h>
52#include <string.h>
53#include <ctype.h>
54#include "smbdes.h"
55
56
57#define uchar unsigned char
58
59static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
60 1, 58, 50, 42, 34, 26, 18,
61 10, 2, 59, 51, 43, 35, 27,
62 19, 11, 3, 60, 52, 44, 36,
63 63, 55, 47, 39, 31, 23, 15,
64 7, 62, 54, 46, 38, 30, 22,
65 14, 6, 61, 53, 45, 37, 29,
66 21, 13, 5, 28, 20, 12, 4};
67
68static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
69 3, 28, 15, 6, 21, 10,
70 23, 19, 12, 4, 26, 8,
71 16, 7, 27, 20, 13, 2,
72 41, 52, 31, 37, 47, 55,
73 30, 40, 51, 45, 33, 48,
74 44, 49, 39, 56, 34, 53,
75 46, 42, 50, 36, 29, 32};
76
77static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
78 60, 52, 44, 36, 28, 20, 12, 4,
79 62, 54, 46, 38, 30, 22, 14, 6,
80 64, 56, 48, 40, 32, 24, 16, 8,
81 57, 49, 41, 33, 25, 17, 9, 1,
82 59, 51, 43, 35, 27, 19, 11, 3,
83 61, 53, 45, 37, 29, 21, 13, 5,
84 63, 55, 47, 39, 31, 23, 15, 7};
85
86static const 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};
94
95static const uchar perm5[32] = { 16, 7, 20, 21,
96 29, 12, 28, 17,
97 1, 15, 23, 26,
98 5, 18, 31, 10,
99 2, 8, 24, 14,
100 32, 27, 3, 9,
101 19, 13, 30, 6,
102 22, 11, 4, 25};
103
104
105static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
106 39, 7, 47, 15, 55, 23, 63, 31,
107 38, 6, 46, 14, 54, 22, 62, 30,
108 37, 5, 45, 13, 53, 21, 61, 29,
109 36, 4, 44, 12, 52, 20, 60, 28,
110 35, 3, 43, 11, 51, 19, 59, 27,
111 34, 2, 42, 10, 50, 18, 58, 26,
112 33, 1, 41, 9, 49, 17, 57, 25};
113
114
115static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
116
117static const uchar sbox[8][4][16] = {
118 {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
119 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
120 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
121 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
122
123 {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
124 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
125 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
126 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
127
128 {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
129 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
130 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
131 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
132
133 {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
134 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
135 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
136 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
137
138 {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
139 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
140 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
141 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
142
143 {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
144 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
145 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
146 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
147
148 {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
149 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
150 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
151 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
152
153 {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
154 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
155 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
156 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
157
158static void permute(char *out, char const *in, uchar const *p, int n)
159{
160 int i;
161 for (i=0;i<n;i++)
162 out[i] = in[p[i]-1];
163}
164
165static void lshift(char *d, int count, int n)
166{
167 char out[64];
168 int i;
169 for (i=0;i<n;i++)
170 out[i] = d[(i+count)%n];
171 for (i=0;i<n;i++)
172 d[i] = out[i];
173}
174
175static void concat(char *out, char *in1, char *in2, int l1, int l2)
176{
177 while (l1--)
178 *out++ = *in1++;
179 while (l2--)
180 *out++ = *in2++;
181}
182
183static void xor(char *out, char *in1, char *in2, int n)
184{
185 int i;
186 for (i=0;i<n;i++)
187 out[i] = in1[i] ^ in2[i];
188}
189
190static void dohash(char *out, char *in, char *key)
191{
192 int i, j, k;
193 char pk1[56];
194 char c[28];
195 char d[28];
196 char cd[56];
197 char ki[16][48];
198 char pd1[64];
199 char l[32], r[32];
200 char rl[64];
201
202 permute(pk1, key, perm1, 56);
203
204 for (i=0;i<28;i++)
205 c[i] = pk1[i];
206 for (i=0;i<28;i++)
207 d[i] = pk1[i+28];
208
209 for (i=0;i<16;i++) {
210 lshift(c, sc[i], 28);
211 lshift(d, sc[i], 28);
212
213 concat(cd, c, d, 28, 28);
214 permute(ki[i], cd, perm2, 48);
215 }
216
217 permute(pd1, in, perm3, 64);
218
219 for (j=0;j<32;j++) {
220 l[j] = pd1[j];
221 r[j] = pd1[j+32];
222 }
223
224 for (i=0;i<16;i++) {
225 char er[48];
226 char erk[48];
227 char b[8][6];
228 char cb[32];
229 char pcb[32];
230 char r2[32];
231
232 permute(er, r, perm4, 48);
233
234 xor(erk, er, ki[i], 48);
235
236 for (j=0;j<8;j++)
237 for (k=0;k<6;k++)
238 b[j][k] = erk[j*6 + k];
239
240 for (j=0;j<8;j++) {
241 int m, n;
242 m = (b[j][0]<<1) | b[j][5];
243
244 n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
245
246 for (k=0;k<4;k++)
247 b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
248 }
249
250 for (j=0;j<8;j++)
251 for (k=0;k<4;k++)
252 cb[j*4+k] = b[j][k];
253 permute(pcb, cb, perm5, 32);
254
255 xor(r2, l, pcb, 32);
256
257 for (j=0;j<32;j++)
258 l[j] = r[j];
259
260 for (j=0;j<32;j++)
261 r[j] = r2[j];
262 }
263
264 concat(rl, r, l, 32, 32);
265
266 permute(out, rl, perm6, 64);
267}
268
269static void str_to_key(unsigned char *str,unsigned char *key)
270{
271 int i;
272
273 key[0] = str[0]>>1;
274 key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
275 key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
276 key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
277 key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
278 key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
279 key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
280 key[7] = str[6]&0x7F;
281 for (i=0;i<8;i++) {
282 key[i] = (key[i]<<1);
283 }
284}
285
286
287void smbhash(unsigned char *out, unsigned char const *in, unsigned char *key)
288{
289 int i;
290 char outb[64];
291 char inb[64];
292 char keyb[64];
293 unsigned char key2[8];
294
295 str_to_key(key, key2);
296
297 for (i=0;i<64;i++) {
298 inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
299 keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
300 outb[i] = 0;
301 }
302
303 dohash(outb, inb, keyb);
304
305 for (i=0;i<8;i++) {
306 out[i] = 0;
307 }
308
309 for (i=0;i<64;i++) {
310 if (outb[i])
311 out[i/8] |= (1<<(7-(i%8)));
312 }
313}
314
315/*
316 * Converts the password to uppercase, and creates the LM
317 * password hash.
318 */
319void smbdes_lmpwdhash(char const *password, uint8_t *lmhash)
320{
321 int i;
322 uint8_t p14[14];
323 static uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
324
325 memset(p14, 0, sizeof(p14));
326 for (i = 0; i < 14 && password[i]; i++) {
327 p14[i] = toupper((uint8_t) password[i]);
328 }
329
330 smbhash(lmhash, sp8, p14);
331 smbhash(lmhash+8, sp8, p14+7);
332}
333
334/*
335 * Take the NT or LM password, and return the MSCHAP response
336 *
337 * The win_password MUST be exactly 16 bytes long.
338 */
339void smbdes_mschap(uint8_t const win_password[16],
340 uint8_t const *challenge, uint8_t *response)
341{
342 uint8_t p21[21];
343
344 memset(p21, 0, sizeof(p21));
345 memcpy(p21, win_password, 16);
346
347 smbhash(response, challenge, p21);
348 smbhash(response+8, challenge, p21+7);
349 smbhash(response+16, challenge, p21+14);
350}
int n
Definition acutest.h:577
#define RCSID(id)
Definition build.h:483
static fr_slen_t in
Definition dict.h:824
unsigned char uint8_t
static const uchar perm2[48]
Definition smbdes.c:68
static void xor(char *out, char *in1, char *in2, int n)
Definition smbdes.c:183
static const uchar sbox[8][4][16]
Definition smbdes.c:117
static void permute(char *out, char const *in, uchar const *p, int n)
Definition smbdes.c:158
static const uchar perm3[64]
Definition smbdes.c:77
static const uchar perm1[56]
Definition smbdes.c:59
static void lshift(char *d, int count, int n)
Definition smbdes.c:165
static const uchar perm4[48]
Definition smbdes.c:86
static void dohash(char *out, char *in, char *key)
Definition smbdes.c:190
static const uchar perm5[32]
Definition smbdes.c:95
static const uchar perm6[64]
Definition smbdes.c:105
static const uchar sc[16]
Definition smbdes.c:115
#define uchar
Definition smbdes.c:57
void smbhash(unsigned char *out, unsigned char const *in, unsigned char *key)
Definition smbdes.c:287
static void str_to_key(unsigned char *str, unsigned char *key)
Definition smbdes.c:269
static void concat(char *out, char *in1, char *in2, int l1, int l2)
Definition smbdes.c:175
void smbdes_mschap(uint8_t const win_password[16], uint8_t const *challenge, uint8_t *response)
Definition smbdes.c:339
void smbdes_lmpwdhash(char const *password, uint8_t *lmhash)
Definition smbdes.c:319
return count
Definition module.c:163
static size_t char ** out
Definition value.h:997