]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/eap.c
CI: Updated the 'checkout' actions that were using Node.js 16 to Node.js 20. (#489)
[ppp.git] / pppd / eap.c
index b97d28552e076b5be5cefecc99e4e1a7514148fa..70154664432e8e90904d901bf311aa6511036a57 100644 (file)
  * Implemented EAP-TLS authentication
  */
 
-#define RCSID  "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
-
-/*
- * TODO:
- */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <errno.h>
 
-#include "pppd.h"
+#include "pppd-private.h"
+#include "options.h"
 #include "pathnames.h"
-#include "md5.h"
+#include "crypto.h"
+#include "crypto_ms.h"
 #include "eap.h"
+#ifdef PPP_WITH_PEAP
+#include "peap.h"
+#endif /* PPP_WITH_PEAP */
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
 #include <t_pwd.h>
 #include <t_server.h>
 #include <t_client.h>
-#include "pppcrypt.h"
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
-#ifndef SHA_DIGESTSIZE
-#define        SHA_DIGESTSIZE 20
-#endif
-
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
 #include "eap-tls.h"
-#endif /* USE_EAPTLS */
-#ifdef CHAPMS
-#include "magic.h"
+#endif /* PPP_WITH_EAPTLS */
+
+#ifdef PPP_WITH_CHAPMS
+#include "chap.h"
 #include "chap_ms.h"
-#include "chap-new.h"
-#endif /* CHAPMS */
+
+extern int chapms_strip_domain;
+#endif /* PPP_WITH_CHAPMS */
 
 eap_state eap_states[NUM_PPP];         /* EAP state; one for each unit */
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
 static char *pn_secret = NULL;         /* Pseudonym generating secret */
 #endif
 
 /*
  * Command-line options.
  */
-static option_t eap_option_list[] = {
+static struct option eap_option_list[] = {
     { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
       "Set retransmit timeout for EAP Requests (server)" },
     { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
@@ -109,7 +112,7 @@ static option_t eap_option_list[] = {
       "Set max number of EAP Requests allows (client)" },
     { "eap-interval", o_int, &eap_states[0].es_rechallenge,
       "Set interval for EAP rechallenge" },
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
     { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
       "Set interval for SRP lightweight rechallenge" },
     { "srp-pn-secret", o_string, &pn_secret,
@@ -123,13 +126,13 @@ static option_t eap_option_list[] = {
 /*
  * Protocol entry points.
  */
-static void eap_init __P((int unit));
-static void eap_input __P((int unit, u_char *inp, int inlen));
-static void eap_protrej __P((int unit));
-static void eap_lowerup __P((int unit));
-static void eap_lowerdown __P((int unit));
-static int  eap_printpkt __P((u_char *inp, int inlen,
-    void (*)(void *arg, char *fmt, ...), void *arg));
+static void eap_init (int unit);
+static void eap_input (int unit, u_char *inp, int inlen);
+static void eap_protrej (int unit);
+static void eap_lowerup (int unit);
+static void eap_lowerdown (int unit);
+static int  eap_printpkt (u_char *inp, int inlen,
+    void (*)(void *arg, char *fmt, ...), void *arg);
 
 struct protent eap_protent = {
        PPP_EAP,                /* protocol number */
@@ -151,6 +154,7 @@ struct protent eap_protent = {
        NULL                    /* say whether to bring up link for this pkt */
 };
 
+#ifdef PPP_WITH_SRP
 /*
  * A well-known 2048 bit modulus.
  */
@@ -188,16 +192,16 @@ static const u_char wkmodulus[] = {
        0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
        0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
 };
+#endif /* PPP_WITH_SRP */
 
 /* Local forward declarations. */
-static void eap_server_timeout __P((void *arg));
+static void eap_server_timeout (void *arg);
 
 /*
  * Convert EAP state code to printable string for debug.
  */
 static const char *
-eap_state_name(esc)
-enum eap_state_code esc;
+eap_state_name(enum eap_state_code esc)
 {
        static const char *state_names[] = { EAP_STATES };
 
@@ -209,8 +213,7 @@ enum eap_state_code esc;
  * called once by main() during start-up.
  */
 static void
-eap_init(unit)
-int unit;
+eap_init(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -221,9 +224,13 @@ int unit;
        esp->es_server.ea_id = (u_char)(drand48() * 0x100);
        esp->es_client.ea_timeout = EAP_DEFREQTIME;
        esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        esp->es_client.ea_using_eaptls = 0;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
+#ifdef PPP_WITH_CHAPMS
+       esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
+       esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
+#endif
 }
 
 /*
@@ -231,8 +238,7 @@ int unit;
  * Request messages.
  */
 static void
-eap_client_timeout(arg)
-void *arg;
+eap_client_timeout(void *arg)
 {
        eap_state *esp = (eap_state *) arg;
 
@@ -251,9 +257,7 @@ void *arg;
  * after eap_lowerup.
  */
 void
-eap_authwithpeer(unit, localname)
-int unit;
-char *localname;
+eap_authwithpeer(int unit, char *localname)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -277,8 +281,7 @@ char *localname;
  * (Server operation)
  */
 static void
-eap_send_failure(esp)
-eap_state *esp;
+eap_send_failure(eap_state *esp)
 {
        u_char *outp;
 
@@ -302,8 +305,7 @@ eap_state *esp;
  * (Server operation)
  */
 static void
-eap_send_success(esp)
-eap_state *esp;
+eap_send_success(eap_state *esp)
 {
        u_char *outp;
 
@@ -322,30 +324,39 @@ eap_state *esp;
            esp->es_server.ea_peer, esp->es_server.ea_peerlen);
 }
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
 /*
  * Set DES key according to pseudonym-generating secret and current
  * date.
  */
 static bool
-pncrypt_setkey(int timeoffs)
+pncrypt_getkey(int timeoffs, unsigned char *key, int keylen)
 {
        struct tm *tp;
        char tbuf[9];
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
+       PPP_MD_CTX *ctxt;
        time_t reftime;
 
        if (pn_secret == NULL)
                return (0);
        reftime = time(NULL) + timeoffs;
        tp = localtime(&reftime);
-       SHA1Init(&ctxt);
-       SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
-       strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
-       SHA1Update(&ctxt, tbuf, strlen(tbuf));
-       SHA1Final(dig, &ctxt);
-       return (DesSetkey(dig));
+
+       ctxt = PPP_MD_CTX_new();
+       if (ctxt) {
+
+           strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
+
+           PPP_DigestInit(ctxt, PPP_sha1());
+           PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
+           PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
+           PPP_DigestFinal(ctxt, key, &keylen);
+
+           PPP_MD_CTX_free(ctxt);
+           return 1;
+       }
+
+       return (0);
 }
 
 static char base64[] =
@@ -357,11 +368,7 @@ struct b64state {
 };
 
 static int
-b64enc(bs, inp, inlen, outp)
-struct b64state *bs;
-u_char *inp;
-int inlen;
-u_char *outp;
+b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
 {
        int outlen = 0;
 
@@ -383,9 +390,7 @@ u_char *outp;
 }
 
 static int
-b64flush(bs, outp)
-struct b64state *bs;
-u_char *outp;
+b64flush(struct b64state *bs, u_char *outp)
 {
        int outlen = 0;
 
@@ -405,11 +410,7 @@ u_char *outp;
 }
 
 static int
-b64dec(bs, inp, inlen, outp)
-struct b64state *bs;
-u_char *inp;
-int inlen;
-u_char *outp;
+b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
 {
        int outlen = 0;
        char *cp;
@@ -428,7 +429,7 @@ u_char *outp;
        }
        return (outlen);
 }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
 /*
  * Assume that current waiting server state is complete and figure
@@ -437,36 +438,34 @@ u_char *outp;
  * 0 for success and non-zero for failure.
  */
 static void
-eap_figure_next_state(esp, status)
-eap_state *esp;
-int status;
+eap_figure_next_state(eap_state *esp, int status)
 {
-#ifdef USE_SRP
-       unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
+#ifdef PPP_WITH_SRP
+       unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH];
        struct t_pw tpw;
        struct t_confent *tce, mytce;
        char *cp, *cp2;
        struct t_server *ts;
-       int id, i, plen, toffs;
+       int id, i, plen, clen, toffs, keylen;
        u_char vals[2];
        struct b64state bs;
-#endif /* USE_SRP */
-#ifdef USE_EAPTLS
+#endif /* PPP_WITH_SRP */
+#ifdef PPP_WITH_EAPTLS
        struct eaptls_session *ets;
        int secret_len;
        char secret[MAXWORDLEN];
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        esp->es_server.ea_timeout = esp->es_savedtime;
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        esp->es_server.ea_prev_state = esp->es_server.ea_state;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
        switch (esp->es_server.ea_state) {
        case eapBadAuth:
                return;
 
        case eapIdentify:
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                /* Discard any previous session. */
                ts = (struct t_server *)esp->es_server.ea_session;
                if (ts != NULL) {
@@ -474,12 +473,12 @@ int status;
                        esp->es_server.ea_session = NULL;
                        esp->es_server.ea_skey = NULL;
                }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
                if (status != 0) {
                        esp->es_server.ea_state = eapBadAuth;
                        break;
                }
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                /* If we've got a pseudonym, try to decode to real name. */
                if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
                    strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
@@ -493,11 +492,12 @@ int status;
                            secbuf);
                        toffs = 0;
                        for (i = 0; i < 5; i++) {
-                               pncrypt_setkey(toffs);
+                               pncrypt_getkey(toffs, key, keylen);
                                toffs -= 86400;
-                               if (!DesDecrypt(secbuf, clear)) {
+
+                               if (!DesDecrypt(secbuf, key, clear)) {
                                        dbglog("no DES here; cannot decode "
-                                           "pseudonym");
+                                               "pseudonym");
                                        return;
                                }
                                id = *(unsigned char *)clear;
@@ -519,7 +519,7 @@ int status;
                                dp += i;
                                sp = secbuf + 8;
                                while (plen > 0) {
-                                       (void) DesDecrypt(sp, dp);
+                                       DesDecrypt(sp, key, dp);
                                        sp += 8;
                                        dp += 8;
                                        plen -= 8;
@@ -569,7 +569,7 @@ int status;
                        tpw.pebuf.name = esp->es_server.ea_peer;
                        tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
                            cp);
-                       tpw.pebuf.password.data = tpw.pwbuf;
+                       tpw.pebuf.password.data = (char*) tpw.pwbuf;
                        tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
                            cp2);
                        tpw.pebuf.salt.data = tpw.saltbuf;
@@ -584,20 +584,20 @@ int status;
                        t_servergenexp(ts);
                        break;
                }
-#endif /* USE_SRP */
-#ifdef USE_EAPTLS
+#endif /* PPP_WITH_SRP */
+#ifdef PPP_WITH_EAPTLS
                 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
                     esp->es_server.ea_name, secret, &secret_len, 1)) {
 
                        esp->es_server.ea_state = eapTlsStart;
                        break;
                }
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
                esp->es_server.ea_state = eapMD5Chall;
                break;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        case eapTlsStart:
                /* Initialize ssl session */
                if(!eaptls_init_ssl_server(esp)) {
@@ -658,17 +658,17 @@ int status;
        case eapTlsSendAlert:
                esp->es_server.ea_state = eapTlsRecvAlertAck;
                break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        case eapSRP1:
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                ts = (struct t_server *)esp->es_server.ea_session;
                if (ts != NULL && status != 0) {
                        t_serverclose(ts);
                        esp->es_server.ea_session = NULL;
                        esp->es_server.ea_skey = NULL;
                }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
                if (status == 1) {
                        esp->es_server.ea_state = eapMD5Chall;
                } else if (status != 0 || esp->es_server.ea_session == NULL) {
@@ -679,14 +679,14 @@ int status;
                break;
 
        case eapSRP2:
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                ts = (struct t_server *)esp->es_server.ea_session;
                if (ts != NULL && status != 0) {
                        t_serverclose(ts);
                        esp->es_server.ea_session = NULL;
                        esp->es_server.ea_skey = NULL;
                }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
                if (status != 0 || esp->es_server.ea_session == NULL) {
                        esp->es_server.ea_state = eapBadAuth;
                } else {
@@ -696,14 +696,14 @@ int status;
 
        case eapSRP3:
        case eapSRP4:
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                ts = (struct t_server *)esp->es_server.ea_session;
                if (ts != NULL && status != 0) {
                        t_serverclose(ts);
                        esp->es_server.ea_session = NULL;
                        esp->es_server.ea_skey = NULL;
                }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
                if (status != 0 || esp->es_server.ea_session == NULL) {
                        esp->es_server.ea_state = eapBadAuth;
                } else {
@@ -711,7 +711,7 @@ int status;
                }
                break;
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
        case eapMSCHAPv2Chall:
 #endif
        case eapMD5Chall:
@@ -729,98 +729,12 @@ int status;
        if (esp->es_server.ea_state == eapBadAuth)
                eap_send_failure(esp);
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state));
-#endif /* USE_EAPTLS */
-}
-
-#if CHAPMS
-static int
-eap_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;
+#endif /* PPP_WITH_EAPTLS */
 }
 
-static struct chap_digest_type eap_chapms2_digest = {
-       CHAP_MICROSOFT_V2,      /* code */
-       NULL, /* chapms2_generate_challenge, */
-       eap_chapms2_verify_response,
-       NULL, /* chapms2_make_response, */
-       NULL, /* chapms2_check_success, */
-       NULL, /* chapms_handle_failure, */
-};
-
+#if PPP_WITH_CHAPMS
 /*
  * eap_chap_verify_response - check whether the peer's response matches
  * what we think it should be.  Returns 1 if it does (authentication
@@ -888,15 +802,14 @@ eap_chapms2_send_request(eap_state *esp, u_char id,
                auth_peer_fail(esp->es_unit, PPP_EAP);
        }
 }
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
 /*
  * Format an EAP Request message and send it to the peer.  Message
  * type depends on current state.  (Server operation)
  */
 static void
-eap_send_request(esp)
-eap_state *esp;
+eap_send_request(eap_state *esp)
 {
        u_char *outp;
        u_char *lenloc;
@@ -904,13 +817,13 @@ eap_state *esp;
        int outlen;
        int challen;
        char *str;
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
        struct t_server *ts;
-       u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
-       int i, j;
+       u_char clear[8], cipher[8], dig[SHA_DIGEST_LENGTH], *optr, *cp, key[SHA_DIGEST_LENGTH];
+       int i, j, diglen, clen, keylen = sizeof(key);
        struct b64state b64;
-       SHA1_CTX ctxt;
-#endif /* USE_SRP */
+       PPP_MD_CTX *ctxt;
+#endif /* PPP_WITH_SRP */
 
        /* Handle both initial auth and restart */
        if (esp->es_server.ea_state < eapIdentify &&
@@ -976,12 +889,11 @@ eap_state *esp;
                INCPTR(esp->es_server.ea_namelen, outp);
                break;
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
        case eapMSCHAPv2Chall:
-               challen = 0x10;
+               esp->es_server.digest->generate_challenge(esp->es_challenge);
+               challen = esp->es_challenge[0];
                esp->es_challen = challen;
-               esp->es_challenge[0] = challen;
-               random_bytes(&esp->es_challenge[1], challen);
 
                PUTCHAR(EAPT_MSCHAPV2, outp);
                PUTCHAR(CHAP_CHALLENGE, outp);
@@ -998,9 +910,9 @@ eap_state *esp;
                                esp->es_server.ea_namelen);
                INCPTR(esp->es_server.ea_namelen, outp);
                break;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        case eapTlsStart:
                PUTCHAR(EAPT_TLS, outp);
                PUTCHAR(EAP_TLS_FLAGS_START, outp);
@@ -1022,9 +934,9 @@ eap_state *esp;
                eaptls_send(esp->es_server.ea_session, &outp);
                eap_figure_next_state(esp, 0);
                break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
        case eapSRP1:
                PUTCHAR(EAPT_SRP, outp);
                PUTCHAR(EAPSRP_CHALLENGE, outp);
@@ -1070,10 +982,10 @@ eap_state *esp;
                PUTLONG(SRPVAL_EBIT, outp);
                ts = (struct t_server *)esp->es_server.ea_session;
                assert(ts != NULL);
-               BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
-               INCPTR(SHA_DIGESTSIZE, outp);
+               BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH);
+               INCPTR(SHA_DIGEST_LENGTH, outp);
 
-               if (pncrypt_setkey(0)) {
+               if (pncrypt_getkey(0, key, keylen)) {
                        /* Generate pseudonym */
                        optr = outp;
                        cp = (unsigned char *)esp->es_server.ea_peer;
@@ -1083,15 +995,17 @@ eap_state *esp;
                        BCOPY(cp, clear + 1, j);
                        i -= j;
                        cp += j;
-                       if (!DesEncrypt(clear, cipher)) {
+
+                       if (!DesEncrypt(clear, key, cipher)) {
                                dbglog("no DES here; not generating pseudonym");
                                break;
-                       }
+            }
+
                        BZERO(&b64, sizeof (b64));
                        outp++;         /* space for pseudonym length */
                        outp += b64enc(&b64, cipher, 8, outp);
                        while (i >= 8) {
-                               (void) DesEncrypt(cp, cipher);
+                               DesEncrypt(cp, key, cipher);
                                outp += b64enc(&b64, cipher, 8, outp);
                                cp += 8;
                                i -= 8;
@@ -1103,7 +1017,8 @@ eap_state *esp;
                                        *cp++ = drand48() * 0x100;
                                        i++;
                                }
-                               (void) DesEncrypt(clear, cipher);
+
+                               DesEncrypt(clear, key, cipher);
                                outp += b64enc(&b64, cipher, 8, outp);
                        }
                        outp += b64flush(&b64, outp);
@@ -1111,32 +1026,40 @@ eap_state *esp;
                        /* Set length and pad out to next 20 octet boundary */
                        i = outp - optr - 1;
                        *optr = i;
-                       i %= SHA_DIGESTSIZE;
+                       i %= SHA_DIGEST_LENGTH;
                        if (i != 0) {
-                               while (i < SHA_DIGESTSIZE) {
+                               while (i < SHA_DIGEST_LENGTH) {
                                        *outp++ = drand48() * 0x100;
                                        i++;
                                }
                        }
 
                        /* Obscure the pseudonym with SHA1 hash */
-                       SHA1Init(&ctxt);
-                       SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
-                       SHA1Update(&ctxt, esp->es_server.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, esp->es_server.ea_peer,
-                           esp->es_server.ea_peerlen);
-                       while (optr < outp) {
-                               SHA1Final(dig, &ctxt);
-                               cp = dig;
-                               while (cp < dig + SHA_DIGESTSIZE)
-                                       *optr++ ^= *cp++;
-                               SHA1Init(&ctxt);
-                               SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
-                               SHA1Update(&ctxt, esp->es_server.ea_skey,
-                                   SESSION_KEY_LEN);
-                               SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
-                                   SHA_DIGESTSIZE);
+                       ctxt = PPP_MD_CTX_new();
+                       if (ctxt) {
+
+                               PPP_DigestInit(ctxt, PPP_sha1());
+                               PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
+                               PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
+                                       SESSION_KEY_LEN);
+                               PPP_DigestUpdate(ctxt,  esp->es_server.ea_peer,
+                                       esp->es_server.ea_peerlen);
+                               while (optr < outp) {
+                                       diglen = SHA_DIGEST_LENGTH;
+                                       PPP_DigestFinal(ctxt, dig, &diglen);
+                                       cp = dig;
+                                       while (cp < dig + SHA_DIGEST_LENGTH)
+                                               *optr++ ^= *cp++;
+
+                                       PPP_DigestInit(ctxt, PPP_sha1());
+                                       PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
+                                       PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
+                                               SESSION_KEY_LEN);
+                                       PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
+                                               SHA_DIGEST_LENGTH);
+                               }
+
+                               PPP_MD_CTX_free(ctxt);
                        }
                }
                break;
@@ -1153,7 +1076,7 @@ eap_state *esp;
                BCOPY(esp->es_challenge, outp, esp->es_challen);
                INCPTR(esp->es_challen, outp);
                break;
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
        default:
                return;
@@ -1177,9 +1100,7 @@ eap_state *esp;
  * after eap_lowerup.
  */
 void
-eap_authpeer(unit, localname)
-int unit;
-char *localname;
+eap_authpeer(int unit, char *localname)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -1207,21 +1128,20 @@ char *localname;
  * expired.
  */
 static void
-eap_server_timeout(arg)
-void *arg;
+eap_server_timeout(void *arg)
 {
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        u_char *outp;
        u_char *lenloc;
        int outlen;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        eap_state *esp = (eap_state *) arg;
 
        if (!eap_server_active(esp))
                return;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        switch(esp->es_server.ea_prev_state) {
 
        /*
@@ -1259,7 +1179,7 @@ void *arg;
        default:
                break;
        }
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        /* EAP ID number must not change on timeout. */
        eap_send_request(esp);
@@ -1271,8 +1191,7 @@ void *arg;
  * will restart the timer.  If it fails, then the link is dropped.
  */
 static void
-eap_rechallenge(arg)
-void *arg;
+eap_rechallenge(void *arg)
 {
        eap_state *esp = (eap_state *)arg;
 
@@ -1288,8 +1207,7 @@ void *arg;
 }
 
 static void
-srp_lwrechallenge(arg)
-void *arg;
+srp_lwrechallenge(void *arg)
 {
        eap_state *esp = (eap_state *)arg;
 
@@ -1312,8 +1230,7 @@ void *arg;
  * thing.
  */
 static void
-eap_lowerup(unit)
-int unit;
+eap_lowerup(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -1336,8 +1253,7 @@ int unit;
  * Cancel all timeouts and return to initial state.
  */
 static void
-eap_lowerdown(unit)
-int unit;
+eap_lowerdown(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -1371,8 +1287,7 @@ int unit;
  * failure.
  */
 static void
-eap_protrej(unit)
-int unit;
+eap_protrej(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -1391,12 +1306,8 @@ int unit;
  * Format and send a regular EAP Response message.
  */
 static void
-eap_send_response(esp, id, typenum, str, lenstr)
-eap_state *esp;
-u_char id;
-u_char typenum;
-u_char *str;
-int lenstr;
+eap_send_response(eap_state *esp, u_char id, u_char typenum,
+                 u_char *str, int lenstr)
 {
        u_char *outp;
        int msglen;
@@ -1422,30 +1333,26 @@ int lenstr;
  * Format and send an MD5-Challenge EAP Response message.
  */
 static void
-eap_chap_response(esp, id, hash, name, namelen)
-eap_state *esp;
-u_char id;
-u_char *hash;
-char *name;
-int namelen;
+eap_chap_response(eap_state *esp, u_char id, u_char *hash,
+                 char *name, int namelen)
 {
        u_char *outp;
        int msglen;
 
        outp = outpacket_buf;
-    
+
        MAKEHEADER(outp, PPP_EAP);
 
        PUTCHAR(EAP_RESPONSE, outp);
        PUTCHAR(id, outp);
        esp->es_client.ea_id = id;
-       msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
+       msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_DIGEST_LENGTH +
            namelen;
        PUTSHORT(msglen, outp);
        PUTCHAR(EAPT_MD5CHAP, outp);
-       PUTCHAR(MD5_SIGNATURE_SIZE, outp);
-       BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
-       INCPTR(MD5_SIGNATURE_SIZE, outp);
+       PUTCHAR(MD5_DIGEST_LENGTH, outp);
+       BCOPY(hash, outp, MD5_DIGEST_LENGTH);
+       INCPTR(MD5_DIGEST_LENGTH, outp);
        if (namelen > 0) {
                BCOPY(name, outp, namelen);
        }
@@ -1453,17 +1360,13 @@ int namelen;
        output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
 }
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
 /*
  * Format and send a SRP EAP Response message.
  */
 static void
-eap_srp_response(esp, id, subtypenum, str, lenstr)
-eap_state *esp;
-u_char id;
-u_char subtypenum;
-u_char *str;
-int lenstr;
+eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
+                u_char *str, int lenstr)
 {
        u_char *outp;
        int msglen;
@@ -1490,11 +1393,7 @@ int lenstr;
  * Format and send a SRP EAP Client Validator Response message.
  */
 static void
-eap_srpval_response(esp, id, flags, str)
-eap_state *esp;
-u_char id;
-u_int32_t flags;
-u_char *str;
+eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
 {
        u_char *outp;
        int msglen;
@@ -1507,25 +1406,23 @@ u_char *str;
        PUTCHAR(id, outp);
        esp->es_client.ea_id = id;
        msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
-           SHA_DIGESTSIZE;
+           SHA_DIGEST_LENGTH;
        PUTSHORT(msglen, outp);
        PUTCHAR(EAPT_SRP, outp);
        PUTCHAR(EAPSRP_CVALIDATOR, outp);
        PUTLONG(flags, outp);
-       BCOPY(str, outp, SHA_DIGESTSIZE);
+       BCOPY(str, outp, SHA_DIGEST_LENGTH);
 
        output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
 }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
 /*
  * Send an EAP-TLS response message with tls data
  */
 static void
-eap_tls_response(esp, id)
-eap_state *esp;
-u_char id;
+eap_tls_response(eap_state *esp, u_char id)
 {
        u_char *outp;
        int outlen;
@@ -1562,9 +1459,7 @@ u_char id;
  * Send an EAP-TLS ack
  */
 static void
-eap_tls_sendack(esp, id)
-eap_state *esp;
-u_char id;
+eap_tls_sendack(eap_state *esp, u_char id)
 {
        u_char *outp;
        int outlen;
@@ -1589,13 +1484,10 @@ u_char id;
 
        output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
 }
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
 static void
-eap_send_nak(esp, id, type)
-eap_state *esp;
-u_char id;
-u_char type;
+eap_send_nak(eap_state *esp, u_char id, u_char type)
 {
        u_char *outp;
        int msglen;
@@ -1615,9 +1507,9 @@ u_char type;
        output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
 }
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
 static char *
-name_of_pn_file()
+name_of_pn_file(void)
 {
        char *user, *path, *file;
        struct passwd *pw;
@@ -1629,7 +1521,7 @@ name_of_pn_file()
                errno = EINVAL;
                return (NULL);
        }
-       file = _PATH_PSEUDONYM;
+       file = PPP_PATH_PSEUDONYM;
        pl = strlen(user) + strlen(file) + 2;
        path = malloc(pl);
        if (path == NULL)
@@ -1643,8 +1535,7 @@ name_of_pn_file()
 }
 
 static int
-open_pn_file(modebits)
-mode_t modebits;
+open_pn_file(mode_t modebits)
 {
        char *path;
        int fd, err;
@@ -1659,7 +1550,7 @@ mode_t modebits;
 }
 
 static void
-remove_pn_file()
+remove_pn_file(void)
 {
        char *path;
 
@@ -1670,16 +1561,13 @@ remove_pn_file()
 }
 
 static void
-write_pseudonym(esp, inp, len, id)
-eap_state *esp;
-u_char *inp;
-int len, id;
+write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
 {
        u_char val;
        u_char *datp, *digp;
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
-       int dsize, fd, olen = len;
+       PPP_MD_CTX *ctxt;
+       u_char dig[SHA_DIGEST_LENGTH];
+       int dsize, fd, olen = len, diglen = sizeof(dig);
 
        /*
         * Do the decoding by working backwards.  This eliminates the need
@@ -1687,22 +1575,30 @@ int len, id;
         */
        val = id;
        while (len > 0) {
-               if ((dsize = len % SHA_DIGESTSIZE) == 0)
-                       dsize = SHA_DIGESTSIZE;
+               if ((dsize = len % SHA_DIGEST_LENGTH) == 0)
+                       dsize = SHA_DIGEST_LENGTH;
                len -= dsize;
                datp = inp + len;
-               SHA1Init(&ctxt);
-               SHA1Update(&ctxt, &val, 1);
-               SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
-               if (len > 0) {
-                       SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
-               } else {
-                       SHA1Update(&ctxt, esp->es_client.ea_name,
-                           esp->es_client.ea_namelen);
+               ctxt = PPP_MD_CTX_new();
+               if (ctxt) {
+
+                       PPP_DigestInit(ctxt, PPP_sha1());
+                       PPP_DigestUpdate(ctxt, &val, 1);
+                       PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
+                                       SESSION_KEY_LEN);
+                       if (len > 0) {
+                               PPP_DigestUpdate(ctxt, datp, SHA_DIGEST_LENGTH);
+                       } else {
+                               PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
+                                       esp->es_client.ea_namelen);
+                       }
+                       PPP_DigestFinal(ctxt, dig, &diglen);
+
+                       for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
+                               *datp++ ^= *digp;
+
+                       PPP_MD_CTX_free(ctxt);
                }
-               SHA1Final(dig, &ctxt);
-               for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
-                       *datp++ ^= *digp;
        }
 
        /* Now check that the result is sane */
@@ -1726,38 +1622,69 @@ int len, id;
                remove_pn_file();
        }
 }
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
+
+#if PPP_WITH_CHAPMS
+/*
+ * Format and send an CHAPV2-Challenge EAP Response message.
+ */
+static void
+eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
+{
+    u_char *outp;
+    int msglen;
+
+    outp = outpacket_buf;
+
+    MAKEHEADER(outp, PPP_EAP);
+
+    PUTCHAR(EAP_RESPONSE, outp);
+    PUTCHAR(id, outp);
+    esp->es_client.ea_id = id;
+    msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
+    PUTSHORT(msglen, outp);
+    PUTCHAR(EAPT_MSCHAPV2, outp);
+    PUTCHAR(CHAP_RESPONSE, outp);
+    PUTCHAR(chapid, outp);
+    PUTCHAR(0, outp);
+    /* len */
+    PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
+    BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
+    INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
+    BCOPY(user, outp, user_len);
+
+    output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
+}
+#endif
 
 /*
  * eap_request - Receive EAP Request message (client mode).
  */
 static void
-eap_request(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_request(eap_state *esp, u_char *inp, int id, int len)
 {
        u_char typenum;
        u_char vallen;
        int secret_len;
        char secret[MAXWORDLEN];
        char rhostname[256];
-       MD5_CTX mdContext;
-       u_char hash[MD5_SIGNATURE_SIZE];
-#ifdef USE_EAPTLS
+       PPP_MD_CTX *mdctx;
+       u_char hash[MD5_DIGEST_LENGTH];
+       int hashlen = MD5_DIGEST_LENGTH;
+#ifdef PPP_WITH_EAPTLS
        u_char flags;
        struct eaptls_session *ets = esp->es_client.ea_session;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
        struct t_client *tc;
        struct t_num sval, gval, Nval, *Ap, Bval;
        u_char vals[2];
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
+       PPP_MD_CTX *ctxt;
+       u_char dig[SHA_DIGEST_LENGTH];
+       int diglen = sizeof(dig);
        int fd;
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
        /*
         * Ignore requests if we're not open
@@ -1794,7 +1721,7 @@ int len;
        case EAPT_IDENTITY:
                if (len > 0)
                        info("EAP: Identity prompt \"%.*q\"", len, inp);
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
                if (esp->es_usepseudo &&
                    (esp->es_usedpseudo == 0 ||
                        (esp->es_usedpseudo == 1 &&
@@ -1820,8 +1747,8 @@ int len;
                        remove_pn_file();
                        esp->es_usedpseudo = 2;
                }
-#endif /* USE_SRP */
-               eap_send_response(esp, id, typenum, esp->es_client.ea_name,
+#endif /* PPP_WITH_SRP */
+               eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
                    esp->es_client.ea_namelen);
                break;
 
@@ -1881,18 +1808,32 @@ int len;
                        eap_send_nak(esp, id, EAPT_SRP);
                        break;
                }
-               MD5_Init(&mdContext);
-               typenum = id;
-               MD5_Update(&mdContext, &typenum, 1);
-               MD5_Update(&mdContext, (u_char *)secret, secret_len);
-               BZERO(secret, sizeof (secret));
-               MD5_Update(&mdContext, inp, vallen);
-               MD5_Final(hash, &mdContext);
-               eap_chap_response(esp, id, hash, esp->es_client.ea_name,
-                   esp->es_client.ea_namelen);
+
+               mdctx = PPP_MD_CTX_new();
+               if (mdctx != NULL) {
+                       if (PPP_DigestInit(mdctx, PPP_md5())) {
+                               typenum = id;
+                               if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
+                                       if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
+                                               BZERO(secret, sizeof(secret));
+                                               if (PPP_DigestUpdate(mdctx, inp, vallen)) {
+                                                       if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
+                                                               eap_chap_response(esp, id, hash, esp->es_client.ea_name,
+                                                                               esp->es_client.ea_namelen);
+                                                               PPP_MD_CTX_free(mdctx);
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       PPP_MD_CTX_free(mdctx);
+               }
+               dbglog("EAP: Invalid MD5 checksum");
+        eap_send_nak(esp, id, EAPT_SRP);
                break;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        case EAPT_TLS:
 
                switch(esp->es_client.ea_state) {
@@ -1918,7 +1859,7 @@ int len;
                                /* Init ssl session */
                                if(!eaptls_init_ssl_client(esp)) {
                                        dbglog("cannot init ssl");
-                                       eap_send_nak(esp, id, EAPT_TLS);
+                                       eap_send_nak(esp, id, EAPT_MSCHAPV2);
                                        esp->es_client.ea_using_eaptls = 0;
                                        break;
                                }
@@ -1930,7 +1871,7 @@ int len;
                        }
 
                        /* The server has sent a bad start packet. */
-                       eap_send_nak(esp, id, EAPT_TLS);
+                       eap_send_nak(esp, id, EAPT_MSCHAPV2);
                        break;
 
                case eapTlsRecvAck:
@@ -1960,7 +1901,7 @@ int len;
 
                        /* Check if TLS handshake is finished */
                        if(eaptls_is_init_finished(ets)) {
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
                                eaptls_gen_mppe_keys(ets, 1);
 #endif
                                eaptls_free_session(ets);
@@ -1974,15 +1915,15 @@ int len;
                        break;
 
                default:
-                       eap_send_nak(esp, id, EAPT_TLS);
+                       eap_send_nak(esp, id, EAPT_MSCHAPV2);
                        esp->es_client.ea_using_eaptls = 0;
                        break;
                }
 
                break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
        case EAPT_SRP:
                if (len < 1) {
                        error("EAP: received empty SRP Request");
@@ -2166,7 +2107,7 @@ int len;
                                            esp->es_client.ea_id, id);
                                }
                        } else {
-                               len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
+                               len -= sizeof (u_int32_t) + SHA_DIGEST_LENGTH;
                                if (len < 0 || t_clientverify(tc, inp +
                                        sizeof (u_int32_t)) != 0) {
                                        error("EAP: SRP server verification "
@@ -2176,7 +2117,7 @@ int len;
                                GETLONG(esp->es_client.ea_keyflags, inp);
                                /* Save pseudonym if user wants it. */
                                if (len > 0 && esp->es_usepseudo) {
-                                       INCPTR(SHA_DIGESTSIZE, inp);
+                                       INCPTR(SHA_DIGEST_LENGTH, inp);
                                        write_pseudonym(esp, inp, len, id);
                                }
                        }
@@ -2193,17 +2134,24 @@ int len;
                                warn("EAP: malformed Lightweight rechallenge");
                                return;
                        }
-                       SHA1Init(&ctxt);
-                       vals[0] = id;
-                       SHA1Update(&ctxt, vals, 1);
-                       SHA1Update(&ctxt, esp->es_client.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, inp, len);
-                       SHA1Update(&ctxt, esp->es_client.ea_name,
-                           esp->es_client.ea_namelen);
-                       SHA1Final(dig, &ctxt);
-                       eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
-                           SHA_DIGESTSIZE);
+                       ctxt = PPP_MD_CTX_new();
+                       if (ctxt) {
+
+                               vals[0] = id;
+                               PPP_DigestInit(ctxt, PPP_sha1());
+                               PPP_DigestUpdate(ctxt, vals, 1);
+                               PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
+                                       SESSION_KEY_LEN);
+                               PPP_DigestUpdate(ctxt, inp, len);
+                               PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
+                                       esp->es_client.ea_namelen);
+                               PPP_DigestFinal(ctxt, dig, &diglen);
+
+                               PPP_MD_CTX_free(ctxt);
+
+                               eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
+                                       SHA_DIGEST_LENGTH);
+                       }
                        break;
 
                default:
@@ -2212,7 +2160,137 @@ int len;
                        break;
                }
                break;
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
+
+#ifdef PPP_WITH_CHAPMS
+        case EAPT_MSCHAPV2:
+           if (len < 4) {
+               error("EAP: received invalid MSCHAPv2 packet, too short");
+               return;
+           }
+           unsigned char opcode;
+           GETCHAR(opcode, inp);
+           unsigned char chapid; /* Chapv2-ID */
+           GETCHAR(chapid, inp);
+           short mssize;
+           GETSHORT(mssize, inp);
+
+           /* Validate the mssize field */
+           if (len != mssize) { 
+               error("EAP: received invalid MSCHAPv2 packet, invalid length");
+               return;
+           }
+           len -= 4;
+
+           /* If MSCHAPv2 digest was not found, NAK the packet */
+           if (!esp->es_client.digest) {
+               error("EAP MSCHAPv2 not supported");
+               eap_send_nak(esp, id, EAPT_SRP);
+               return;
+           }
+
+           switch (opcode) {
+           case CHAP_CHALLENGE: {
+
+               /* make_response() expects: VLEN + VALUE */
+               u_char *challenge = inp;
+
+               unsigned char vsize;
+               GETCHAR(vsize, inp);
+                len -= 1;
+
+               /* Validate the VALUE field */
+                if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
+                    error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
+                    return;
+                }
+
+               /* Increment past the VALUE field */
+               INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
+               len -= MS_CHAP2_PEER_CHAL_LEN;
+
+               /* Extract the hostname */
+               rhostname[0] = '\0';
+               if (len > 0) {
+                   if (len >= sizeof (rhostname)) {
+                       dbglog("EAP: trimming really long peer name down");
+                       len = sizeof(rhostname) - 1;
+                   }
+                   BCOPY(inp, rhostname, len);
+                   rhostname[len] = '\0';
+               }
+
+               /* In case the remote doesn't give us his name. */
+               if (explicit_remote || (remote_name[0] != '\0' && len == 0))
+                   strlcpy(rhostname, remote_name, sizeof(rhostname));
+
+               /* Get the secret for authenticating ourselves with the specified host. */
+               if (!get_secret(esp->es_unit, esp->es_client.ea_name,
+                   rhostname, secret, &secret_len, 0)) {
+                   dbglog("EAP: no CHAP secret for auth to %q", rhostname);
+                   eap_send_nak(esp, id, EAPT_SRP);
+                   break;
+               }
+               esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
+
+               /* Create the MSCHAPv2 response (and add to cache) */
+               unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
+               esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
+                       challenge, secret, secret_len, NULL);
+
+               eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
+               break;
+           }
+           case CHAP_SUCCESS: {
+
+               /* Check response for mutual authentication */
+               u_char status = CHAP_FAILURE;
+               if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
+                    info("Chap authentication succeeded! %.*v", len, inp);
+                    status = CHAP_SUCCESS;
+               }
+               eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
+               break;
+           }
+           case CHAP_FAILURE: {
+
+               /* Process the failure string, and log appropriate information */
+               esp->es_client.digest->handle_failure(inp, len);
+
+               u_char status = CHAP_FAILURE;
+               eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
+               goto client_failure; /* force termination */
+           }
+           default:
+
+                error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
+               eap_send_nak(esp, id, EAPT_SRP);
+           }
+
+           break;
+#endif /* PPP_WITH_CHAPMS */
+#ifdef PPP_WITH_PEAP
+       case EAPT_PEAP:
+
+               /* Initialize the PEAP context (if not already initialized) */
+               if (!esp->ea_peap) {
+                       rhostname[0] = '\0';
+                       if (explicit_remote || (remote_name[0] != '\0')) {
+                               strlcpy(rhostname, remote_name, sizeof (rhostname));
+                       }
+                       if (peap_init(&esp->ea_peap, rhostname)) {
+                               eap_send_nak(esp, id, EAPT_TLS);
+                               break;
+                       }
+               }
+
+               /* Process the PEAP packet */
+               if (peap_process(esp, id, inp, len)) {
+                       eap_send_nak(esp, id, EAPT_TLS);
+               }
+
+               break;
+#endif // PPP_WITH_PEAP
 
        default:
                info("EAP: unknown authentication type %d; Naking", typenum);
@@ -2227,54 +2305,49 @@ int len;
        }
        return;
 
-#ifdef USE_SRP
 client_failure:
        esp->es_client.ea_state = eapBadAuth;
        if (esp->es_client.ea_timeout > 0) {
                UNTIMEOUT(eap_client_timeout, (void *)esp);
        }
        esp->es_client.ea_session = NULL;
+#ifdef PPP_WITH_SRP
        t_clientclose(tc);
        auth_withpeer_fail(esp->es_unit, PPP_EAP);
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 }
 
 /*
  * eap_response - Receive EAP Response message (server mode).
  */
 static void
-eap_response(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_response(eap_state *esp, u_char *inp, int id, int len)
 {
        u_char typenum;
        u_char vallen;
        int secret_len;
        char secret[MAXSECRETLEN];
        char rhostname[256];
-       MD5_CTX mdContext;
-       u_char hash[MD5_SIGNATURE_SIZE];
-#ifdef USE_SRP
+       PPP_MD_CTX *mdctx;
+       u_char hash[MD5_DIGEST_LENGTH];
+       int hashlen = MD5_DIGEST_LENGTH;
+#ifdef PPP_WITH_SRP
        struct t_server *ts;
        struct t_num A;
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
-#endif /* USE_SRP */
+       PPP_MD_CTX *ctxt;
+       u_char dig[SHA_DIGEST_LENGTH];
+       int diglen = sizeof(dig);
+#endif /* PPP_WITH_SRP */
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        struct eaptls_session *ets;
        u_char flags;
-#endif /* USE_EAPTLS */
-#ifdef CHAPMS
+#endif /* PPP_WITH_EAPTLS */
+#ifdef PPP_WITH_CHAPMS
        u_char opcode;
-       int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
-               unsigned char *, unsigned char *, char *, int);
+        chap_verify_hook_fn *chap_verifier;
        char response_message[256];
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
        /*
         * Ignore responses if we're not open
@@ -2321,7 +2394,7 @@ int len;
                eap_figure_next_state(esp, 0);
                break;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        case EAPT_TLS:
                switch(esp->es_server.ea_state) {
 
@@ -2351,7 +2424,7 @@ int len;
                                GETCHAR(flags, inp);
 
                                if(len == 1 && !flags) {        /* Ack = ok */
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
                                        eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
 #endif
                                        eap_send_success(esp);
@@ -2377,7 +2450,7 @@ int len;
                        break;
                }
                break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        case EAPT_NOTIFICATION:
                dbglog("EAP unexpected Notification; response discarded");
@@ -2410,19 +2483,25 @@ int len;
                        esp->es_server.ea_state = eapMD5Chall;
                        break;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
                        /* Send EAP-TLS start packet */
                case EAPT_TLS:
                        esp->es_server.ea_state = eapTlsStart;
                        break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
                case EAPT_MSCHAPV2:
                        info("EAP: peer proposes MSCHAPv2");
+                       /* If MSCHAPv2 digest was not found, NAK the packet */
+                       if (!esp->es_server.digest) {
+                               error("EAP MSCHAPv2 not supported");
+                               eap_send_nak(esp, id, EAPT_SRP);
+                               break;
+                       }
                        esp->es_server.ea_state = eapMSCHAPv2Chall;
                        break;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
                default:
                        dbglog("EAP: peer requesting unknown Type %d", vallen);
@@ -2488,24 +2567,45 @@ int len;
                        eap_send_failure(esp);
                        break;
                }
-               MD5_Init(&mdContext);
-               MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
-               MD5_Update(&mdContext, (u_char *)secret, secret_len);
-               BZERO(secret, sizeof (secret));
-               MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
-               MD5_Final(hash, &mdContext);
-               if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
-                       eap_send_failure(esp);
-                       break;
+
+               mdctx = PPP_MD_CTX_new();
+               if (mdctx != NULL) {
+
+                       if (PPP_DigestInit(mdctx, PPP_md5())) {
+
+                               if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
+
+                                       if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
+
+                                               BZERO(secret, sizeof(secret));
+                                               if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
+
+                                                       if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
+
+                                                               if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) {
+                                                                       esp->es_server.ea_type = EAPT_MD5CHAP;
+                                                                       eap_send_success(esp);
+                                                                       eap_figure_next_state(esp, 0);
+
+                                                                       if (esp->es_rechallenge != 0) {
+                                                                               TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
+                                                                       }
+                                                                       PPP_MD_CTX_free(mdctx);
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       PPP_MD_CTX_free(mdctx);
                }
-               esp->es_server.ea_type = EAPT_MD5CHAP;
-               eap_send_success(esp);
-               eap_figure_next_state(esp, 0);
-               if (esp->es_rechallenge != 0)
-                       TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
+
+               eap_send_failure(esp);
                break;
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
        case EAPT_MSCHAPV2:
                if (len < 1) {
                        error("EAP: received MSCHAPv2 with no data");
@@ -2549,6 +2649,14 @@ int len;
                                        (remote_name[0] != '\0' && vallen == len))
                                strlcpy(rhostname, remote_name, sizeof (rhostname));
 
+                       /* strip the MS domain name */
+                       if (chapms_strip_domain && strrchr(rhostname, '\\')) {
+                               char tmp[MAXNAMELEN+1];
+
+                               strcpy(tmp, strrchr(rhostname, '\\') + 1);
+                               strlcpy(rhostname, tmp, sizeof(rhostname));
+                       }
+
                        if (chap_verify_hook)
                                chap_verifier = chap_verify_hook;
                        else
@@ -2558,7 +2666,7 @@ int len;
                        if ((*chap_verifier)(rhostname,
                                                esp->es_server.ea_name,
                                                id,
-                                               &eap_chapms2_digest,
+                                               esp->es_server.digest,
                                                esp->es_challenge,
                                                inp - 1,
                                                response_message,
@@ -2600,9 +2708,9 @@ int len;
                }
 
                break;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
-#ifdef USE_SRP
+#ifdef PPP_WITH_SRP
        case EAPT_SRP:
                if (len < 1) {
                        error("EAP: empty SRP Response");
@@ -2638,9 +2746,9 @@ int len;
                                eap_figure_next_state(esp, 1);
                                break;
                        }
-                       if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
+                       if (len < sizeof (u_int32_t) + SHA_DIGEST_LENGTH) {
                                error("EAP: M1 length %d < %d", len,
-                                   sizeof (u_int32_t) + SHA_DIGESTSIZE);
+                                   sizeof (u_int32_t) + SHA_DIGEST_LENGTH);
                                eap_figure_next_state(esp, 1);
                                break;
                        }
@@ -2677,33 +2785,41 @@ int len;
                                info("EAP: unexpected SRP Subtype 4 Response");
                                return;
                        }
-                       if (len != SHA_DIGESTSIZE) {
+                       if (len != SHA_DIGEST_LENGTH) {
                                error("EAP: bad Lightweight rechallenge "
                                    "response");
                                return;
                        }
-                       SHA1Init(&ctxt);
-                       vallen = id;
-                       SHA1Update(&ctxt, &vallen, 1);
-                       SHA1Update(&ctxt, esp->es_server.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
-                       SHA1Update(&ctxt, esp->es_server.ea_peer,
-                           esp->es_server.ea_peerlen);
-                       SHA1Final(dig, &ctxt);
-                       if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
-                               error("EAP: failed Lightweight rechallenge");
-                               eap_send_failure(esp);
-                               break;
+                       ctxt = PPP_MD_CTX_new();
+                       if (ctxt) {
+                               vallen = id;
+
+                               PPP_DigestInit(ctxt, PPP_sha1());
+                               PPP_DigestUpdate(ctxt, &vallen, 1);
+                               PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
+                                       SESSION_KEY_LEN);
+                               PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen);
+                               PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
+                                       esp->es_server.ea_peerlen);
+                               PPP_DigestFinal(ctxt, dig, &diglen);
+
+                               PPP_MD_CTX_free(ctxt);
+
+                               if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) {
+                                       error("EAP: failed Lightweight rechallenge");
+                                       eap_send_failure(esp);
+                                       break;
+                               }
+
+                               esp->es_server.ea_state = eapOpen;
+                               if (esp->es_lwrechallenge != 0)
+                                       TIMEOUT(srp_lwrechallenge, esp,
+                                               esp->es_lwrechallenge);
                        }
-                       esp->es_server.ea_state = eapOpen;
-                       if (esp->es_lwrechallenge != 0)
-                               TIMEOUT(srp_lwrechallenge, esp,
-                                   esp->es_lwrechallenge);
                        break;
                }
                break;
-#endif /* USE_SRP */
+#endif /* PPP_WITH_SRP */
 
        default:
                /* This can't happen. */
@@ -2726,16 +2842,12 @@ int len;
  * eap_success - Receive EAP Success message (client mode).
  */
 static void
-eap_success(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_success(eap_state *esp, u_char *inp, int id, int len)
 {
        if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
                && esp->es_client.ea_state != eapTlsRecvSuccess
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
                ) {
                dbglog("EAP unexpected success message in state %s (%d)",
                    eap_state_name(esp->es_client.ea_state),
@@ -2743,7 +2855,7 @@ int len;
                return;
        }
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
                eapTlsRecvSuccess) {
                dbglog("EAP-TLS unexpected success message in state %s (%d)",
@@ -2751,7 +2863,7 @@ int len;
                     esp->es_client.ea_state);
                return;
        }
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
        if (esp->es_client.ea_timeout > 0) {
                UNTIMEOUT(eap_client_timeout, (void *)esp);
@@ -2762,6 +2874,10 @@ int len;
                PRINTMSG(inp, len);
        }
 
+#ifdef PPP_WITH_PEAP
+       peap_finish(&esp->ea_peap);
+#endif
+
        esp->es_client.ea_state = eapOpen;
        auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
 }
@@ -2770,11 +2886,7 @@ int len;
  * eap_failure - Receive EAP Failure message (client mode).
  */
 static void
-eap_failure(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_failure(eap_state *esp, u_char *inp, int id, int len)
 {
        /*
         * Ignore failure messages if we're not open
@@ -2800,6 +2912,11 @@ int len;
        esp->es_client.ea_state = eapBadAuth;
 
        error("EAP: peer reports authentication failure");
+
+#ifdef PPP_WITH_PEAP
+       peap_finish(&esp->ea_peap);
+#endif
+
        auth_withpeer_fail(esp->es_unit, PPP_EAP);
 }
 
@@ -2807,10 +2924,7 @@ int len;
  * eap_input - Handle received EAP message.
  */
 static void
-eap_input(unit, inp, inlen)
-int unit;
-u_char *inp;
-int inlen;
+eap_input(int unit, u_char *inp, int inlen)
 {
        eap_state *esp = &eap_states[unit];
        u_char code, id;
@@ -2877,21 +2991,18 @@ static char *eap_typenames[] = {
 };
 
 static int
-eap_printpkt(inp, inlen, printer, arg)
-u_char *inp;
-int inlen;
-void (*printer) __P((void *, char *, ...));
-void *arg;
+eap_printpkt(u_char *inp, int inlen,
+            void (*printer) (void *, char *, ...), void *arg)
 {
        int code, id, len, rtype, vallen;
        u_char *pstart;
        u_int32_t uval;
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
        u_char flags;
-#endif /* USE_EAPTLS */
-#ifdef CHAPMS
+#endif /* PPP_WITH_EAPTLS */
+#ifdef PPP_WITH_CHAPMS
        u_char opcode;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
        if (inlen < EAP_HEADERLEN)
                return (0);
@@ -2956,7 +3067,7 @@ void *arg;
                        }
                        break;
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
                case EAPT_MSCHAPV2:
                        if (len <= 0)
                                break;
@@ -3009,9 +3120,9 @@ void *arg;
                                break;
                        }
                        break;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
                case EAPT_TLS:
                        if (len < 1)
                                break;
@@ -3027,8 +3138,9 @@ void *arg;
                        printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
                        printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
                        break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
+#ifdef PPP_WITH_SRP
                case EAPT_SRP:
                        if (len < 3)
                                goto truncated;
@@ -3096,10 +3208,10 @@ void *arg;
                                if (uval != 0) {
                                        printer(arg, " f<%X>", uval);
                                }
-                               if ((vallen = len) > SHA_DIGESTSIZE)
-                                       vallen = SHA_DIGESTSIZE;
+                               if ((vallen = len) > SHA_DIGEST_LENGTH)
+                                       vallen = SHA_DIGEST_LENGTH;
                                printer(arg, " <M2%.*B%s>", len, inp,
-                                   len < SHA_DIGESTSIZE ? "?" : "");
+                                   len < SHA_DIGEST_LENGTH ? "?" : "");
                                INCPTR(vallen, inp);
                                len -= vallen;
                                if (len > 0) {
@@ -3116,6 +3228,7 @@ void *arg;
                                break;
                        }
                        break;
+#endif  /* PPP_WITH_SRP */
                }
                break;
 
@@ -3140,7 +3253,7 @@ void *arg;
                        }
                        break;
 
-#ifdef USE_EAPTLS
+#ifdef PPP_WITH_EAPTLS
                case EAPT_TLS:
                        if (len < 1)
                                break;
@@ -3157,7 +3270,7 @@ void *arg;
                        printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
 
                        break;
-#endif /* USE_EAPTLS */
+#endif /* PPP_WITH_EAPTLS */
 
                case EAPT_NAK:
                        if (len <= 0) {
@@ -3168,7 +3281,7 @@ void *arg;
                        len--;
                        printer(arg, " <Suggested-type %02X", rtype);
                        if (rtype >= 1 &&
-                           rtype < sizeof (eap_typenames) / sizeof (char *))
+                           rtype <= sizeof (eap_typenames) / sizeof (char *))
                                printer(arg, " (%s)", eap_typenames[rtype-1]);
                        printer(arg, ">");
                        break;
@@ -3196,7 +3309,7 @@ void *arg;
                        }
                        break;
 
-#ifdef CHAPMS
+#ifdef PPP_WITH_CHAPMS
                case EAPT_MSCHAPV2:
                        if (len <= 0)
                                break;
@@ -3239,8 +3352,9 @@ void *arg;
                                break;
                        }
                        break;
-#endif /* CHAPMS */
+#endif /* PPP_WITH_CHAPMS */
 
+#ifdef PPP_WITH_SRP
                case EAPT_SRP:
                        if (len < 1)
                                goto truncated;
@@ -3267,7 +3381,7 @@ void *arg;
                                        printer(arg, " f<%X>", uval);
                                }
                                printer(arg, " <M1%.*B%s>", len, inp,
-                                   len == SHA_DIGESTSIZE ? "" : "?");
+                                   len == SHA_DIGEST_LENGTH ? "" : "?");
                                INCPTR(len, inp);
                                len = 0;
                                break;
@@ -3277,14 +3391,15 @@ void *arg;
 
                        case EAPSRP_LWRECHALLENGE:
                                printer(arg, " <Response%.*B%s>", len, inp,
-                                   len == SHA_DIGESTSIZE ? "" : "?");
-                               if ((vallen = len) > SHA_DIGESTSIZE)
-                                       vallen = SHA_DIGESTSIZE;
+                                   len == SHA_DIGEST_LENGTH ? "" : "?");
+                               if ((vallen = len) > SHA_DIGEST_LENGTH)
+                                       vallen = SHA_DIGEST_LENGTH;
                                INCPTR(vallen, inp);
                                len -= vallen;
                                break;
                        }
                        break;
+#endif  /* PPP_WITH_SRP */
                }
                break;