mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-12-13 10:16:40 +08:00
Revert "Removed all stuff requiring encryption."
This reverts commit c268c5e07c046eb2cb8e5798a1f3eba7e0ad13c1. Conflicts: src/netif/ppp/auth.c src/netif/ppp/ppp.c src/netif/ppp/pppmy.c src/netif/ppp/pppmy.h
This commit is contained in:
parent
795d5807b5
commit
b896203dcf
@ -106,12 +106,17 @@
|
|||||||
#include "pppd.h"
|
#include "pppd.h"
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
#include "lcp.h"
|
#include "lcp.h"
|
||||||
|
#include "ccp.h"
|
||||||
|
#include "ecp.h"
|
||||||
#include "ipcp.h"
|
#include "ipcp.h"
|
||||||
#include "upap.h"
|
#include "upap.h"
|
||||||
#include "chap-new.h"
|
#include "chap-new.h"
|
||||||
#if EAP_SUPPORT
|
#if EAP_SUPPORT
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#endif /* EAP_SUPPORT */
|
#endif /* EAP_SUPPORT */
|
||||||
|
#if CBCP_SUPPORT
|
||||||
|
#include "cbcp.h"
|
||||||
|
#endif
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
@ -844,9 +849,48 @@ start_networks(unit)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct protent *protp;
|
struct protent *protp;
|
||||||
|
int ecp_required, mppe_required;
|
||||||
|
|
||||||
new_phase(PHASE_NETWORK);
|
new_phase(PHASE_NETWORK);
|
||||||
|
|
||||||
|
#ifdef HAVE_MULTILINK
|
||||||
|
if (multilink) {
|
||||||
|
if (mp_join_bundle()) {
|
||||||
|
if (multilink_join_hook)
|
||||||
|
(*multilink_join_hook)();
|
||||||
|
if (updetach && !nodetach)
|
||||||
|
detach();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MULTILINK */
|
||||||
|
|
||||||
|
#ifdef PPP_FILTER
|
||||||
|
if (!demand)
|
||||||
|
set_filters(&pass_filter, &active_filter);
|
||||||
|
#endif
|
||||||
|
/* Start CCP and ECP */
|
||||||
|
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||||
|
if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP)
|
||||||
|
&& protp->enabled_flag && protp->open != NULL)
|
||||||
|
(*protp->open)(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bring up other network protocols iff encryption is not required.
|
||||||
|
*/
|
||||||
|
ecp_required = ecp_gotoptions[unit].required;
|
||||||
|
mppe_required = ccp_gotoptions[unit].mppe;
|
||||||
|
if (!ecp_required && !mppe_required)
|
||||||
|
continue_networks(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
continue_networks(unit)
|
||||||
|
int unit;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct protent *protp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the "real" network protocols.
|
* Start the "real" network protocols.
|
||||||
*/
|
*/
|
||||||
@ -1292,10 +1336,15 @@ auth_reset(unit)
|
|||||||
ao->neg_eap = !ppp_settings.refuse_eap;
|
ao->neg_eap = !ppp_settings.refuse_eap;
|
||||||
#endif /* EAP_SUPPORT */
|
#endif /* EAP_SUPPORT */
|
||||||
|
|
||||||
if(!ppp_settings.refuse_chap) {
|
ao->chap_mdtype = MDTYPE_NONE;
|
||||||
ao->chap_mdtype = MDTYPE_MD5;
|
if(!ppp_settings.refuse_chap)
|
||||||
ao->neg_chap = 1;
|
ao->chap_mdtype |= MDTYPE_MD5;
|
||||||
}
|
if(!ppp_settings.refuse_mschap)
|
||||||
|
ao->chap_mdtype |= MDTYPE_MICROSOFT;
|
||||||
|
if(!ppp_settings.refuse_mschap_v2)
|
||||||
|
ao->chap_mdtype |= MDTYPE_MICROSOFT_V2;
|
||||||
|
|
||||||
|
ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ao->neg_upap = 0;
|
ao->neg_upap = 0;
|
||||||
@ -1306,6 +1355,7 @@ auth_reset(unit)
|
|||||||
ao->chap_mdtype = MDTYPE_NONE;
|
ao->chap_mdtype = MDTYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("neg_upap: %d\n", ao->neg_upap);
|
printf("neg_upap: %d\n", ao->neg_upap);
|
||||||
printf("neg_chap: %d\n", ao->neg_chap);
|
printf("neg_chap: %d\n", ao->neg_chap);
|
||||||
printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) );
|
printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) );
|
||||||
|
|||||||
26
src/netif/ppp/cbcp.h
Normal file
26
src/netif/ppp/cbcp.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef CBCP_H
|
||||||
|
#define CBCP_H
|
||||||
|
|
||||||
|
typedef struct cbcp_state {
|
||||||
|
int us_unit; /* Interface unit number */
|
||||||
|
u_char us_id; /* Current id */
|
||||||
|
u_char us_allowed;
|
||||||
|
int us_type;
|
||||||
|
char *us_number; /* Telefone Number */
|
||||||
|
} cbcp_state;
|
||||||
|
|
||||||
|
extern cbcp_state cbcp[];
|
||||||
|
|
||||||
|
extern struct protent cbcp_protent;
|
||||||
|
|
||||||
|
#define CBCP_MINLEN 4
|
||||||
|
|
||||||
|
#define CBCP_REQ 1
|
||||||
|
#define CBCP_RESP 2
|
||||||
|
#define CBCP_ACK 3
|
||||||
|
|
||||||
|
#define CB_CONF_NO 1
|
||||||
|
#define CB_CONF_USER 2
|
||||||
|
#define CB_CONF_ADMIN 3
|
||||||
|
#define CB_CONF_LIST 4
|
||||||
|
#endif
|
||||||
1680
src/netif/ppp/ccp.c
Normal file
1680
src/netif/ppp/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
52
src/netif/ppp/ccp.h
Normal file
52
src/netif/ppp/ccp.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ccp.h - Definitions for PPP Compression Control Protocol.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* 3. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by Paul Mackerras
|
||||||
|
* <paulus@samba.org>".
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct ccp_options {
|
||||||
|
bool bsd_compress; /* do BSD Compress? */
|
||||||
|
bool deflate; /* do Deflate? */
|
||||||
|
bool predictor_1; /* do Predictor-1? */
|
||||||
|
bool predictor_2; /* do Predictor-2? */
|
||||||
|
bool deflate_correct; /* use correct code for deflate? */
|
||||||
|
bool deflate_draft; /* use draft RFC code for deflate? */
|
||||||
|
bool mppe; /* do MPPE? */
|
||||||
|
u_short bsd_bits; /* # bits/code for BSD Compress */
|
||||||
|
u_short deflate_size; /* lg(window size) for Deflate */
|
||||||
|
short method; /* code for chosen compression method */
|
||||||
|
} ccp_options;
|
||||||
|
|
||||||
|
extern fsm ccp_fsm[];
|
||||||
|
extern ccp_options ccp_wantoptions[];
|
||||||
|
extern ccp_options ccp_gotoptions[];
|
||||||
|
extern ccp_options ccp_allowoptions[];
|
||||||
|
extern ccp_options ccp_hisoptions[];
|
||||||
|
|
||||||
|
extern struct protent ccp_protent;
|
||||||
943
src/netif/ppp/chap_ms.c
Normal file
943
src/netif/ppp/chap_ms.c
Normal file
@ -0,0 +1,943 @@
|
|||||||
|
/*
|
||||||
|
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
|
||||||
|
*
|
||||||
|
* Implemented LANManager type password response to MS-CHAP challenges.
|
||||||
|
* Now pppd provides both NT style and LANMan style blocks, and the
|
||||||
|
* prefered is set by option "ms-lanman". Default is to use NT.
|
||||||
|
* The hash text (StdText) was taken from Win95 RASAPI32.DLL.
|
||||||
|
*
|
||||||
|
* You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modifications by Frank Cusack, frank@google.com, March 2002.
|
||||||
|
*
|
||||||
|
* Implemented MS-CHAPv2 functionality, heavily based on sample
|
||||||
|
* implementation in RFC 2759. Implemented MPPE functionality,
|
||||||
|
* heavily based on sample implementation in RFC 3079.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 Google, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $"
|
||||||
|
|
||||||
|
#ifdef CHAPMS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "pppd.h"
|
||||||
|
#include "chap-new.h"
|
||||||
|
#include "chap_ms.h"
|
||||||
|
#include "md4.h"
|
||||||
|
#include "sha1.h"
|
||||||
|
#include "pppcrypt.h"
|
||||||
|
#include "magic.h"
|
||||||
|
|
||||||
|
static const char rcsid[] = RCSID;
|
||||||
|
|
||||||
|
|
||||||
|
static void ascii2unicode __P((char[], int, u_char[]));
|
||||||
|
static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE]));
|
||||||
|
static void ChallengeResponse __P((u_char *, u_char *, u_char[24]));
|
||||||
|
static void ChapMS_NT __P((u_char *, char *, int, u_char[24]));
|
||||||
|
static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int,
|
||||||
|
u_char[24]));
|
||||||
|
static void GenerateAuthenticatorResponsePlain
|
||||||
|
__P((char*, int, u_char[24], u_char[16], u_char *,
|
||||||
|
char *, u_char[41]));
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
static void ChapMS_LANMan __P((u_char *, char *, int, u_char *));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
static void Set_Start_Key __P((u_char *, char *, int));
|
||||||
|
static void SetMasterKeys __P((char *, int, u_char[24], int));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
bool ms_lanman = 0; /* Use LanMan password instead of NT */
|
||||||
|
/* Has meaning only with MS-CHAP challenges */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
u_char mppe_send_key[MPPE_MAX_KEY_LEN];
|
||||||
|
u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
|
||||||
|
int mppe_keys_set = 0; /* Have the MPPE keys been set? */
|
||||||
|
|
||||||
|
#ifdef DEBUGMPPEKEY
|
||||||
|
/* For MPPE debug */
|
||||||
|
/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */
|
||||||
|
static char *mschap_challenge = NULL;
|
||||||
|
/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */
|
||||||
|
static char *mschap2_peer_challenge = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "fsm.h" /* Need to poke MPPE options */
|
||||||
|
#include "ccp.h"
|
||||||
|
#include <net/ppp-comp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command-line options.
|
||||||
|
*/
|
||||||
|
static option_t chapms_option_list[] = {
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
{ "ms-lanman", o_bool, &ms_lanman,
|
||||||
|
"Use LanMan passwd when using MS-CHAP", 1 },
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUGMPPEKEY
|
||||||
|
{ "mschap-challenge", o_string, &mschap_challenge,
|
||||||
|
"specify CHAP challenge" },
|
||||||
|
{ "mschap2-peer-challenge", o_string, &mschap2_peer_challenge,
|
||||||
|
"specify CHAP peer challenge" },
|
||||||
|
#endif
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chapms_generate_challenge - generate a challenge for MS-CHAP.
|
||||||
|
* For MS-CHAP the challenge length is fixed at 8 bytes.
|
||||||
|
* The length goes in challenge[0] and the actual challenge starts
|
||||||
|
* at challenge[1].
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
chapms_generate_challenge(unsigned char *challenge)
|
||||||
|
{
|
||||||
|
*challenge++ = 8;
|
||||||
|
#ifdef DEBUGMPPEKEY
|
||||||
|
if (mschap_challenge && strlen(mschap_challenge) == 8)
|
||||||
|
memcpy(challenge, mschap_challenge, 8);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
random_bytes(challenge, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chapms2_generate_challenge(unsigned char *challenge)
|
||||||
|
{
|
||||||
|
*challenge++ = 16;
|
||||||
|
#ifdef DEBUGMPPEKEY
|
||||||
|
if (mschap_challenge && strlen(mschap_challenge) == 16)
|
||||||
|
memcpy(challenge, mschap_challenge, 16);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
random_bytes(challenge, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chapms_verify_response(int id, char *name,
|
||||||
|
unsigned char *secret, int secret_len,
|
||||||
|
unsigned char *challenge, unsigned char *response,
|
||||||
|
char *message, int message_space)
|
||||||
|
{
|
||||||
|
unsigned char md[MS_CHAP_RESPONSE_LEN];
|
||||||
|
int diff;
|
||||||
|
int challenge_len, response_len;
|
||||||
|
|
||||||
|
challenge_len = *challenge++; /* skip length, is 8 */
|
||||||
|
response_len = *response++;
|
||||||
|
if (response_len != MS_CHAP_RESPONSE_LEN)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
#ifndef MSLANMAN
|
||||||
|
if (!response[MS_CHAP_USENT]) {
|
||||||
|
/* Should really propagate this into the error packet. */
|
||||||
|
notice("Peer request for LANMAN auth not supported");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generate the expected response. */
|
||||||
|
ChapMS(challenge, (char *)secret, secret_len, md);
|
||||||
|
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
/* Determine which part of response to verify against */
|
||||||
|
if (!response[MS_CHAP_USENT])
|
||||||
|
diff = memcmp(&response[MS_CHAP_LANMANRESP],
|
||||||
|
&md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP],
|
||||||
|
MS_CHAP_NTRESP_LEN);
|
||||||
|
|
||||||
|
if (diff == 0) {
|
||||||
|
slprintf(message, message_space, "Access granted");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bad:
|
||||||
|
/* See comments below for MS-CHAP V2 */
|
||||||
|
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0",
|
||||||
|
challenge_len, challenge);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chapms2_verify_response(int id, char *name,
|
||||||
|
unsigned char *secret, int secret_len,
|
||||||
|
unsigned char *challenge, unsigned char *response,
|
||||||
|
char *message, int message_space)
|
||||||
|
{
|
||||||
|
unsigned char md[MS_CHAP2_RESPONSE_LEN];
|
||||||
|
char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
|
||||||
|
int challenge_len, response_len;
|
||||||
|
|
||||||
|
challenge_len = *challenge++; /* skip length, is 16 */
|
||||||
|
response_len = *response++;
|
||||||
|
if (response_len != MS_CHAP2_RESPONSE_LEN)
|
||||||
|
goto bad; /* not even the right length */
|
||||||
|
|
||||||
|
/* Generate the expected response and our mutual auth. */
|
||||||
|
ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
|
||||||
|
(char *)secret, secret_len, md,
|
||||||
|
(unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
|
||||||
|
|
||||||
|
/* compare MDs and send the appropriate status */
|
||||||
|
/*
|
||||||
|
* Per RFC 2759, success message must be formatted as
|
||||||
|
* "S=<auth_string> M=<message>"
|
||||||
|
* where
|
||||||
|
* <auth_string> is the Authenticator Response (mutual auth)
|
||||||
|
* <message> is a text message
|
||||||
|
*
|
||||||
|
* However, some versions of Windows (win98 tested) do not know
|
||||||
|
* about the M=<message> part (required per RFC 2759) and flag
|
||||||
|
* it as an error (reported incorrectly as an encryption error
|
||||||
|
* to the user). Since the RFC requires it, and it can be
|
||||||
|
* useful information, we supply it if the peer is a conforming
|
||||||
|
* system. Luckily (?), win98 sets the Flags field to 0x04
|
||||||
|
* (contrary to RFC requirements) so we can use that to
|
||||||
|
* distinguish between conforming and non-conforming systems.
|
||||||
|
*
|
||||||
|
* Special thanks to Alex Swiridov <say@real.kharkov.ua> for
|
||||||
|
* help debugging this.
|
||||||
|
*/
|
||||||
|
if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
|
||||||
|
MS_CHAP2_NTRESP_LEN) == 0) {
|
||||||
|
if (response[MS_CHAP2_FLAGS])
|
||||||
|
slprintf(message, message_space, "S=%s", saresponse);
|
||||||
|
else
|
||||||
|
slprintf(message, message_space, "S=%s M=%s",
|
||||||
|
saresponse, "Access granted");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bad:
|
||||||
|
/*
|
||||||
|
* Failure message must be formatted as
|
||||||
|
* "E=e R=r C=c V=v M=m"
|
||||||
|
* where
|
||||||
|
* e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
|
||||||
|
* r = retry (we use 1, ok to retry)
|
||||||
|
* c = challenge to use for next response, we reuse previous
|
||||||
|
* v = Change Password version supported, we use 0
|
||||||
|
* m = text message
|
||||||
|
*
|
||||||
|
* The M=m part is only for MS-CHAPv2. Neither win2k nor
|
||||||
|
* win98 (others untested) display the message to the user anyway.
|
||||||
|
* They also both ignore the E=e code.
|
||||||
|
*
|
||||||
|
* Note that it's safe to reuse the same challenge as we don't
|
||||||
|
* actually accept another response based on the error message
|
||||||
|
* (and no clients try to resend a response anyway).
|
||||||
|
*
|
||||||
|
* Basically, this whole bit is useless code, even the small
|
||||||
|
* implementation here is only because of overspecification.
|
||||||
|
*/
|
||||||
|
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
|
||||||
|
challenge_len, challenge, "Access denied");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chapms_make_response(unsigned char *response, int id, char *our_name,
|
||||||
|
unsigned char *challenge, char *secret, int secret_len,
|
||||||
|
unsigned char *private)
|
||||||
|
{
|
||||||
|
challenge++; /* skip length, should be 8 */
|
||||||
|
*response++ = MS_CHAP_RESPONSE_LEN;
|
||||||
|
ChapMS(challenge, secret, secret_len, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chapms2_make_response(unsigned char *response, int id, char *our_name,
|
||||||
|
unsigned char *challenge, char *secret, int secret_len,
|
||||||
|
unsigned char *private)
|
||||||
|
{
|
||||||
|
challenge++; /* skip length, should be 16 */
|
||||||
|
*response++ = MS_CHAP2_RESPONSE_LEN;
|
||||||
|
ChapMS2(challenge,
|
||||||
|
#ifdef DEBUGMPPEKEY
|
||||||
|
mschap2_peer_challenge,
|
||||||
|
#else
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
our_name, secret, secret_len, response, private,
|
||||||
|
MS_CHAP2_AUTHENTICATEE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chapms2_check_success(unsigned char *msg, int len, unsigned char *private)
|
||||||
|
{
|
||||||
|
if ((len < MS_AUTH_RESPONSE_LENGTH + 2) ||
|
||||||
|
strncmp((char *)msg, "S=", 2) != 0) {
|
||||||
|
/* Packet does not start with "S=" */
|
||||||
|
error("MS-CHAPv2 Success packet is badly formed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
msg += 2;
|
||||||
|
len -= 2;
|
||||||
|
if (len < MS_AUTH_RESPONSE_LENGTH
|
||||||
|
|| memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) {
|
||||||
|
/* Authenticator Response did not match expected. */
|
||||||
|
error("MS-CHAPv2 mutual authentication failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Authenticator Response matches. */
|
||||||
|
msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */
|
||||||
|
len -= MS_AUTH_RESPONSE_LENGTH;
|
||||||
|
if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) {
|
||||||
|
msg += 3; /* Eat the delimiter */
|
||||||
|
} else if (len) {
|
||||||
|
/* Packet has extra text which does not begin " M=" */
|
||||||
|
error("MS-CHAPv2 Success packet is badly formed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chapms_handle_failure(unsigned char *inp, int len)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char *p, *msg;
|
||||||
|
|
||||||
|
/* We want a null-terminated string for strxxx(). */
|
||||||
|
msg = malloc(len + 1);
|
||||||
|
if (!msg) {
|
||||||
|
notice("Out of memory in chapms_handle_failure");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BCOPY(inp, msg, len);
|
||||||
|
msg[len] = 0;
|
||||||
|
p = msg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deal with MS-CHAP formatted failure messages; just print the
|
||||||
|
* M=<message> part (if any). For MS-CHAP we're not really supposed
|
||||||
|
* to use M=<message>, but it shouldn't hurt. See
|
||||||
|
* chapms[2]_verify_response.
|
||||||
|
*/
|
||||||
|
if (!strncmp(p, "E=", 2))
|
||||||
|
err = strtol(p+2, NULL, 10); /* Remember the error code. */
|
||||||
|
else
|
||||||
|
goto print_msg; /* Message is badly formatted. */
|
||||||
|
|
||||||
|
if (len && ((p = strstr(p, " M=")) != NULL)) {
|
||||||
|
/* M=<message> field found. */
|
||||||
|
p += 3;
|
||||||
|
} else {
|
||||||
|
/* No M=<message>; use the error code. */
|
||||||
|
switch (err) {
|
||||||
|
case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS:
|
||||||
|
p = "E=646 Restricted logon hours";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MS_CHAP_ERROR_ACCT_DISABLED:
|
||||||
|
p = "E=647 Account disabled";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MS_CHAP_ERROR_PASSWD_EXPIRED:
|
||||||
|
p = "E=648 Password expired";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MS_CHAP_ERROR_NO_DIALIN_PERMISSION:
|
||||||
|
p = "E=649 No dialin permission";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MS_CHAP_ERROR_AUTHENTICATION_FAILURE:
|
||||||
|
p = "E=691 Authentication failure";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MS_CHAP_ERROR_CHANGING_PASSWORD:
|
||||||
|
/* Should never see this, we don't support Change Password. */
|
||||||
|
p = "E=709 Error changing password";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
free(msg);
|
||||||
|
error("Unknown MS-CHAP authentication failure: %.*v",
|
||||||
|
len, inp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_msg:
|
||||||
|
if (p != NULL)
|
||||||
|
error("MS-CHAP authentication failed: %v", p);
|
||||||
|
free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ChallengeResponse(u_char *challenge,
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE],
|
||||||
|
u_char response[24])
|
||||||
|
{
|
||||||
|
u_char ZPasswordHash[21];
|
||||||
|
|
||||||
|
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||||
|
BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dbglog("ChallengeResponse - ZPasswordHash %.*B",
|
||||||
|
sizeof(ZPasswordHash), ZPasswordHash);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void) DesSetkey(ZPasswordHash + 0);
|
||||||
|
DesEncrypt(challenge, response + 0);
|
||||||
|
(void) DesSetkey(ZPasswordHash + 7);
|
||||||
|
DesEncrypt(challenge, response + 8);
|
||||||
|
(void) DesSetkey(ZPasswordHash + 14);
|
||||||
|
DesEncrypt(challenge, response + 16);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dbglog("ChallengeResponse - response %.24B", response);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
|
||||||
|
char *username, u_char Challenge[8])
|
||||||
|
|
||||||
|
{
|
||||||
|
SHA1_CTX sha1Context;
|
||||||
|
u_char sha1Hash[SHA1_SIGNATURE_SIZE];
|
||||||
|
char *user;
|
||||||
|
|
||||||
|
/* remove domain from "domain\username" */
|
||||||
|
if ((user = strrchr(username, '\\')) != NULL)
|
||||||
|
++user;
|
||||||
|
else
|
||||||
|
user = username;
|
||||||
|
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, PeerChallenge, 16);
|
||||||
|
SHA1_Update(&sha1Context, rchallenge, 16);
|
||||||
|
SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user));
|
||||||
|
SHA1_Final(sha1Hash, &sha1Context);
|
||||||
|
|
||||||
|
BCOPY(sha1Hash, Challenge, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the ASCII version of the password to Unicode.
|
||||||
|
* This implicitly supports 8-bit ISO8859/1 characters.
|
||||||
|
* This gives us the little-endian representation, which
|
||||||
|
* is assumed by all M$ CHAP RFCs. (Unicode byte ordering
|
||||||
|
* is machine-dependent.)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ascii2unicode(char ascii[], int ascii_len, u_char unicode[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BZERO(unicode, ascii_len * 2);
|
||||||
|
for (i = 0; i < ascii_len; i++)
|
||||||
|
unicode[i * 2] = (u_char) ascii[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
|
||||||
|
{
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
/* NetBSD uses the libc md4 routines which take bytes instead of bits */
|
||||||
|
int mdlen = secret_len;
|
||||||
|
#else
|
||||||
|
int mdlen = secret_len * 8;
|
||||||
|
#endif
|
||||||
|
MD4_CTX md4Context;
|
||||||
|
|
||||||
|
MD4Init(&md4Context);
|
||||||
|
/* MD4Update can take at most 64 bytes at a time */
|
||||||
|
while (mdlen > 512) {
|
||||||
|
MD4Update(&md4Context, secret, 512);
|
||||||
|
secret += 64;
|
||||||
|
mdlen -= 512;
|
||||||
|
}
|
||||||
|
MD4Update(&md4Context, secret, mdlen);
|
||||||
|
MD4Final(hash, &md4Context);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ChapMS_NT(u_char *rchallenge, char *secret, int secret_len,
|
||||||
|
u_char NTResponse[24])
|
||||||
|
{
|
||||||
|
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
|
||||||
|
/* Hash the Unicode version of the secret (== password). */
|
||||||
|
ascii2unicode(secret, secret_len, unicodePassword);
|
||||||
|
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||||
|
|
||||||
|
ChallengeResponse(rchallenge, PasswordHash, NTResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username,
|
||||||
|
char *secret, int secret_len, u_char NTResponse[24])
|
||||||
|
{
|
||||||
|
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
u_char Challenge[8];
|
||||||
|
|
||||||
|
ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
|
||||||
|
|
||||||
|
/* Hash the Unicode version of the secret (== password). */
|
||||||
|
ascii2unicode(secret, secret_len, unicodePassword);
|
||||||
|
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||||
|
|
||||||
|
ChallengeResponse(Challenge, PasswordHash, NTResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
|
||||||
|
unsigned char *response)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
|
||||||
|
/* LANMan password is case insensitive */
|
||||||
|
BZERO(UcasePassword, sizeof(UcasePassword));
|
||||||
|
for (i = 0; i < secret_len; i++)
|
||||||
|
UcasePassword[i] = (u_char)toupper(secret[i]);
|
||||||
|
(void) DesSetkey(UcasePassword + 0);
|
||||||
|
DesEncrypt( StdText, PasswordHash + 0 );
|
||||||
|
(void) DesSetkey(UcasePassword + 7);
|
||||||
|
DesEncrypt( StdText, PasswordHash + 8 );
|
||||||
|
ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||||
|
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||||
|
u_char *rchallenge, char *username,
|
||||||
|
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* "Magic" constants used in response generation, from RFC 2759.
|
||||||
|
*/
|
||||||
|
u_char Magic1[39] = /* "Magic server to client signing constant" */
|
||||||
|
{ 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
|
||||||
|
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
|
||||||
|
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
|
||||||
|
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 };
|
||||||
|
u_char Magic2[41] = /* "Pad to make it do more than one iteration" */
|
||||||
|
{ 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
|
||||||
|
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
|
||||||
|
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
|
||||||
|
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
|
||||||
|
0x6E };
|
||||||
|
|
||||||
|
int i;
|
||||||
|
SHA1_CTX sha1Context;
|
||||||
|
u_char Digest[SHA1_SIGNATURE_SIZE];
|
||||||
|
u_char Challenge[8];
|
||||||
|
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||||
|
SHA1_Update(&sha1Context, NTResponse, 24);
|
||||||
|
SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
|
||||||
|
SHA1_Final(Digest, &sha1Context);
|
||||||
|
|
||||||
|
ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
|
||||||
|
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, Digest, sizeof(Digest));
|
||||||
|
SHA1_Update(&sha1Context, Challenge, sizeof(Challenge));
|
||||||
|
SHA1_Update(&sha1Context, Magic2, sizeof(Magic2));
|
||||||
|
SHA1_Final(Digest, &sha1Context);
|
||||||
|
|
||||||
|
/* Convert to ASCII hex string. */
|
||||||
|
for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++)
|
||||||
|
sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
GenerateAuthenticatorResponsePlain
|
||||||
|
(char *secret, int secret_len,
|
||||||
|
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||||
|
u_char *rchallenge, char *username,
|
||||||
|
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
|
||||||
|
{
|
||||||
|
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||||
|
|
||||||
|
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||||
|
ascii2unicode(secret, secret_len, unicodePassword);
|
||||||
|
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||||
|
NTPasswordHash(PasswordHash, sizeof(PasswordHash),
|
||||||
|
PasswordHashHash);
|
||||||
|
|
||||||
|
GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge,
|
||||||
|
rchallenge, username, authResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
/*
|
||||||
|
* Set mppe_xxxx_key from the NTPasswordHashHash.
|
||||||
|
* RFC 2548 (RADIUS support) requires us to export this function (ugh).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE])
|
||||||
|
{
|
||||||
|
SHA1_CTX sha1Context;
|
||||||
|
u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||||
|
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||||
|
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||||
|
SHA1_Update(&sha1Context, rchallenge, 8);
|
||||||
|
SHA1_Final(Digest, &sha1Context);
|
||||||
|
|
||||||
|
/* Same key in both directions. */
|
||||||
|
BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
|
||||||
|
BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
|
||||||
|
|
||||||
|
mppe_keys_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Set_Start_Key(u_char *rchallenge, char *secret, int secret_len)
|
||||||
|
{
|
||||||
|
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||||
|
|
||||||
|
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||||
|
ascii2unicode(secret, secret_len, unicodePassword);
|
||||||
|
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||||
|
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
|
||||||
|
|
||||||
|
mppe_set_keys(rchallenge, PasswordHashHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
|
||||||
|
*
|
||||||
|
* This helper function used in the Winbind module, which gets the
|
||||||
|
* NTHashHash from the server.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||||
|
u_char NTResponse[24], int IsServer)
|
||||||
|
{
|
||||||
|
SHA1_CTX sha1Context;
|
||||||
|
u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||||
|
u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||||
|
|
||||||
|
u_char SHApad1[40] =
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
u_char SHApad2[40] =
|
||||||
|
{ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||||
|
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||||
|
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||||
|
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
|
||||||
|
|
||||||
|
/* "This is the MPPE Master Key" */
|
||||||
|
u_char Magic1[27] =
|
||||||
|
{ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
|
||||||
|
0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
|
||||||
|
0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };
|
||||||
|
/* "On the client side, this is the send key; "
|
||||||
|
"on the server side, it is the receive key." */
|
||||||
|
u_char Magic2[84] =
|
||||||
|
{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||||
|
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||||
|
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
|
||||||
|
0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
|
||||||
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
|
||||||
|
0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||||
|
0x6b, 0x65, 0x79, 0x2e };
|
||||||
|
/* "On the client side, this is the receive key; "
|
||||||
|
"on the server side, it is the send key." */
|
||||||
|
u_char Magic3[84] =
|
||||||
|
{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||||
|
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||||
|
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||||
|
0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
|
||||||
|
0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
|
||||||
|
0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
|
||||||
|
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
|
||||||
|
0x6b, 0x65, 0x79, 0x2e };
|
||||||
|
u_char *s;
|
||||||
|
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||||
|
SHA1_Update(&sha1Context, NTResponse, 24);
|
||||||
|
SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
|
||||||
|
SHA1_Final(MasterKey, &sha1Context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate send key
|
||||||
|
*/
|
||||||
|
if (IsServer)
|
||||||
|
s = Magic3;
|
||||||
|
else
|
||||||
|
s = Magic2;
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, MasterKey, 16);
|
||||||
|
SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
|
||||||
|
SHA1_Update(&sha1Context, s, 84);
|
||||||
|
SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
|
||||||
|
SHA1_Final(Digest, &sha1Context);
|
||||||
|
|
||||||
|
BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate recv key
|
||||||
|
*/
|
||||||
|
if (IsServer)
|
||||||
|
s = Magic2;
|
||||||
|
else
|
||||||
|
s = Magic3;
|
||||||
|
SHA1_Init(&sha1Context);
|
||||||
|
SHA1_Update(&sha1Context, MasterKey, 16);
|
||||||
|
SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
|
||||||
|
SHA1_Update(&sha1Context, s, 84);
|
||||||
|
SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
|
||||||
|
SHA1_Final(Digest, &sha1Context);
|
||||||
|
|
||||||
|
BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
|
||||||
|
|
||||||
|
mppe_keys_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer)
|
||||||
|
{
|
||||||
|
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||||
|
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||||
|
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||||
|
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||||
|
ascii2unicode(secret, secret_len, unicodePassword);
|
||||||
|
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||||
|
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
|
||||||
|
mppe_set_keys2(PasswordHashHash, NTResponse, IsServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MPPE */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ChapMS(u_char *rchallenge, char *secret, int secret_len,
|
||||||
|
unsigned char *response)
|
||||||
|
{
|
||||||
|
BZERO(response, MS_CHAP_RESPONSE_LEN);
|
||||||
|
|
||||||
|
ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]);
|
||||||
|
|
||||||
|
#ifdef MSLANMAN
|
||||||
|
ChapMS_LANMan(rchallenge, secret, secret_len,
|
||||||
|
&response[MS_CHAP_LANMANRESP]);
|
||||||
|
|
||||||
|
/* preferred method is set by option */
|
||||||
|
response[MS_CHAP_USENT] = !ms_lanman;
|
||||||
|
#else
|
||||||
|
response[MS_CHAP_USENT] = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
Set_Start_Key(rchallenge, secret, secret_len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If PeerChallenge is NULL, one is generated and the PeerChallenge
|
||||||
|
* field of response is filled in. Call this way when generating a response.
|
||||||
|
* If PeerChallenge is supplied, it is copied into the PeerChallenge field.
|
||||||
|
* Call this way when verifying a response (or debugging).
|
||||||
|
* Do not call with PeerChallenge = response.
|
||||||
|
*
|
||||||
|
* The PeerChallenge field of response is then used for calculation of the
|
||||||
|
* Authenticator Response.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ChapMS2(u_char *rchallenge, u_char *PeerChallenge,
|
||||||
|
char *user, char *secret, int secret_len, unsigned char *response,
|
||||||
|
u_char authResponse[], int authenticator)
|
||||||
|
{
|
||||||
|
/* ARGSUSED */
|
||||||
|
u_char *p = &response[MS_CHAP2_PEER_CHALLENGE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BZERO(response, MS_CHAP2_RESPONSE_LEN);
|
||||||
|
|
||||||
|
/* Generate the Peer-Challenge if requested, or copy it if supplied. */
|
||||||
|
if (!PeerChallenge)
|
||||||
|
for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++)
|
||||||
|
*p++ = (u_char) (drand48() * 0xff);
|
||||||
|
else
|
||||||
|
BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE],
|
||||||
|
MS_CHAP2_PEER_CHAL_LEN);
|
||||||
|
|
||||||
|
/* Generate the NT-Response */
|
||||||
|
ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user,
|
||||||
|
secret, secret_len, &response[MS_CHAP2_NTRESP]);
|
||||||
|
|
||||||
|
/* Generate the Authenticator Response. */
|
||||||
|
GenerateAuthenticatorResponsePlain(secret, secret_len,
|
||||||
|
&response[MS_CHAP2_NTRESP],
|
||||||
|
&response[MS_CHAP2_PEER_CHALLENGE],
|
||||||
|
rchallenge, user, authResponse);
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
SetMasterKeys(secret, secret_len,
|
||||||
|
&response[MS_CHAP2_NTRESP], authenticator);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
/*
|
||||||
|
* Set MPPE options from plugins.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
set_mppe_enc_types(int policy, int types)
|
||||||
|
{
|
||||||
|
/* Early exit for unknown policies. */
|
||||||
|
if (policy != MPPE_ENC_POL_ENC_ALLOWED ||
|
||||||
|
policy != MPPE_ENC_POL_ENC_REQUIRED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Don't modify MPPE if it's optional and wasn't already configured. */
|
||||||
|
if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable undesirable encryption types. Note that we don't ENABLE
|
||||||
|
* any encryption types, to avoid overriding manual configuration.
|
||||||
|
*/
|
||||||
|
switch(types) {
|
||||||
|
case MPPE_ENC_TYPES_RC4_40:
|
||||||
|
ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */
|
||||||
|
break;
|
||||||
|
case MPPE_ENC_TYPES_RC4_128:
|
||||||
|
ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MPPE */
|
||||||
|
|
||||||
|
static struct chap_digest_type chapms_digest = {
|
||||||
|
CHAP_MICROSOFT, /* code */
|
||||||
|
chapms_generate_challenge,
|
||||||
|
chapms_verify_response,
|
||||||
|
chapms_make_response,
|
||||||
|
NULL, /* check_success */
|
||||||
|
chapms_handle_failure,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct chap_digest_type chapms2_digest = {
|
||||||
|
CHAP_MICROSOFT_V2, /* code */
|
||||||
|
chapms2_generate_challenge,
|
||||||
|
chapms2_verify_response,
|
||||||
|
chapms2_make_response,
|
||||||
|
chapms2_check_success,
|
||||||
|
chapms_handle_failure,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
chapms_init(void)
|
||||||
|
{
|
||||||
|
chap_register_digest(&chapms_digest);
|
||||||
|
chap_register_digest(&chapms2_digest);
|
||||||
|
add_options(chapms_option_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CHAPMS */
|
||||||
109
src/netif/ppp/chap_ms.h
Normal file
109
src/netif/ppp/chap_ms.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* chap_ms.h - Challenge Handshake Authentication Protocol definitions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CHAPMS_INCLUDE__
|
||||||
|
|
||||||
|
#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
|
||||||
|
#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */
|
||||||
|
|
||||||
|
#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
|
||||||
|
#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */
|
||||||
|
#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */
|
||||||
|
/* as ASCII */
|
||||||
|
|
||||||
|
/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */
|
||||||
|
#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646
|
||||||
|
#define MS_CHAP_ERROR_ACCT_DISABLED 647
|
||||||
|
#define MS_CHAP_ERROR_PASSWD_EXPIRED 648
|
||||||
|
#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649
|
||||||
|
#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691
|
||||||
|
#define MS_CHAP_ERROR_CHANGING_PASSWORD 709
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Offsets within the response field for MS-CHAP
|
||||||
|
*/
|
||||||
|
#define MS_CHAP_LANMANRESP 0
|
||||||
|
#define MS_CHAP_LANMANRESP_LEN 24
|
||||||
|
#define MS_CHAP_NTRESP 24
|
||||||
|
#define MS_CHAP_NTRESP_LEN 24
|
||||||
|
#define MS_CHAP_USENT 48
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Offsets within the response field for MS-CHAP2
|
||||||
|
*/
|
||||||
|
#define MS_CHAP2_PEER_CHALLENGE 0
|
||||||
|
#define MS_CHAP2_PEER_CHAL_LEN 16
|
||||||
|
#define MS_CHAP2_RESERVED_LEN 8
|
||||||
|
#define MS_CHAP2_NTRESP 24
|
||||||
|
#define MS_CHAP2_NTRESP_LEN 24
|
||||||
|
#define MS_CHAP2_FLAGS 48
|
||||||
|
|
||||||
|
#ifdef MPPE
|
||||||
|
#include "mppe.h" /* MPPE_MAX_KEY_LEN */
|
||||||
|
extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
|
||||||
|
extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
|
||||||
|
extern int mppe_keys_set;
|
||||||
|
|
||||||
|
/* These values are the RADIUS attribute values--see RFC 2548. */
|
||||||
|
#define MPPE_ENC_POL_ENC_ALLOWED 1
|
||||||
|
#define MPPE_ENC_POL_ENC_REQUIRED 2
|
||||||
|
#define MPPE_ENC_TYPES_RC4_40 2
|
||||||
|
#define MPPE_ENC_TYPES_RC4_128 4
|
||||||
|
|
||||||
|
/* used by plugins (using above values) */
|
||||||
|
extern void set_mppe_enc_types(int, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */
|
||||||
|
#define MS_CHAP2_AUTHENTICATEE 0
|
||||||
|
#define MS_CHAP2_AUTHENTICATOR 1
|
||||||
|
|
||||||
|
void ChapMS __P((u_char *, char *, int, u_char *));
|
||||||
|
void ChapMS2 __P((u_char *, u_char *, char *, char *, int,
|
||||||
|
u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int));
|
||||||
|
#ifdef MPPE
|
||||||
|
void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE]));
|
||||||
|
void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||||
|
u_char NTResponse[24], int IsServer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8]));
|
||||||
|
|
||||||
|
void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||||
|
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||||
|
u_char *rchallenge, char *username,
|
||||||
|
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]);
|
||||||
|
|
||||||
|
void chapms_init(void);
|
||||||
|
|
||||||
|
#define __CHAPMS_INCLUDE__
|
||||||
|
#endif /* __CHAPMS_INCLUDE__ */
|
||||||
530
src/netif/ppp/des.c
Normal file
530
src/netif/ppp/des.c
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FreeSec: libcrypt
|
||||||
|
*
|
||||||
|
* Copyright (c) 1994 David Burren
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 4. Neither the name of the author nor the names of other contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||||
|
* by David Burren <davidb@werj.com.au>.
|
||||||
|
*
|
||||||
|
* An excellent reference on the underlying algorithm (and related
|
||||||
|
* algorithms) is:
|
||||||
|
*
|
||||||
|
* B. Schneier, Applied Cryptography: protocols, algorithms,
|
||||||
|
* and source code in C, John Wiley & Sons, 1994.
|
||||||
|
*
|
||||||
|
* Note that in that book's description of DES the lookups for the initial,
|
||||||
|
* pbox, and final permutations are inverted (this has been brought to the
|
||||||
|
* attention of the author). A list of errata for this book has been
|
||||||
|
* posted to the sci.crypt newsgroup by the author and is available for FTP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
/* FIXME: don't build if not necessary */
|
||||||
|
|
||||||
|
#include "lwip/def.h"
|
||||||
|
|
||||||
|
static const u_char IP[64] = {
|
||||||
|
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
|
||||||
|
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
|
||||||
|
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
|
||||||
|
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static u_char inv_key_perm[64];
|
||||||
|
static u_char u_key_perm[56];
|
||||||
|
static u_char const key_perm[56] = {
|
||||||
|
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
|
||||||
|
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
|
||||||
|
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
|
||||||
|
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u_char key_shifts[16] = {
|
||||||
|
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static u_char inv_comp_perm[56];
|
||||||
|
static const u_char comp_perm[48] = {
|
||||||
|
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
|
||||||
|
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
|
||||||
|
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
|
||||||
|
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No E box is used, as it's replaced by some ANDs, shifts, and ORs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static u_char u_sbox[8][64];
|
||||||
|
static const u_char sbox[8][64] = {
|
||||||
|
{
|
||||||
|
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||||
|
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||||||
|
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||||
|
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||||
|
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||||||
|
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||||
|
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||||
|
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||||||
|
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||||
|
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||||
|
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||||||
|
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||||
|
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||||
|
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||||||
|
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||||
|
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||||
|
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||||||
|
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||||
|
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||||
|
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||||||
|
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||||
|
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||||
|
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||||||
|
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||||
|
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static u_char un_pbox[32];
|
||||||
|
static const u_char pbox[32] = {
|
||||||
|
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
|
||||||
|
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
|
||||||
|
};
|
||||||
|
|
||||||
|
const u_int32_t _des_bits32[32] =
|
||||||
|
{
|
||||||
|
0x80000000, 0x40000000, 0x20000000, 0x10000000,
|
||||||
|
0x08000000, 0x04000000, 0x02000000, 0x01000000,
|
||||||
|
0x00800000, 0x00400000, 0x00200000, 0x00100000,
|
||||||
|
0x00080000, 0x00040000, 0x00020000, 0x00010000,
|
||||||
|
0x00008000, 0x00004000, 0x00002000, 0x00001000,
|
||||||
|
0x00000800, 0x00000400, 0x00000200, 0x00000100,
|
||||||
|
0x00000080, 0x00000040, 0x00000020, 0x00000010,
|
||||||
|
0x00000008, 0x00000004, 0x00000002, 0x00000001
|
||||||
|
};
|
||||||
|
|
||||||
|
const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||||
|
|
||||||
|
static const u_int32_t *bits28, *bits24;
|
||||||
|
static u_char init_perm[64], final_perm[64];
|
||||||
|
static u_int32_t en_keysl[16], en_keysr[16];
|
||||||
|
static u_int32_t de_keysl[16], de_keysr[16];
|
||||||
|
int _des_initialised = 0;
|
||||||
|
static u_char m_sbox[4][4096];
|
||||||
|
static u_int32_t psbox[4][256];
|
||||||
|
static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
|
||||||
|
static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
|
||||||
|
static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
|
||||||
|
static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
|
||||||
|
static u_int32_t old_rawkey0, old_rawkey1;
|
||||||
|
|
||||||
|
void
|
||||||
|
_des_init(void)
|
||||||
|
{
|
||||||
|
int i, j, b, k, inbit, obit;
|
||||||
|
u_int32_t *p, *il, *ir, *fl, *fr;
|
||||||
|
|
||||||
|
old_rawkey0 = old_rawkey1 = 0;
|
||||||
|
bits24 = (bits28 = _des_bits32 + 4) + 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the S-boxes, reordering the input bits.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
for (j = 0; j < 64; j++) {
|
||||||
|
b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
|
||||||
|
u_sbox[i][j] = sbox[i][b];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the inverted S-boxes into 4 arrays of 8 bits.
|
||||||
|
* Each will handle 12 bits of the S-box input.
|
||||||
|
*/
|
||||||
|
for (b = 0; b < 4; b++)
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
for (j = 0; j < 64; j++)
|
||||||
|
m_sbox[b][(i << 6) | j] =
|
||||||
|
(u_sbox[(b << 1)][i] << 4) |
|
||||||
|
u_sbox[(b << 1) + 1][j];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the initial & final permutations into a useful form, and
|
||||||
|
* initialise the inverted key permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
init_perm[final_perm[i] = IP[i] - 1] = i;
|
||||||
|
inv_key_perm[i] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the key permutation and initialise the inverted key
|
||||||
|
* compression permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 56; i++) {
|
||||||
|
u_key_perm[i] = key_perm[i] - 1;
|
||||||
|
inv_key_perm[key_perm[i] - 1] = i;
|
||||||
|
inv_comp_perm[i] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the key compression permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 48; i++) {
|
||||||
|
inv_comp_perm[comp_perm[i] - 1] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the OR-mask arrays for the initial and final permutations,
|
||||||
|
* and for the key initial and compression permutations.
|
||||||
|
*/
|
||||||
|
for (k = 0; k < 8; k++) {
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
*(il = &ip_maskl[k][i]) = 0;
|
||||||
|
*(ir = &ip_maskr[k][i]) = 0;
|
||||||
|
*(fl = &fp_maskl[k][i]) = 0;
|
||||||
|
*(fr = &fp_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
inbit = 8 * k + j;
|
||||||
|
if (i & _des_bits8[j]) {
|
||||||
|
if ((obit = init_perm[inbit]) < 32)
|
||||||
|
*il |= _des_bits32[obit];
|
||||||
|
else
|
||||||
|
*ir |= _des_bits32[obit-32];
|
||||||
|
if ((obit = final_perm[inbit]) < 32)
|
||||||
|
*fl |= _des_bits32[obit];
|
||||||
|
else
|
||||||
|
*fr |= _des_bits32[obit - 32];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 128; i++) {
|
||||||
|
*(il = &key_perm_maskl[k][i]) = 0;
|
||||||
|
*(ir = &key_perm_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 7; j++) {
|
||||||
|
inbit = 8 * k + j;
|
||||||
|
if (i & _des_bits8[j + 1]) {
|
||||||
|
if ((obit = inv_key_perm[inbit]) == 255)
|
||||||
|
continue;
|
||||||
|
if (obit < 28)
|
||||||
|
*il |= bits28[obit];
|
||||||
|
else
|
||||||
|
*ir |= bits28[obit - 28];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(il = &comp_maskl[k][i]) = 0;
|
||||||
|
*(ir = &comp_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 7; j++) {
|
||||||
|
inbit = 7 * k + j;
|
||||||
|
if (i & _des_bits8[j + 1]) {
|
||||||
|
if ((obit=inv_comp_perm[inbit]) == 255)
|
||||||
|
continue;
|
||||||
|
if (obit < 24)
|
||||||
|
*il |= bits24[obit];
|
||||||
|
else
|
||||||
|
*ir |= bits24[obit - 24];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the P-box permutation, and convert into OR-masks for
|
||||||
|
* handling the output of the S-box arrays setup above.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
un_pbox[pbox[i] - 1] = i;
|
||||||
|
|
||||||
|
for (b = 0; b < 4; b++)
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
*(p = &psbox[b][i]) = 0;
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if (i & _des_bits8[j])
|
||||||
|
*p |= _des_bits32[un_pbox[8 * b + j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_des_initialised = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
des_setkey(const char *key)
|
||||||
|
{
|
||||||
|
u_int32_t k0, k1, rawkey0, rawkey1;
|
||||||
|
int shifts, round;
|
||||||
|
|
||||||
|
if (!_des_initialised)
|
||||||
|
_des_init();
|
||||||
|
|
||||||
|
rawkey0 = ntohl(*(u_int32_t *) key);
|
||||||
|
rawkey1 = ntohl(*(u_int32_t *) (key + 4));
|
||||||
|
|
||||||
|
if ((rawkey0 | rawkey1)
|
||||||
|
&& rawkey0 == old_rawkey0
|
||||||
|
&& rawkey1 == old_rawkey1) {
|
||||||
|
/*
|
||||||
|
* Already setup for this key.
|
||||||
|
* This optimisation fails on a zero key (which is weak and
|
||||||
|
* has bad parity anyway) in order to simplify the starting
|
||||||
|
* conditions.
|
||||||
|
*/
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
old_rawkey0 = rawkey0;
|
||||||
|
old_rawkey1 = rawkey1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do key permutation and split into two 28-bit subkeys.
|
||||||
|
*/
|
||||||
|
k0 = key_perm_maskl[0][rawkey0 >> 25]
|
||||||
|
| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
|
||||||
|
| key_perm_maskl[4][rawkey1 >> 25]
|
||||||
|
| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
|
||||||
|
k1 = key_perm_maskr[0][rawkey0 >> 25]
|
||||||
|
| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
|
||||||
|
| key_perm_maskr[4][rawkey1 >> 25]
|
||||||
|
| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
|
||||||
|
/*
|
||||||
|
* Rotate subkeys and do compression permutation.
|
||||||
|
*/
|
||||||
|
shifts = 0;
|
||||||
|
for (round = 0; round < 16; round++) {
|
||||||
|
u_int32_t t0, t1;
|
||||||
|
|
||||||
|
shifts += key_shifts[round];
|
||||||
|
|
||||||
|
t0 = (k0 << shifts) | (k0 >> (28 - shifts));
|
||||||
|
t1 = (k1 << shifts) | (k1 >> (28 - shifts));
|
||||||
|
|
||||||
|
de_keysl[15 - round] =
|
||||||
|
en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
|
||||||
|
| comp_maskl[1][(t0 >> 14) & 0x7f]
|
||||||
|
| comp_maskl[2][(t0 >> 7) & 0x7f]
|
||||||
|
| comp_maskl[3][t0 & 0x7f]
|
||||||
|
| comp_maskl[4][(t1 >> 21) & 0x7f]
|
||||||
|
| comp_maskl[5][(t1 >> 14) & 0x7f]
|
||||||
|
| comp_maskl[6][(t1 >> 7) & 0x7f]
|
||||||
|
| comp_maskl[7][t1 & 0x7f];
|
||||||
|
|
||||||
|
de_keysr[15 - round] =
|
||||||
|
en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
|
||||||
|
| comp_maskr[1][(t0 >> 14) & 0x7f]
|
||||||
|
| comp_maskr[2][(t0 >> 7) & 0x7f]
|
||||||
|
| comp_maskr[3][t0 & 0x7f]
|
||||||
|
| comp_maskr[4][(t1 >> 21) & 0x7f]
|
||||||
|
| comp_maskr[5][(t1 >> 14) & 0x7f]
|
||||||
|
| comp_maskr[6][(t1 >> 7) & 0x7f]
|
||||||
|
| comp_maskr[7][t1 & 0x7f];
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out,
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||||
|
*/
|
||||||
|
u_int32_t l, r, *kl, *kr, *kl1, *kr1;
|
||||||
|
u_int32_t f, r48l, r48r;
|
||||||
|
int round;
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return(1);
|
||||||
|
} else if (count > 0) {
|
||||||
|
/*
|
||||||
|
* Encrypting
|
||||||
|
*/
|
||||||
|
kl1 = en_keysl;
|
||||||
|
kr1 = en_keysr;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Decrypting
|
||||||
|
*/
|
||||||
|
count = -count;
|
||||||
|
kl1 = de_keysl;
|
||||||
|
kr1 = de_keysr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do initial permutation (IP).
|
||||||
|
*/
|
||||||
|
l = ip_maskl[0][l_in >> 24]
|
||||||
|
| ip_maskl[1][(l_in >> 16) & 0xff]
|
||||||
|
| ip_maskl[2][(l_in >> 8) & 0xff]
|
||||||
|
| ip_maskl[3][l_in & 0xff]
|
||||||
|
| ip_maskl[4][r_in >> 24]
|
||||||
|
| ip_maskl[5][(r_in >> 16) & 0xff]
|
||||||
|
| ip_maskl[6][(r_in >> 8) & 0xff]
|
||||||
|
| ip_maskl[7][r_in & 0xff];
|
||||||
|
r = ip_maskr[0][l_in >> 24]
|
||||||
|
| ip_maskr[1][(l_in >> 16) & 0xff]
|
||||||
|
| ip_maskr[2][(l_in >> 8) & 0xff]
|
||||||
|
| ip_maskr[3][l_in & 0xff]
|
||||||
|
| ip_maskr[4][r_in >> 24]
|
||||||
|
| ip_maskr[5][(r_in >> 16) & 0xff]
|
||||||
|
| ip_maskr[6][(r_in >> 8) & 0xff]
|
||||||
|
| ip_maskr[7][r_in & 0xff];
|
||||||
|
|
||||||
|
while (count--) {
|
||||||
|
/*
|
||||||
|
* Do each round.
|
||||||
|
*/
|
||||||
|
kl = kl1;
|
||||||
|
kr = kr1;
|
||||||
|
round = 16;
|
||||||
|
while (round--) {
|
||||||
|
/*
|
||||||
|
* Expand R to 48 bits (simulate the E-box).
|
||||||
|
*/
|
||||||
|
r48l = ((r & 0x00000001) << 23)
|
||||||
|
| ((r & 0xf8000000) >> 9)
|
||||||
|
| ((r & 0x1f800000) >> 11)
|
||||||
|
| ((r & 0x01f80000) >> 13)
|
||||||
|
| ((r & 0x001f8000) >> 15);
|
||||||
|
|
||||||
|
r48r = ((r & 0x0001f800) << 7)
|
||||||
|
| ((r & 0x00001f80) << 5)
|
||||||
|
| ((r & 0x000001f8) << 3)
|
||||||
|
| ((r & 0x0000001f) << 1)
|
||||||
|
| ((r & 0x80000000) >> 31);
|
||||||
|
/*
|
||||||
|
* Do XOR with the permuted key.
|
||||||
|
*/
|
||||||
|
r48l ^= *kl++;
|
||||||
|
r48r ^= *kr++;
|
||||||
|
/*
|
||||||
|
* Do sbox lookups (which shrink it back to 32 bits)
|
||||||
|
* and do the pbox permutation at the same time.
|
||||||
|
*/
|
||||||
|
f = psbox[0][m_sbox[0][r48l >> 12]]
|
||||||
|
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
||||||
|
| psbox[2][m_sbox[2][r48r >> 12]]
|
||||||
|
| psbox[3][m_sbox[3][r48r & 0xfff]];
|
||||||
|
/*
|
||||||
|
* Now that we've permuted things, complete f().
|
||||||
|
*/
|
||||||
|
f ^= l;
|
||||||
|
l = r;
|
||||||
|
r = f;
|
||||||
|
}
|
||||||
|
r = l;
|
||||||
|
l = f;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do final permutation (inverse of IP).
|
||||||
|
*/
|
||||||
|
*l_out = fp_maskl[0][l >> 24]
|
||||||
|
| fp_maskl[1][(l >> 16) & 0xff]
|
||||||
|
| fp_maskl[2][(l >> 8) & 0xff]
|
||||||
|
| fp_maskl[3][l & 0xff]
|
||||||
|
| fp_maskl[4][r >> 24]
|
||||||
|
| fp_maskl[5][(r >> 16) & 0xff]
|
||||||
|
| fp_maskl[6][(r >> 8) & 0xff]
|
||||||
|
| fp_maskl[7][r & 0xff];
|
||||||
|
*r_out = fp_maskr[0][l >> 24]
|
||||||
|
| fp_maskr[1][(l >> 16) & 0xff]
|
||||||
|
| fp_maskr[2][(l >> 8) & 0xff]
|
||||||
|
| fp_maskr[3][l & 0xff]
|
||||||
|
| fp_maskr[4][r >> 24]
|
||||||
|
| fp_maskr[5][(r >> 16) & 0xff]
|
||||||
|
| fp_maskr[6][(r >> 8) & 0xff]
|
||||||
|
| fp_maskr[7][r & 0xff];
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int setkey(const char *key) {
|
||||||
|
int i, j;
|
||||||
|
u_int32_t packed_keys[2];
|
||||||
|
u_char *p;
|
||||||
|
|
||||||
|
p = (u_char *) packed_keys;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
p[i] = 0;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
if (*key++ & 1)
|
||||||
|
p[i] |= _des_bits8[j];
|
||||||
|
}
|
||||||
|
return(des_setkey((char *)p));
|
||||||
|
}
|
||||||
|
|
||||||
|
int encrypt(char *block, int flag) {
|
||||||
|
u_int32_t io[2];
|
||||||
|
u_char *p;
|
||||||
|
int i, j, retval;
|
||||||
|
|
||||||
|
if (!_des_initialised)
|
||||||
|
_des_init();
|
||||||
|
|
||||||
|
p = (u_char *)block;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
io[i] = 0L;
|
||||||
|
for (j = 0; j < 32; j++)
|
||||||
|
if (*p++ & 1)
|
||||||
|
io[i] |= _des_bits32[j];
|
||||||
|
}
|
||||||
|
retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
for (j = 0; j < 32; j++)
|
||||||
|
block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0;
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
40
src/netif/ppp/des.h
Normal file
40
src/netif/ppp/des.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* DES header
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DES_H_
|
||||||
|
#define DES_H_
|
||||||
|
|
||||||
|
int setkey(const char *key);
|
||||||
|
int encrypt(char *block, int flag);
|
||||||
|
|
||||||
|
#endif /* DES_H_ */
|
||||||
175
src/netif/ppp/ecp.c
Normal file
175
src/netif/ppp/ecp.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* ecp.c - PPP Encryption Control Protocol.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 Google, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* Derived from ccp.c, which is:
|
||||||
|
*
|
||||||
|
* Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* 3. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by Paul Mackerras
|
||||||
|
* <paulus@samba.org>".
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $"
|
||||||
|
|
||||||
|
static const char rcsid[] = RCSID;
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pppd.h"
|
||||||
|
#include "fsm.h"
|
||||||
|
#include "ecp.h"
|
||||||
|
|
||||||
|
static option_t ecp_option_list[] = {
|
||||||
|
{ "noecp", o_bool, &ecp_protent.enabled_flag,
|
||||||
|
"Disable ECP negotiation" },
|
||||||
|
{ "-ecp", o_bool, &ecp_protent.enabled_flag,
|
||||||
|
"Disable ECP negotiation", OPT_ALIAS },
|
||||||
|
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Protocol entry points from main code.
|
||||||
|
*/
|
||||||
|
static void ecp_init __P((int unit));
|
||||||
|
/*
|
||||||
|
static void ecp_open __P((int unit));
|
||||||
|
static void ecp_close __P((int unit, char *));
|
||||||
|
static void ecp_lowerup __P((int unit));
|
||||||
|
static void ecp_lowerdown __P((int));
|
||||||
|
static void ecp_input __P((int unit, u_char *pkt, int len));
|
||||||
|
static void ecp_protrej __P((int unit));
|
||||||
|
*/
|
||||||
|
static int ecp_printpkt __P((u_char *pkt, int len,
|
||||||
|
void (*printer) __P((void *, char *, ...)),
|
||||||
|
void *arg));
|
||||||
|
/*
|
||||||
|
static void ecp_datainput __P((int unit, u_char *pkt, int len));
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct protent ecp_protent = {
|
||||||
|
PPP_ECP,
|
||||||
|
ecp_init,
|
||||||
|
NULL, /* ecp_input, */
|
||||||
|
NULL, /* ecp_protrej, */
|
||||||
|
NULL, /* ecp_lowerup, */
|
||||||
|
NULL, /* ecp_lowerdown, */
|
||||||
|
NULL, /* ecp_open, */
|
||||||
|
NULL, /* ecp_close, */
|
||||||
|
ecp_printpkt,
|
||||||
|
NULL, /* ecp_datainput, */
|
||||||
|
0,
|
||||||
|
"ECP",
|
||||||
|
"Encrypted",
|
||||||
|
ecp_option_list,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
fsm ecp_fsm[NUM_PPP];
|
||||||
|
ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */
|
||||||
|
ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */
|
||||||
|
ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */
|
||||||
|
ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */
|
||||||
|
|
||||||
|
static fsm_callbacks ecp_callbacks = {
|
||||||
|
NULL, /* ecp_resetci, */
|
||||||
|
NULL, /* ecp_cilen, */
|
||||||
|
NULL, /* ecp_addci, */
|
||||||
|
NULL, /* ecp_ackci, */
|
||||||
|
NULL, /* ecp_nakci, */
|
||||||
|
NULL, /* ecp_rejci, */
|
||||||
|
NULL, /* ecp_reqci, */
|
||||||
|
NULL, /* ecp_up, */
|
||||||
|
NULL, /* ecp_down, */
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL, /* ecp_extcode, */
|
||||||
|
"ECP"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ecp_init - initialize ECP.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ecp_init(unit)
|
||||||
|
int unit;
|
||||||
|
{
|
||||||
|
fsm *f = &ecp_fsm[unit];
|
||||||
|
|
||||||
|
f->unit = unit;
|
||||||
|
f->protocol = PPP_ECP;
|
||||||
|
f->callbacks = &ecp_callbacks;
|
||||||
|
fsm_init(f);
|
||||||
|
|
||||||
|
memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options));
|
||||||
|
memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options));
|
||||||
|
memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options));
|
||||||
|
memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
ecp_printpkt(p, plen, printer, arg)
|
||||||
|
u_char *p;
|
||||||
|
int plen;
|
||||||
|
void (*printer) __P((void *, char *, ...));
|
||||||
|
void *arg;
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
45
src/netif/ppp/ecp.h
Normal file
45
src/netif/ppp/ecp.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* ecp.h - Definitions for PPP Encryption Control Protocol.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 Google, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct ecp_options {
|
||||||
|
bool required; /* Is ECP required? */
|
||||||
|
unsigned enctype; /* Encryption type */
|
||||||
|
} ecp_options;
|
||||||
|
|
||||||
|
extern fsm ecp_fsm[];
|
||||||
|
extern ecp_options ecp_wantoptions[];
|
||||||
|
extern ecp_options ecp_gotoptions[];
|
||||||
|
extern ecp_options ecp_allowoptions[];
|
||||||
|
extern ecp_options ecp_hisoptions[];
|
||||||
|
|
||||||
|
extern struct protent ecp_protent;
|
||||||
301
src/netif/ppp/md4.c
Normal file
301
src/netif/ppp/md4.c
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
** ********************************************************************
|
||||||
|
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||||
|
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||||
|
** (C) 1990 RSA Data Security, Inc. **
|
||||||
|
** ********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** To use MD4:
|
||||||
|
** -- Include md4.h in your program
|
||||||
|
** -- Declare an MDstruct MD to hold the state of the digest
|
||||||
|
** computation.
|
||||||
|
** -- Initialize MD using MDbegin(&MD)
|
||||||
|
** -- For each full block (64 bytes) X you wish to process, call
|
||||||
|
** MD4Update(&MD,X,512)
|
||||||
|
** (512 is the number of bits in a full block.)
|
||||||
|
** -- For the last block (less than 64 bytes) you wish to process,
|
||||||
|
** MD4Update(&MD,X,n)
|
||||||
|
** where n is the number of bits in the partial block. A partial
|
||||||
|
** block terminates the computation, so every MD computation
|
||||||
|
** should terminate by processing a partial block, even if it
|
||||||
|
** has n = 0.
|
||||||
|
** -- The message digest is available in MD.buffer[0] ...
|
||||||
|
** MD.buffer[3]. (Least-significant byte of each word
|
||||||
|
** should be output first.)
|
||||||
|
** -- You can print out the digest using MDprint(&MD)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Implementation notes:
|
||||||
|
** This implementation assumes that ints are 32-bit quantities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
/* Compile-time includes
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "md4.h"
|
||||||
|
#include "pppd.h"
|
||||||
|
|
||||||
|
/* Compile-time declarations of MD4 "magic constants".
|
||||||
|
*/
|
||||||
|
#define I0 0x67452301 /* Initial values for MD buffer */
|
||||||
|
#define I1 0xefcdab89
|
||||||
|
#define I2 0x98badcfe
|
||||||
|
#define I3 0x10325476
|
||||||
|
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||||
|
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||||
|
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||||
|
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||||
|
** Table 2, page 660.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define fs1 3 /* round 1 shift amounts */
|
||||||
|
#define fs2 7
|
||||||
|
#define fs3 11
|
||||||
|
#define fs4 19
|
||||||
|
#define gs1 3 /* round 2 shift amounts */
|
||||||
|
#define gs2 5
|
||||||
|
#define gs3 9
|
||||||
|
#define gs4 13
|
||||||
|
#define hs1 3 /* round 3 shift amounts */
|
||||||
|
#define hs2 9
|
||||||
|
#define hs3 11
|
||||||
|
#define hs4 15
|
||||||
|
|
||||||
|
/* Compile-time macro declarations for MD4.
|
||||||
|
** Note: The "rot" operator uses the variable "tmp".
|
||||||
|
** It assumes tmp is declared as unsigned int, so that the >>
|
||||||
|
** operator will shift in zeros rather than extending the sign bit.
|
||||||
|
*/
|
||||||
|
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||||
|
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||||
|
#define h(X,Y,Z) (X^Y^Z)
|
||||||
|
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||||
|
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||||
|
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||||
|
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||||
|
|
||||||
|
/* MD4print(MDp)
|
||||||
|
** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||||
|
** Order is from low-order byte of buffer[0] to high-order byte of
|
||||||
|
** buffer[3].
|
||||||
|
** Each byte is printed with high-order hexadecimal digit first.
|
||||||
|
** This is a user-callable routine.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
MD4Print(MDp)
|
||||||
|
MD4_CTX *MDp;
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
for (i=0;i<4;i++)
|
||||||
|
for (j=0;j<32;j=j+8)
|
||||||
|
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD4Init(MDp)
|
||||||
|
** Initialize message digest buffer MDp.
|
||||||
|
** This is a user-callable routine.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
MD4Init(MDp)
|
||||||
|
MD4_CTX *MDp;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MDp->buffer[0] = I0;
|
||||||
|
MDp->buffer[1] = I1;
|
||||||
|
MDp->buffer[2] = I2;
|
||||||
|
MDp->buffer[3] = I3;
|
||||||
|
for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||||
|
MDp->done = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MDblock(MDp,X)
|
||||||
|
** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||||
|
** Assumes all 16 words of X are full of data.
|
||||||
|
** Does not update MDp->count.
|
||||||
|
** This routine is not user-callable.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
MDblock(MDp,Xb)
|
||||||
|
MD4_CTX *MDp;
|
||||||
|
unsigned char *Xb;
|
||||||
|
{
|
||||||
|
register unsigned int tmp, A, B, C, D;
|
||||||
|
unsigned int X[16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; ++i) {
|
||||||
|
X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
|
||||||
|
Xb += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
A = MDp->buffer[0];
|
||||||
|
B = MDp->buffer[1];
|
||||||
|
C = MDp->buffer[2];
|
||||||
|
D = MDp->buffer[3];
|
||||||
|
/* Update the message digest buffer */
|
||||||
|
ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||||
|
ff(D , A , B , C , 1 , fs2);
|
||||||
|
ff(C , D , A , B , 2 , fs3);
|
||||||
|
ff(B , C , D , A , 3 , fs4);
|
||||||
|
ff(A , B , C , D , 4 , fs1);
|
||||||
|
ff(D , A , B , C , 5 , fs2);
|
||||||
|
ff(C , D , A , B , 6 , fs3);
|
||||||
|
ff(B , C , D , A , 7 , fs4);
|
||||||
|
ff(A , B , C , D , 8 , fs1);
|
||||||
|
ff(D , A , B , C , 9 , fs2);
|
||||||
|
ff(C , D , A , B , 10 , fs3);
|
||||||
|
ff(B , C , D , A , 11 , fs4);
|
||||||
|
ff(A , B , C , D , 12 , fs1);
|
||||||
|
ff(D , A , B , C , 13 , fs2);
|
||||||
|
ff(C , D , A , B , 14 , fs3);
|
||||||
|
ff(B , C , D , A , 15 , fs4);
|
||||||
|
gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||||
|
gg(D , A , B , C , 4 , gs2);
|
||||||
|
gg(C , D , A , B , 8 , gs3);
|
||||||
|
gg(B , C , D , A , 12 , gs4);
|
||||||
|
gg(A , B , C , D , 1 , gs1);
|
||||||
|
gg(D , A , B , C , 5 , gs2);
|
||||||
|
gg(C , D , A , B , 9 , gs3);
|
||||||
|
gg(B , C , D , A , 13 , gs4);
|
||||||
|
gg(A , B , C , D , 2 , gs1);
|
||||||
|
gg(D , A , B , C , 6 , gs2);
|
||||||
|
gg(C , D , A , B , 10 , gs3);
|
||||||
|
gg(B , C , D , A , 14 , gs4);
|
||||||
|
gg(A , B , C , D , 3 , gs1);
|
||||||
|
gg(D , A , B , C , 7 , gs2);
|
||||||
|
gg(C , D , A , B , 11 , gs3);
|
||||||
|
gg(B , C , D , A , 15 , gs4);
|
||||||
|
hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||||
|
hh(D , A , B , C , 8 , hs2);
|
||||||
|
hh(C , D , A , B , 4 , hs3);
|
||||||
|
hh(B , C , D , A , 12 , hs4);
|
||||||
|
hh(A , B , C , D , 2 , hs1);
|
||||||
|
hh(D , A , B , C , 10 , hs2);
|
||||||
|
hh(C , D , A , B , 6 , hs3);
|
||||||
|
hh(B , C , D , A , 14 , hs4);
|
||||||
|
hh(A , B , C , D , 1 , hs1);
|
||||||
|
hh(D , A , B , C , 9 , hs2);
|
||||||
|
hh(C , D , A , B , 5 , hs3);
|
||||||
|
hh(B , C , D , A , 13 , hs4);
|
||||||
|
hh(A , B , C , D , 3 , hs1);
|
||||||
|
hh(D , A , B , C , 11 , hs2);
|
||||||
|
hh(C , D , A , B , 7 , hs3);
|
||||||
|
hh(B , C , D , A , 15 , hs4);
|
||||||
|
MDp->buffer[0] += A;
|
||||||
|
MDp->buffer[1] += B;
|
||||||
|
MDp->buffer[2] += C;
|
||||||
|
MDp->buffer[3] += D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD4Update(MDp,X,count)
|
||||||
|
** Input: X -- a pointer to an array of unsigned characters.
|
||||||
|
** count -- the number of bits of X to use.
|
||||||
|
** (if not a multiple of 8, uses high bits of last byte.)
|
||||||
|
** Update MDp using the number of bits of X given by count.
|
||||||
|
** This is the basic input routine for an MD4 user.
|
||||||
|
** The routine completes the MD computation when count < 512, so
|
||||||
|
** every MD computation should end with one call to MD4Update with a
|
||||||
|
** count less than 512. A call with count 0 will be ignored if the
|
||||||
|
** MD has already been terminated (done != 0), so an extra call with
|
||||||
|
** count 0 can be given as a "courtesy close" to force termination
|
||||||
|
** if desired.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
MD4Update(MDp,X,count)
|
||||||
|
MD4_CTX *MDp;
|
||||||
|
unsigned char *X;
|
||||||
|
unsigned int count;
|
||||||
|
{
|
||||||
|
unsigned int i, tmp, bit, byte, mask;
|
||||||
|
unsigned char XX[64];
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
/* return with no error if this is a courtesy close with count
|
||||||
|
** zero and MDp->done is true.
|
||||||
|
*/
|
||||||
|
if (count == 0 && MDp->done) return;
|
||||||
|
/* check to see if MD is already done and report error */
|
||||||
|
if (MDp->done)
|
||||||
|
{ printf("\nError: MD4Update MD already done."); return; }
|
||||||
|
|
||||||
|
/* Add count to MDp->count */
|
||||||
|
tmp = count;
|
||||||
|
p = MDp->count;
|
||||||
|
while (tmp)
|
||||||
|
{ tmp += *p;
|
||||||
|
*p++ = tmp;
|
||||||
|
tmp = tmp >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process data */
|
||||||
|
if (count == 512)
|
||||||
|
{ /* Full block of data to handle */
|
||||||
|
MDblock(MDp,X);
|
||||||
|
}
|
||||||
|
else if (count > 512) /* Check for count too large */
|
||||||
|
{
|
||||||
|
printf("\nError: MD4Update called with illegal count value %d.",
|
||||||
|
count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else /* partial block -- must be last block so finish up */
|
||||||
|
{
|
||||||
|
/* Find out how many bytes and residual bits there are */
|
||||||
|
byte = count >> 3;
|
||||||
|
bit = count & 7;
|
||||||
|
/* Copy X into XX since we need to modify it */
|
||||||
|
if (count)
|
||||||
|
for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||||
|
for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||||
|
/* Add padding '1' bit and low-order zeros in last byte */
|
||||||
|
mask = 1 << (7 - bit);
|
||||||
|
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||||
|
/* If room for bit count, finish up with this block */
|
||||||
|
if (byte <= 55)
|
||||||
|
{
|
||||||
|
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||||
|
MDblock(MDp,XX);
|
||||||
|
}
|
||||||
|
else /* need to do two blocks to finish up */
|
||||||
|
{
|
||||||
|
MDblock(MDp,XX);
|
||||||
|
for (i=0;i<56;i++) XX[i] = 0;
|
||||||
|
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||||
|
MDblock(MDp,XX);
|
||||||
|
}
|
||||||
|
/* Set flag saying we're done with MD computation */
|
||||||
|
MDp->done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Finish up MD4 computation and return message digest.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
MD4Final(buf, MD)
|
||||||
|
unsigned char *buf;
|
||||||
|
MD4_CTX *MD;
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned int w;
|
||||||
|
|
||||||
|
MD4Update(MD, NULL, 0);
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
w = MD->buffer[i];
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
*buf++ = w;
|
||||||
|
w >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** End of md4.c
|
||||||
|
****************************(cut)***********************************/
|
||||||
64
src/netif/ppp/md4.h
Normal file
64
src/netif/ppp/md4.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
** ********************************************************************
|
||||||
|
** md4.h -- Header file for implementation of **
|
||||||
|
** MD4 Message Digest Algorithm **
|
||||||
|
** Updated: 2/13/90 by Ronald L. Rivest **
|
||||||
|
** (C) 1990 RSA Data Security, Inc. **
|
||||||
|
** ********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# if defined(__STDC__) || defined(__GNUC__)
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* MDstruct is the data structure for a message digest computation.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||||
|
unsigned char count[8]; /* Number of bits processed so far */
|
||||||
|
unsigned int done; /* Nonzero means MD computation finished */
|
||||||
|
} MD4_CTX;
|
||||||
|
|
||||||
|
/* MD4Init(MD4_CTX *)
|
||||||
|
** Initialize the MD4_CTX prepatory to doing a message digest
|
||||||
|
** computation.
|
||||||
|
*/
|
||||||
|
extern void MD4Init __P((MD4_CTX *MD));
|
||||||
|
|
||||||
|
/* MD4Update(MD,X,count)
|
||||||
|
** Input: X -- a pointer to an array of unsigned characters.
|
||||||
|
** count -- the number of bits of X to use (an unsigned int).
|
||||||
|
** Updates MD using the first "count" bits of X.
|
||||||
|
** The array pointed to by X is not modified.
|
||||||
|
** If count is not a multiple of 8, MD4Update uses high bits of
|
||||||
|
** last byte.
|
||||||
|
** This is the basic input routine for a user.
|
||||||
|
** The routine terminates the MD computation when count < 512, so
|
||||||
|
** every MD computation should end with one call to MD4Update with a
|
||||||
|
** count less than 512. Zero is OK for a count.
|
||||||
|
*/
|
||||||
|
extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count));
|
||||||
|
|
||||||
|
/* MD4Print(MD)
|
||||||
|
** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||||
|
** Order is from low-order byte of buffer[0] to high-order byte
|
||||||
|
** of buffer[3].
|
||||||
|
** Each byte is printed with high-order hexadecimal digit first.
|
||||||
|
*/
|
||||||
|
extern void MD4Print __P((MD4_CTX *));
|
||||||
|
|
||||||
|
/* MD4Final(buf, MD)
|
||||||
|
** Returns message digest from MD and terminates the message
|
||||||
|
** digest computation.
|
||||||
|
*/
|
||||||
|
extern void MD4Final __P((unsigned char *, MD4_CTX *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
** End of md4.h
|
||||||
|
****************************(cut)***********************************/
|
||||||
@ -107,8 +107,14 @@
|
|||||||
#if EAP_SUPPORT
|
#if EAP_SUPPORT
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#endif /* EAP_SUPPORT */
|
#endif /* EAP_SUPPORT */
|
||||||
|
#include "ccp.h"
|
||||||
|
#include "ecp.h"
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
|
|
||||||
|
#if CBCP_SUPPORT
|
||||||
|
#include "cbcp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AT_CHANGE
|
#ifdef AT_CHANGE
|
||||||
#include "atcp.h"
|
#include "atcp.h"
|
||||||
#endif
|
#endif
|
||||||
@ -161,6 +167,7 @@ int fd_ppp = -1; /* fd for talking PPP */
|
|||||||
int phase; /* where the link is at */
|
int phase; /* where the link is at */
|
||||||
int kill_link;
|
int kill_link;
|
||||||
int asked_to_quit;
|
int asked_to_quit;
|
||||||
|
int open_ccp_flag;
|
||||||
int listen_time;
|
int listen_time;
|
||||||
int got_sigusr2;
|
int got_sigusr2;
|
||||||
int got_sigterm;
|
int got_sigterm;
|
||||||
@ -227,6 +234,7 @@ static void hup __P((int));
|
|||||||
static void term __P((int));
|
static void term __P((int));
|
||||||
static void chld __P((int));
|
static void chld __P((int));
|
||||||
static void toggle_debug __P((int));
|
static void toggle_debug __P((int));
|
||||||
|
static void open_ccp __P((int));
|
||||||
static void bad_signal __P((int));
|
static void bad_signal __P((int));
|
||||||
static void holdoff_end __P((void *));
|
static void holdoff_end __P((void *));
|
||||||
static void forget_child __P((int pid, int status));
|
static void forget_child __P((int pid, int status));
|
||||||
@ -265,6 +273,8 @@ struct protent *protocols[] = {
|
|||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
&ipv6cp_protent,
|
&ipv6cp_protent,
|
||||||
#endif
|
#endif
|
||||||
|
&ccp_protent,
|
||||||
|
&ecp_protent,
|
||||||
#ifdef AT_CHANGE
|
#ifdef AT_CHANGE
|
||||||
&atcp_protent,
|
&atcp_protent,
|
||||||
#endif
|
#endif
|
||||||
@ -507,6 +517,12 @@ int ppp_oldmain() {
|
|||||||
if (phase == PHASE_MASTER)
|
if (phase == PHASE_MASTER)
|
||||||
mp_bundle_terminated();
|
mp_bundle_terminated();
|
||||||
}
|
}
|
||||||
|
if (open_ccp_flag) {
|
||||||
|
if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
|
||||||
|
ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
|
||||||
|
(*ccp_protent.open)(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* restore FSMs to original state */
|
/* restore FSMs to original state */
|
||||||
lcp_close(0, "");
|
lcp_close(0, "");
|
||||||
@ -562,7 +578,7 @@ handle_events()
|
|||||||
{
|
{
|
||||||
struct timeval timo;
|
struct timeval timo;
|
||||||
|
|
||||||
kill_link = 0;
|
kill_link = open_ccp_flag = 0;
|
||||||
if (sigsetjmp(sigjmp, 1) == 0) {
|
if (sigsetjmp(sigjmp, 1) == 0) {
|
||||||
sigprocmask(SIG_BLOCK, &signals_handled, NULL);
|
sigprocmask(SIG_BLOCK, &signals_handled, NULL);
|
||||||
if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
|
if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
|
||||||
@ -594,6 +610,10 @@ handle_events()
|
|||||||
got_sigchld = 0;
|
got_sigchld = 0;
|
||||||
reap_kids(); /* Don't leave dead kids lying around */
|
reap_kids(); /* Don't leave dead kids lying around */
|
||||||
}
|
}
|
||||||
|
if (got_sigusr2) {
|
||||||
|
open_ccp_flag = 1;
|
||||||
|
got_sigusr2 = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -630,6 +650,7 @@ setup_signals()
|
|||||||
SIGNAL(SIGCHLD, chld);
|
SIGNAL(SIGCHLD, chld);
|
||||||
|
|
||||||
SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */
|
SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */
|
||||||
|
SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Install a handler for other signals which would otherwise
|
* Install a handler for other signals which would otherwise
|
||||||
@ -1438,6 +1459,23 @@ toggle_debug(sig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* open_ccp - Catch SIGUSR2 signal.
|
||||||
|
*
|
||||||
|
* Try to (re)negotiate compression.
|
||||||
|
*/
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
open_ccp(sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
got_sigusr2 = 1;
|
||||||
|
if (waiting)
|
||||||
|
siglongjmp(sigjmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bad_signal - We've caught a fatal signal. Clean up state and exit.
|
* bad_signal - We've caught a fatal signal. Clean up state and exit.
|
||||||
*/
|
*/
|
||||||
|
|||||||
146
src/netif/ppp/pppcrypt.c
Normal file
146
src/netif/ppp/pppcrypt.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||||
|
*
|
||||||
|
* Extracted from chap_ms.c by James Carlson.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#include "pppd.h"
|
||||||
|
#include "pppcrypt.h"
|
||||||
|
#include "des.h"
|
||||||
|
|
||||||
|
static u_char
|
||||||
|
Get7Bits(input, startBit)
|
||||||
|
u_char *input;
|
||||||
|
int startBit;
|
||||||
|
{
|
||||||
|
unsigned int word;
|
||||||
|
|
||||||
|
word = (unsigned)input[startBit / 8] << 8;
|
||||||
|
word |= (unsigned)input[startBit / 8 + 1];
|
||||||
|
|
||||||
|
word >>= 15 - (startBit % 8 + 7);
|
||||||
|
|
||||||
|
return word & 0xFE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MakeKey(key, des_key)
|
||||||
|
u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||||
|
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||||
|
{
|
||||||
|
des_key[0] = Get7Bits(key, 0);
|
||||||
|
des_key[1] = Get7Bits(key, 7);
|
||||||
|
des_key[2] = Get7Bits(key, 14);
|
||||||
|
des_key[3] = Get7Bits(key, 21);
|
||||||
|
des_key[4] = Get7Bits(key, 28);
|
||||||
|
des_key[5] = Get7Bits(key, 35);
|
||||||
|
des_key[6] = Get7Bits(key, 42);
|
||||||
|
des_key[7] = Get7Bits(key, 49);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in == 8-byte string (expanded version of the 56-bit key)
|
||||||
|
* out == 64-byte string where each byte is either 1 or 0
|
||||||
|
* Note that the low-order "bit" is always ignored by by setkey()
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Expand(in, out)
|
||||||
|
u_char *in;
|
||||||
|
u_char *out;
|
||||||
|
{
|
||||||
|
int j, c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 64; in++){
|
||||||
|
c = *in;
|
||||||
|
for (j = 7; j >= 0; j--)
|
||||||
|
*out++ = (c >> j) & 01;
|
||||||
|
i += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The inverse of Expand
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
Collapse(in, out)
|
||||||
|
u_char *in;
|
||||||
|
u_char *out;
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int i;
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
|
for (i = 0; i < 64; i += 8, out++) {
|
||||||
|
c = 0;
|
||||||
|
for (j = 7; j >= 0; j--, in++)
|
||||||
|
c |= *in << j;
|
||||||
|
*out = c & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesSetkey(key)
|
||||||
|
u_char *key;
|
||||||
|
{
|
||||||
|
u_char des_key[8];
|
||||||
|
u_char crypt_key[66];
|
||||||
|
|
||||||
|
MakeKey(key, des_key);
|
||||||
|
Expand(des_key, crypt_key);
|
||||||
|
setkey((const char *)crypt_key);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesEncrypt(clear, cipher)
|
||||||
|
u_char *clear; /* IN 8 octets */
|
||||||
|
u_char *cipher; /* OUT 8 octets */
|
||||||
|
{
|
||||||
|
u_char des_input[66];
|
||||||
|
|
||||||
|
Expand(clear, des_input);
|
||||||
|
encrypt((char *)des_input, 0);
|
||||||
|
Collapse(des_input, cipher);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesDecrypt(cipher, clear)
|
||||||
|
u_char *cipher; /* IN 8 octets */
|
||||||
|
u_char *clear; /* OUT 8 octets */
|
||||||
|
{
|
||||||
|
u_char des_input[66];
|
||||||
|
|
||||||
|
Expand(cipher, des_input);
|
||||||
|
encrypt((char *)des_input, 1);
|
||||||
|
Collapse(des_input, clear);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
40
src/netif/ppp/pppcrypt.h
Normal file
40
src/netif/ppp/pppcrypt.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||||
|
*
|
||||||
|
* Extracted from chap_ms.c by James Carlson.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The name(s) of the authors of this software must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPPCRYPT_H
|
||||||
|
#define PPPCRYPT_H
|
||||||
|
|
||||||
|
extern bool DesSetkey __P((u_char *));
|
||||||
|
extern bool DesEncrypt __P((u_char *, u_char *));
|
||||||
|
extern bool DesDecrypt __P((u_char *, u_char *));
|
||||||
|
|
||||||
|
#endif /* PPPCRYPT_H */
|
||||||
@ -529,6 +529,7 @@ void link_down __P((int)); /* the LCP layer has left the Opened state */
|
|||||||
void upper_layers_down __P((int));/* take all NCPs down */
|
void upper_layers_down __P((int));/* take all NCPs down */
|
||||||
void link_established __P((int)); /* the link is up; authenticate now */
|
void link_established __P((int)); /* the link is up; authenticate now */
|
||||||
void start_networks __P((int)); /* start all the network control protos */
|
void start_networks __P((int)); /* start all the network control protos */
|
||||||
|
void continue_networks __P((int)); /* start network [ip, etc] control protos */
|
||||||
void np_up __P((int, int)); /* a network protocol has come up */
|
void np_up __P((int, int)); /* a network protocol has come up */
|
||||||
void np_down __P((int, int)); /* a network protocol has gone down */
|
void np_down __P((int, int)); /* a network protocol has gone down */
|
||||||
void np_finished __P((int, int)); /* a network protocol no longer needs link */
|
void np_finished __P((int, int)); /* a network protocol no longer needs link */
|
||||||
|
|||||||
@ -436,10 +436,14 @@ void
|
|||||||
pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
|
pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
|
||||||
{
|
{
|
||||||
ppp_settings.refuse_pap = 1;
|
ppp_settings.refuse_pap = 1;
|
||||||
ppp_settings.refuse_chap = 0;
|
ppp_settings.refuse_chap = 1;
|
||||||
|
ppp_settings.refuse_mschap = 1;
|
||||||
|
ppp_settings.refuse_mschap_v2 = 0;
|
||||||
#if EAP_SUPPORT
|
#if EAP_SUPPORT
|
||||||
ppp_settings.refuse_pap = 1;
|
ppp_settings.refuse_pap = 1;
|
||||||
ppp_settings.refuse_chap = 1;
|
ppp_settings.refuse_chap = 1;
|
||||||
|
ppp_settings.refuse_mschap = 1;
|
||||||
|
ppp_settings.refuse_mschap_v2 = 1;
|
||||||
ppp_settings.refuse_eap = 0;
|
ppp_settings.refuse_eap = 0;
|
||||||
#endif /* EAP_SUPPORT */
|
#endif /* EAP_SUPPORT */
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,8 @@ struct ppp_settings {
|
|||||||
u_int explicit_remote : 1; /* remote_name specified with remotename opt */
|
u_int explicit_remote : 1; /* remote_name specified with remotename opt */
|
||||||
u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */
|
u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */
|
||||||
u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */
|
u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */
|
||||||
|
u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */
|
||||||
|
u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */
|
||||||
#if EAP_SUPPORT
|
#if EAP_SUPPORT
|
||||||
u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */
|
u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */
|
||||||
#endif /* EAP_SUPPORT */
|
#endif /* EAP_SUPPORT */
|
||||||
|
|||||||
172
src/netif/ppp/sha1.c
Normal file
172
src/netif/ppp/sha1.c
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
|
||||||
|
*
|
||||||
|
* SHA-1 in C
|
||||||
|
* By Steve Reid <steve@edmweb.com>
|
||||||
|
* 100% Public Domain
|
||||||
|
*
|
||||||
|
* Test Vectors (from FIPS PUB 180-1)
|
||||||
|
* "abc"
|
||||||
|
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||||
|
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||||
|
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||||
|
* A million repetitions of "a"
|
||||||
|
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <netinet/in.h> /* htonl() */
|
||||||
|
#include <net/ppp_defs.h>
|
||||||
|
#include "sha1.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
SHA1_Transform(u_int32_t[5], const unsigned char[64]);
|
||||||
|
|
||||||
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||||
|
|
||||||
|
/* blk0() and blk() perform the initial expand. */
|
||||||
|
/* I got the idea of expanding during the round function from SSLeay */
|
||||||
|
#define blk0(i) (block->l[i] = htonl(block->l[i]))
|
||||||
|
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||||
|
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||||
|
|
||||||
|
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||||
|
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||||
|
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||||
|
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||||
|
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||||
|
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64])
|
||||||
|
{
|
||||||
|
u_int32_t a, b, c, d, e;
|
||||||
|
typedef union {
|
||||||
|
unsigned char c[64];
|
||||||
|
u_int32_t l[16];
|
||||||
|
} CHAR64LONG16;
|
||||||
|
CHAR64LONG16 *block;
|
||||||
|
|
||||||
|
#ifdef SHA1HANDSOFF
|
||||||
|
static unsigned char workspace[64];
|
||||||
|
block = (CHAR64LONG16 *) workspace;
|
||||||
|
memcpy(block, buffer, 64);
|
||||||
|
#else
|
||||||
|
block = (CHAR64LONG16 *) buffer;
|
||||||
|
#endif
|
||||||
|
/* Copy context->state[] to working vars */
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
e = state[4];
|
||||||
|
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||||
|
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||||
|
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||||
|
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||||
|
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||||
|
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||||
|
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||||
|
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||||
|
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||||
|
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||||
|
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||||
|
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||||
|
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||||
|
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||||
|
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||||
|
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||||
|
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||||
|
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||||
|
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||||
|
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||||
|
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||||
|
/* Add the working vars back into context.state[] */
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
state[4] += e;
|
||||||
|
/* Wipe variables */
|
||||||
|
a = b = c = d = e = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SHA1Init - Initialize new context */
|
||||||
|
|
||||||
|
void
|
||||||
|
SHA1_Init(SHA1_CTX *context)
|
||||||
|
{
|
||||||
|
/* SHA1 initialization constants */
|
||||||
|
context->state[0] = 0x67452301;
|
||||||
|
context->state[1] = 0xEFCDAB89;
|
||||||
|
context->state[2] = 0x98BADCFE;
|
||||||
|
context->state[3] = 0x10325476;
|
||||||
|
context->state[4] = 0xC3D2E1F0;
|
||||||
|
context->count[0] = context->count[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Run your data through this. */
|
||||||
|
|
||||||
|
void
|
||||||
|
SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
j = (context->count[0] >> 3) & 63;
|
||||||
|
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
|
||||||
|
context->count[1] += (len >> 29);
|
||||||
|
i = 64 - j;
|
||||||
|
while (len >= i) {
|
||||||
|
memcpy(&context->buffer[j], data, i);
|
||||||
|
SHA1_Transform(context->state, context->buffer);
|
||||||
|
data += i;
|
||||||
|
len -= i;
|
||||||
|
i = 64;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&context->buffer[j], data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add padding and return the message digest. */
|
||||||
|
|
||||||
|
void
|
||||||
|
SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
|
||||||
|
{
|
||||||
|
u_int32_t i, j;
|
||||||
|
unsigned char finalcount[8];
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
||||||
|
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||||
|
}
|
||||||
|
SHA1_Update(context, (unsigned char *) "\200", 1);
|
||||||
|
while ((context->count[0] & 504) != 448) {
|
||||||
|
SHA1_Update(context, (unsigned char *) "\0", 1);
|
||||||
|
}
|
||||||
|
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||||
|
for (i = 0; i < 20; i++) {
|
||||||
|
digest[i] = (unsigned char)
|
||||||
|
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||||
|
}
|
||||||
|
/* Wipe variables */
|
||||||
|
i = j = 0;
|
||||||
|
memset(context->buffer, 0, 64);
|
||||||
|
memset(context->state, 0, 20);
|
||||||
|
memset(context->count, 0, 8);
|
||||||
|
memset(&finalcount, 0, 8);
|
||||||
|
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
|
||||||
|
SHA1Transform(context->state, context->buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
31
src/netif/ppp/sha1.h
Normal file
31
src/netif/ppp/sha1.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* sha1.h */
|
||||||
|
|
||||||
|
/* If OpenSSL is in use, then use that version of SHA-1 */
|
||||||
|
#ifdef OPENSSL
|
||||||
|
#include <t_sha.h>
|
||||||
|
#define __SHA1_INCLUDE_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __SHA1_INCLUDE_
|
||||||
|
|
||||||
|
#ifndef SHA1_SIGNATURE_SIZE
|
||||||
|
#ifdef SHA_DIGESTSIZE
|
||||||
|
#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
|
||||||
|
#else
|
||||||
|
#define SHA1_SIGNATURE_SIZE 20
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u_int32_t state[5];
|
||||||
|
u_int32_t count[2];
|
||||||
|
unsigned char buffer[64];
|
||||||
|
} SHA1_CTX;
|
||||||
|
|
||||||
|
extern void SHA1_Init(SHA1_CTX *);
|
||||||
|
extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
|
||||||
|
extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
|
||||||
|
|
||||||
|
#define __SHA1_INCLUDE_
|
||||||
|
#endif /* __SHA1_INCLUDE_ */
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user