OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_Demo_Rowley_ARM7/] [lwip-1.1.0/] [src/] [netif/] [ppp/] [chpms.c] - Blame information for rev 583

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 583 jeremybenn
/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/
2
/*****************************************************************************
3
* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.
4
*
5
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
6
* Copyright (c) 1997 by Global Election Systems Inc.  All rights reserved.
7
*
8
* The authors hereby grant permission to use, copy, modify, distribute,
9
* and license this software and its documentation for any purpose, provided
10
* that existing copyright notices are retained in all copies and that this
11
* notice and the following disclaimer are included verbatim in any
12
* distributions. No written agreement, license, or royalty fee is required
13
* for any of the authorized uses.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*
26
******************************************************************************
27
* REVISION HISTORY
28
*
29
* 03-01-01 Marc Boucher <marc@mbsi.ca>
30
*   Ported to lwIP.
31
* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
32
*       Original based on BSD chap_ms.c.
33
*****************************************************************************/
34
/*
35
 * chap_ms.c - Microsoft MS-CHAP compatible implementation.
36
 *
37
 * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
38
 * http://www.strataware.com/
39
 *
40
 * All rights reserved.
41
 *
42
 * Redistribution and use in source and binary forms are permitted
43
 * provided that the above copyright notice and this paragraph are
44
 * duplicated in all such forms and that any documentation,
45
 * advertising materials, and other materials related to such
46
 * distribution and use acknowledge that the software was developed
47
 * by Eric Rosenquist.  The name of the author may not be used to
48
 * endorse or promote products derived from this software without
49
 * specific prior written permission.
50
 *
51
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
52
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
53
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
54
 */
55
 
56
/*
57
 * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
58
 *
59
 *   Implemented LANManager type password response to MS-CHAP challenges.
60
 *   Now pppd provides both NT style and LANMan style blocks, and the
61
 *   prefered is set by option "ms-lanman". Default is to use NT.
62
 *   The hash text (StdText) was taken from Win95 RASAPI32.DLL.
63
 *
64
 *   You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
65
 */
66
 
67
#define USE_CRYPT
68
 
69
 
70
#include "ppp.h"
71
 
72
#if MSCHAP_SUPPORT > 0
73
 
74
#include "md4.h"
75
#ifndef USE_CRYPT
76
#include "des.h"
77
#endif
78
#include "chap.h"
79
#include "chpms.h"
80
#include "pppdebug.h"
81
 
82
 
83
/*************************/
84
/*** LOCAL DEFINITIONS ***/
85
/*************************/
86
 
87
 
88
/************************/
89
/*** LOCAL DATA TYPES ***/
90
/************************/
91
typedef struct {
92
    u_char LANManResp[24];
93
    u_char NTResp[24];
94
    u_char UseNT;               /* If 1, ignore the LANMan response field */
95
} MS_ChapResponse;
96
/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
97
   in case this struct gets padded. */
98
 
99
 
100
 
101
/***********************************/
102
/*** LOCAL FUNCTION DECLARATIONS ***/
103
/***********************************/
104
 
105
/* XXX Don't know what to do with these. */
106
extern void setkey(const char *);
107
extern void encrypt(char *, int);
108
 
109
static void     DesEncrypt (u_char *, u_char *, u_char *);
110
static void     MakeKey (u_char *, u_char *);
111
 
112
#ifdef USE_CRYPT
113
static void     Expand (u_char *, u_char *);
114
static void     Collapse (u_char *, u_char *);
115
#endif
116
 
117
static void ChallengeResponse(
118
        u_char *challenge,      /* IN   8 octets */
119
        u_char *pwHash,         /* IN  16 octets */
120
        u_char *response        /* OUT 24 octets */
121
);
122
static void ChapMS_NT(
123
        char *rchallenge,
124
        int rchallenge_len,
125
        char *secret,
126
        int secret_len,
127
        MS_ChapResponse *response
128
);
129
static u_char Get7Bits(
130
        u_char *input,
131
        int startBit
132
);
133
 
134
 
135
/***********************************/
136
/*** PUBLIC FUNCTION DEFINITIONS ***/
137
/***********************************/
138
void ChapMS(
139
        chap_state *cstate,
140
        char *rchallenge,
141
        int rchallenge_len,
142
        char *secret,
143
        int secret_len
144
)
145
{
146
        MS_ChapResponse response;
147
#ifdef MSLANMAN
148
        extern int ms_lanman;
149
#endif
150
 
151
#if 0
152
        CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));
153
#endif
154
        BZERO(&response, sizeof(response));
155
 
156
        /* Calculate both always */
157
        ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
158
 
159
#ifdef MSLANMAN
160
        ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
161
 
162
        /* prefered method is set by option  */
163
        response.UseNT = !ms_lanman;
164
#else
165
        response.UseNT = 1;
166
#endif
167
 
168
        BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
169
        cstate->resp_length = MS_CHAP_RESPONSE_LEN;
170
}
171
 
172
 
173
/**********************************/
174
/*** LOCAL FUNCTION DEFINITIONS ***/
175
/**********************************/
176
static void ChallengeResponse(
177
        u_char *challenge,      /* IN   8 octets */
178
        u_char *pwHash,         /* IN  16 octets */
179
        u_char *response        /* OUT 24 octets */
180
)
181
{
182
        char    ZPasswordHash[21];
183
 
184
        BZERO(ZPasswordHash, sizeof(ZPasswordHash));
185
        BCOPY(pwHash, ZPasswordHash, 16);
186
 
187
#if 0
188
        log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
189
#endif
190
 
191
        DesEncrypt(challenge, ZPasswordHash +  0, response + 0);
192
        DesEncrypt(challenge, ZPasswordHash +  7, response + 8);
193
        DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
194
 
195
#if 0
196
        log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
197
#endif
198
}
199
 
200
 
201
#ifdef USE_CRYPT
202
static void DesEncrypt(
203
        u_char *clear,  /* IN  8 octets */
204
        u_char *key,    /* IN  7 octets */
205
        u_char *cipher  /* OUT 8 octets */
206
)
207
{
208
        u_char des_key[8];
209
        u_char crypt_key[66];
210
        u_char des_input[66];
211
 
212
        MakeKey(key, des_key);
213
 
214
        Expand(des_key, crypt_key);
215
        setkey(crypt_key);
216
 
217
#if 0
218
        CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
219
               clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
220
#endif
221
 
222
        Expand(clear, des_input);
223
        encrypt(des_input, 0);
224
        Collapse(des_input, cipher);
225
 
226
#if 0
227
        CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
228
               cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
229
#endif
230
}
231
 
232
#else /* USE_CRYPT */
233
 
234
static void DesEncrypt(
235
        u_char *clear,  /* IN  8 octets */
236
        u_char *key,    /* IN  7 octets */
237
        u_char *cipher  /* OUT 8 octets */
238
)
239
{
240
        des_cblock              des_key;
241
        des_key_schedule        key_schedule;
242
 
243
        MakeKey(key, des_key);
244
 
245
        des_set_key(&des_key, key_schedule);
246
 
247
#if 0
248
        CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
249
               clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
250
#endif
251
 
252
        des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
253
 
254
#if 0
255
        CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
256
               cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
257
#endif
258
}
259
 
260
#endif /* USE_CRYPT */
261
 
262
 
263
static u_char Get7Bits(
264
        u_char *input,
265
        int startBit
266
)
267
{
268
        register unsigned int   word;
269
 
270
        word  = (unsigned)input[startBit / 8] << 8;
271
        word |= (unsigned)input[startBit / 8 + 1];
272
 
273
        word >>= 15 - (startBit % 8 + 7);
274
 
275
        return word & 0xFE;
276
}
277
 
278
#ifdef USE_CRYPT
279
 
280
/* in == 8-byte string (expanded version of the 56-bit key)
281
 * out == 64-byte string where each byte is either 1 or 0
282
 * Note that the low-order "bit" is always ignored by by setkey()
283
 */
284
static void Expand(u_char *in, u_char *out)
285
{
286
        int j, c;
287
        int i;
288
 
289
        for(i = 0; i < 64; in++){
290
                c = *in;
291
                for(j = 7; j >= 0; j--)
292
                        *out++ = (c >> j) & 01;
293
                i += 8;
294
        }
295
}
296
 
297
/* The inverse of Expand
298
 */
299
static void Collapse(u_char *in, u_char *out)
300
{
301
        int j;
302
        int i;
303
        unsigned int c;
304
 
305
        for (i = 0; i < 64; i += 8, out++) {
306
                c = 0;
307
                for (j = 7; j >= 0; j--, in++)
308
                        c |= *in << j;
309
                *out = c & 0xff;
310
        }
311
}
312
#endif
313
 
314
static void MakeKey(
315
        u_char *key,            /* IN  56 bit DES key missing parity bits */
316
        u_char *des_key         /* OUT 64 bit DES key with parity bits added */
317
)
318
{
319
        des_key[0] = Get7Bits(key,  0);
320
        des_key[1] = Get7Bits(key,  7);
321
        des_key[2] = Get7Bits(key, 14);
322
        des_key[3] = Get7Bits(key, 21);
323
        des_key[4] = Get7Bits(key, 28);
324
        des_key[5] = Get7Bits(key, 35);
325
        des_key[6] = Get7Bits(key, 42);
326
        des_key[7] = Get7Bits(key, 49);
327
 
328
#ifndef USE_CRYPT
329
        des_set_odd_parity((des_cblock *)des_key);
330
#endif
331
 
332
#if 0
333
        CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
334
               key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
335
        CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
336
               des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
337
#endif
338
}
339
 
340
static void ChapMS_NT(
341
        char *rchallenge,
342
        int rchallenge_len,
343
        char *secret,
344
        int secret_len,
345
        MS_ChapResponse *response
346
)
347
{
348
        int                     i;
349
        MDstruct        md4Context;
350
        u_char          unicodePassword[MAX_NT_PASSWORD * 2];
351
        static int      low_byte_first = -1;
352
 
353
        /* Initialize the Unicode version of the secret (== password). */
354
        /* This implicitly supports 8-bit ISO8859/1 characters. */
355
        BZERO(unicodePassword, sizeof(unicodePassword));
356
        for (i = 0; i < secret_len; i++)
357
                unicodePassword[i * 2] = (u_char)secret[i];
358
 
359
        MDbegin(&md4Context);
360
        MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);     /* Unicode is 2 bytes/char, *8 for bit count */
361
 
362
        if (low_byte_first == -1)
363
                low_byte_first = (htons((unsigned short int)1) != 1);
364
        if (low_byte_first == 0)
365
                MDreverse((u_long *)&md4Context);  /*  sfb 961105 */
366
 
367
        MDupdate(&md4Context, NULL, 0);  /* Tell MD4 we're done */
368
 
369
        ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);
370
}
371
 
372
#ifdef MSLANMAN
373
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
374
 
375
static ChapMS_LANMan(
376
        char *rchallenge,
377
        int rchallenge_len,
378
        char *secret,
379
        int secret_len,
380
        MS_ChapResponse *response
381
)
382
{
383
        int                     i;
384
        u_char          UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
385
        u_char          PasswordHash[16];
386
 
387
        /* LANMan password is case insensitive */
388
        BZERO(UcasePassword, sizeof(UcasePassword));
389
        for (i = 0; i < secret_len; i++)
390
                UcasePassword[i] = (u_char)toupper(secret[i]);
391
        DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
392
        DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
393
        ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
394
}
395
#endif
396
 
397
#endif /* MSCHAP_SUPPORT */
398
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.