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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP_130/] [src/] [netif/] [ppp/] [chpms.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 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
#include "lwip/opt.h"
70
 
71
#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
72
 
73
#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
74
 
75
#include "ppp.h"
76
#include "pppdebug.h"
77
 
78
#include "md4.h"
79
#ifndef USE_CRYPT
80
#include "des.h"
81
#endif
82
#include "chap.h"
83
#include "chpms.h"
84
 
85
 
86
/*************************/
87
/*** LOCAL DEFINITIONS ***/
88
/*************************/
89
 
90
 
91
/************************/
92
/*** LOCAL DATA TYPES ***/
93
/************************/
94
typedef struct {
95
    u_char LANManResp[24];
96
    u_char NTResp[24];
97
    u_char UseNT; /* If 1, ignore the LANMan response field */
98
} MS_ChapResponse;
99
/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
100
   in case this struct gets padded. */
101
 
102
 
103
 
104
/***********************************/
105
/*** LOCAL FUNCTION DECLARATIONS ***/
106
/***********************************/
107
 
108
/* XXX Don't know what to do with these. */
109
extern void setkey(const char *);
110
extern void encrypt(char *, int);
111
 
112
static void DesEncrypt (u_char *, u_char *, u_char *);
113
static void MakeKey (u_char *, u_char *);
114
 
115
#ifdef USE_CRYPT
116
static void Expand (u_char *, u_char *);
117
static void Collapse (u_char *, u_char *);
118
#endif
119
 
120
static void ChallengeResponse(
121
  u_char *challenge, /* IN   8 octets */
122
  u_char *pwHash,    /* IN  16 octets */
123
  u_char *response   /* OUT 24 octets */
124
);
125
static void ChapMS_NT(
126
  char *rchallenge,
127
  int rchallenge_len,
128
  char *secret,
129
  int secret_len,
130
  MS_ChapResponse *response
131
);
132
static u_char Get7Bits(
133
  u_char *input,
134
  int startBit
135
);
136
 
137
 
138
/***********************************/
139
/*** PUBLIC FUNCTION DEFINITIONS ***/
140
/***********************************/
141
void
142
ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len)
143
{
144
  MS_ChapResponse response;
145
#ifdef MSLANMAN
146
  extern int ms_lanman;
147
#endif
148
 
149
#if 0
150
  CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));
151
#endif
152
  BZERO(&response, sizeof(response));
153
 
154
  /* Calculate both always */
155
  ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
156
 
157
#ifdef MSLANMAN
158
  ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
159
 
160
  /* prefered method is set by option  */
161
  response.UseNT = !ms_lanman;
162
#else
163
  response.UseNT = 1;
164
#endif
165
 
166
  BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
167
  cstate->resp_length = MS_CHAP_RESPONSE_LEN;
168
}
169
 
170
 
171
/**********************************/
172
/*** LOCAL FUNCTION DEFINITIONS ***/
173
/**********************************/
174
static void
175
ChallengeResponse( u_char *challenge, /* IN   8 octets */
176
                   u_char *pwHash,    /* IN  16 octets */
177
                   u_char *response   /* OUT 24 octets */)
178
{
179
  char    ZPasswordHash[21];
180
 
181
  BZERO(ZPasswordHash, sizeof(ZPasswordHash));
182
  BCOPY(pwHash, ZPasswordHash, 16);
183
 
184
#if 0
185
  log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
186
#endif
187
 
188
  DesEncrypt(challenge, ZPasswordHash +  0, response + 0);
189
  DesEncrypt(challenge, ZPasswordHash +  7, response + 8);
190
  DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
191
 
192
#if 0
193
  log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
194
#endif
195
}
196
 
197
 
198
#ifdef USE_CRYPT
199
static void
200
DesEncrypt( u_char *clear, /* IN  8 octets */
201
            u_char *key,   /* IN  7 octets */
202
            u_char *cipher /* OUT 8 octets */)
203
{
204
  u_char des_key[8];
205
  u_char crypt_key[66];
206
  u_char des_input[66];
207
 
208
  MakeKey(key, des_key);
209
 
210
  Expand(des_key, crypt_key);
211
  setkey(crypt_key);
212
 
213
#if 0
214
  CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
215
             clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
216
#endif
217
 
218
  Expand(clear, des_input);
219
  encrypt(des_input, 0);
220
  Collapse(des_input, cipher);
221
 
222
#if 0
223
  CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
224
             cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
225
#endif
226
}
227
 
228
#else /* USE_CRYPT */
229
 
230
static void
231
DesEncrypt( u_char *clear, /* IN  8 octets */
232
            u_char *key,   /* IN  7 octets */
233
            u_char *cipher /* OUT 8 octets */)
234
{
235
  des_cblock    des_key;
236
  des_key_schedule  key_schedule;
237
 
238
  MakeKey(key, des_key);
239
 
240
  des_set_key(&des_key, key_schedule);
241
 
242
#if 0
243
  CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
244
             clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
245
#endif
246
 
247
  des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
248
 
249
#if 0
250
  CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
251
             cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
252
#endif
253
}
254
 
255
#endif /* USE_CRYPT */
256
 
257
 
258
static u_char
259
Get7Bits( u_char *input, int startBit)
260
{
261
  register unsigned int  word;
262
 
263
  word  = (unsigned)input[startBit / 8] << 8;
264
  word |= (unsigned)input[startBit / 8 + 1];
265
 
266
  word >>= 15 - (startBit % 8 + 7);
267
 
268
  return word & 0xFE;
269
}
270
 
271
#ifdef USE_CRYPT
272
 
273
/* in == 8-byte string (expanded version of the 56-bit key)
274
 * out == 64-byte string where each byte is either 1 or 0
275
 * Note that the low-order "bit" is always ignored by by setkey()
276
 */
277
static void
278
Expand(u_char *in, u_char *out)
279
{
280
  int j, c;
281
  int i;
282
 
283
  for(i = 0; i < 64; in++){
284
    c = *in;
285
    for(j = 7; j >= 0; j--) {
286
      *out++ = (c >> j) & 01;
287
    }
288
    i += 8;
289
  }
290
}
291
 
292
/* The inverse of Expand
293
 */
294
static void
295
Collapse(u_char *in, u_char *out)
296
{
297
  int j;
298
  int i;
299
  unsigned int c;
300
 
301
  for (i = 0; i < 64; i += 8, out++) {
302
    c = 0;
303
    for (j = 7; j >= 0; j--, in++) {
304
      c |= *in << j;
305
    }
306
    *out = c & 0xff;
307
  }
308
}
309
#endif
310
 
311
static void
312
MakeKey( u_char *key,    /* IN  56 bit DES key missing parity bits */
313
         u_char *des_key /* OUT 64 bit DES key with parity bits added */)
314
{
315
  des_key[0] = Get7Bits(key,  0);
316
  des_key[1] = Get7Bits(key,  7);
317
  des_key[2] = Get7Bits(key, 14);
318
  des_key[3] = Get7Bits(key, 21);
319
  des_key[4] = Get7Bits(key, 28);
320
  des_key[5] = Get7Bits(key, 35);
321
  des_key[6] = Get7Bits(key, 42);
322
  des_key[7] = Get7Bits(key, 49);
323
 
324
#ifndef USE_CRYPT
325
  des_set_odd_parity((des_cblock *)des_key);
326
#endif
327
 
328
#if 0
329
  CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
330
             key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
331
  CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
332
             des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
333
#endif
334
}
335
 
336
static void
337
ChapMS_NT( char *rchallenge,
338
           int rchallenge_len,
339
           char *secret,
340
           int secret_len,
341
           MS_ChapResponse *response)
342
{
343
  int      i;
344
  MDstruct  md4Context;
345
  u_char    unicodePassword[MAX_NT_PASSWORD * 2];
346
  static int  low_byte_first = -1;
347
 
348
  /* Initialize the Unicode version of the secret (== password). */
349
  /* This implicitly supports 8-bit ISO8859/1 characters. */
350
  BZERO(unicodePassword, sizeof(unicodePassword));
351
  for (i = 0; i < secret_len; i++) {
352
    unicodePassword[i * 2] = (u_char)secret[i];
353
  }
354
  MDbegin(&md4Context);
355
  MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8);  /* Unicode is 2 bytes/char, *8 for bit count */
356
 
357
  if (low_byte_first == -1) {
358
    low_byte_first = (htons((unsigned short int)1) != 1);
359
  }
360
  if (low_byte_first == 0) {
361
    MDreverse((u_long *)&md4Context);  /*  sfb 961105 */
362
  }
363
 
364
  MDupdate(&md4Context, NULL, 0);  /* Tell MD4 we're done */
365
 
366
  ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);
367
}
368
 
369
#ifdef MSLANMAN
370
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
371
 
372
static void
373
ChapMS_LANMan( char *rchallenge,
374
               int rchallenge_len,
375
               char *secret,
376
               int secret_len,
377
               MS_ChapResponse  *response)
378
{
379
  int      i;
380
  u_char    UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
381
  u_char    PasswordHash[16];
382
 
383
  /* LANMan password is case insensitive */
384
  BZERO(UcasePassword, sizeof(UcasePassword));
385
  for (i = 0; i < secret_len; i++) {
386
    UcasePassword[i] = (u_char)toupper(secret[i]);
387
  }
388
  DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
389
  DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
390
  ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
391
}
392
#endif
393
 
394
#endif /* MSCHAP_SUPPORT */
395
 
396
#endif /* PPP_SUPPORT */

powered by: WebSVN 2.1.0

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