summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEivind Næss <eivnaes@yahoo.com>2022-08-13 14:59:08 -0700
committerEivind Næss <eivnaes@yahoo.com>2022-08-19 08:55:54 -0700
commita25e52a87c3f5cbe2c2264f4e7c4c02439ac6717 (patch)
treef74436ddd60819918008c6549830ad04e4951d5c
parent3b87aa186a1a60709fe3884798b291e795776135 (diff)
downloadppp-a25e52a87c3f5cbe2c2264f4e7c4c02439ac6717.tar.gz
Adding back DesEncrypt/DesDecrypt functions as they are a special incarnation DES w.r.t. RFC2759
Signed-off-by: Eivind Næss <eivnaes@yahoo.com>
-rw-r--r--pppd/Makefile.am16
-rw-r--r--pppd/chap_ms.c37
-rw-r--r--pppd/eap.c344
-rw-r--r--pppd/ppp-crypto-priv.h2
-rw-r--r--pppd/ppp-crypto.c57
-rw-r--r--pppd/ppp-des.c124
-rw-r--r--pppd/pppcrypt.c280
-rw-r--r--pppd/pppcrypt.h75
8 files changed, 574 insertions, 361 deletions
diff --git a/pppd/Makefile.am b/pppd/Makefile.am
index 0a13bb1..55d926b 100644
--- a/pppd/Makefile.am
+++ b/pppd/Makefile.am
@@ -2,7 +2,7 @@ sbin_PROGRAMS = pppd
dist_man8_MANS = pppd.8
check_PROGRAMS =
-utest_chap_SOURCES = chap_ms.c utils.c
+utest_chap_SOURCES = chap_ms.c utils.c pppcrypt.c
utest_chap_CPPFLAGS = -DUNIT_TEST
utest_chap_LDFLAGS =
@@ -14,6 +14,10 @@ utest_crypto_SOURCES = ppp-crypto.c
utest_crypto_CPPFLAGS = -DUNIT_TEST
utest_crypto_LDFLAGS =
+utest_pppcrypt_SOURCES = pppcrypt.c
+utest_pppcrypt_CPPFLAGS = -DUNIT_TEST_PPPCRYPT
+utest_pppcrypt_LDFLAGS =
+
check_PROGRAMS += utest_crypto
if WITH_SRP
@@ -45,6 +49,7 @@ pppd_include_HEADERS = \
peap.h \
pppd.h \
pppdconf.h \
+ pppcrypt.h \
ppp-crypto.h \
ppp-crypto-priv.h \
session.h \
@@ -88,8 +93,14 @@ pppd_LIBS += -lsocket -lnsl
endif
if PPP_WITH_CHAPMS
-pppd_SOURCES += chap_ms.c
+pppd_SOURCES += chap_ms.c pppcrypt.c
check_PROGRAMS += utest_chap
+check_PROGRAMS += utest_pppcrypt
+else
+if WITH_SRP
+pppd_SOURCES += pppcrypt.c
+check_PROGRAMS += utest_pppcrypt
+endif
endif
if PPP_WITH_CBCP
@@ -157,6 +168,7 @@ endif
utest_peap_LDADD = libppp_crypt.la
utest_chap_LDADD = libppp_crypt.la
utest_crypto_LDADD = libppp_crypt.la
+utest_pppcrypt_LDADD = libppp_crypt.la
pppd_LIBS += libppp_crypt.la
diff --git a/pppd/chap_ms.c b/pppd/chap_ms.c
index 71942fe..704052f 100644
--- a/pppd/chap_ms.c
+++ b/pppd/chap_ms.c
@@ -99,6 +99,7 @@
#include "magic.h"
#include "mppe.h"
#include "ppp-crypto.h"
+#include "pppcrypt.h"
#ifdef UNIT_TEST
#undef PPP_WITH_MPPE
@@ -509,9 +510,6 @@ ChallengeResponse(u_char *challenge,
{
u_char ZPasswordHash[21];
PPP_CIPHER_CTX *ctx;
- int outlen = 0;
- int offset = 0;
- int retval = 0;
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
BCOPY(PasswordHash, ZPasswordHash, MD4_DIGEST_LENGTH);
@@ -521,38 +519,15 @@ ChallengeResponse(u_char *challenge,
sizeof(ZPasswordHash), ZPasswordHash);
#endif
- ctx = PPP_CIPHER_CTX_new();
- if (ctx != NULL) {
-
- if (PPP_CipherInit(ctx, PPP_des_ecb(), ZPasswordHash + 0, NULL, 1)) {
-
- if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
- offset += outlen;
-
- PPP_CIPHER_CTX_set_cipher_data(ctx, ZPasswordHash + 7);
- if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
- offset += outlen;
-
- PPP_CIPHER_CTX_set_cipher_data(ctx, ZPasswordHash + 14);
- if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
- offset += outlen;
-
- if (PPP_CipherFinal(ctx, response + offset, &outlen)) {
-
- retval = 1;
- }
- }
- }
- }
- }
-
- PPP_CIPHER_CTX_free(ctx);
- }
+ if (DesEncrypt(challenge, ZPasswordHash + 0, response + 0) &&
+ DesEncrypt(challenge, ZPasswordHash + 7, response + 8) &&
+ DesEncrypt(challenge, ZPasswordHash + 14, response + 16))
+ return 1;
#if 0
dbglog("ChallengeResponse - response %.24B", response);
#endif
- return retval;
+ return 0;
}
void
diff --git a/pppd/eap.c b/pppd/eap.c
index a627756..4dd3123 100644
--- a/pppd/eap.c
+++ b/pppd/eap.c
@@ -66,6 +66,7 @@
#include "pppd.h"
#include "pathnames.h"
#include "ppp-crypto.h"
+#include "pppcrypt.h"
#include "eap.h"
#ifdef PPP_WITH_PEAP
#include "peap.h"
@@ -80,10 +81,6 @@
#include <t_client.h>
#endif /* PPP_WITH_SRP */
-#ifndef SHA_DIGESTSIZE
-#define SHA_DIGESTSIZE 20
-#endif
-
#ifdef PPP_WITH_EAPTLS
#include "eap-tls.h"
#endif /* PPP_WITH_EAPTLS */
@@ -451,7 +448,6 @@ eap_figure_next_state(eap_state *esp, int status)
int id, i, plen, clen, toffs, keylen;
u_char vals[2];
struct b64state bs;
- PPP_CIPHER_CTX *cctx;
#endif /* PPP_WITH_SRP */
#ifdef PPP_WITH_EAPTLS
struct eaptls_session *ets;
@@ -494,27 +490,11 @@ eap_figure_next_state(eap_state *esp, int status)
esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
secbuf);
toffs = 0;
-
- cctx = PPP_CIPHER_CTX_new();
- if (!cctx) {
- dbglog("no DES here; cannot decode "
- "pseudonym");
- break;
- }
-
- if (!PPP_CipherInit(cctx, PPP_des_ecb(), NULL, NULL, 0)) {
- dbglog("no DES here; cannot decode "
- "pseudonym");
- break;
- }
-
for (i = 0; i < 5; i++) {
pncrypt_getkey(toffs, key, keylen);
toffs -= 86400;
- PPP_CIPHER_CTX_set_cipher_data(cctx, key);
-
- if (!PPP_CipherUpdate(cctx, clear, &clen, secbuf, 8)) {
+ if (!DesDecrypt(secbuf, key, clear)) {
dbglog("no DES here; cannot decode "
"pseudonym");
return;
@@ -538,12 +518,11 @@ eap_figure_next_state(eap_state *esp, int status)
dp += i;
sp = secbuf + 8;
while (plen > 0) {
- PPP_CipherUpdate(cctx, dp, &clen, sp, 8);
+ DesDecrypt(sp, key, dp);
sp += 8;
dp += 8;
plen -= 8;
}
- PPP_CIPHER_CTX_free(cctx);
esp->es_server.ea_peer[
esp->es_server.ea_peerlen] = '\0';
dbglog("decoded pseudonym to \"%.*q\"",
@@ -839,11 +818,10 @@ eap_send_request(eap_state *esp)
char *str;
#ifdef PPP_WITH_SRP
struct t_server *ts;
- u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp, key[SHA_DIGEST_LENGTH];
+ 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;
PPP_MD_CTX *ctxt;
- PPP_CIPHER_CTX *cctx;
#endif /* PPP_WITH_SRP */
/* Handle both initial auth and restart */
@@ -1017,20 +995,16 @@ eap_send_request(eap_state *esp)
i -= j;
cp += j;
- cctx = PPP_CIPHER_CTX_new();
- if (!cctx) {
+ if (!DesEncrypt(clear, key, cipher)) {
dbglog("no DES here; not generating pseudonym");
break;
- }
- PPP_CipherInit(cctx, PPP_des_ecb(), key, NULL, 1);
-
- PPP_CipherUpdate(cctx, cipher, &clen, clear, sizeof(clear));
+ }
BZERO(&b64, sizeof (b64));
outp++; /* space for pseudonym length */
outp += b64enc(&b64, cipher, 8, outp);
while (i >= 8) {
- PPP_CipherUpdate(cctx, cipher, &clen, cp, 8);
+ DesEncrypt(cp, key, cipher);
outp += b64enc(&b64, cipher, 8, outp);
cp += 8;
i -= 8;
@@ -1043,13 +1017,11 @@ eap_send_request(eap_state *esp)
i++;
}
- PPP_CipherUpdate(cctx, cipher, &clen, clear, 8);
+ DesEncrypt(clear, key, cipher);
outp += b64enc(&b64, cipher, 8, outp);
}
outp += b64flush(&b64, outp);
- PPP_CIPHER_CTX_free(cctx);
-
/* Set length and pad out to next 20 octet boundary */
i = outp - optr - 1;
*optr = i;
@@ -1062,33 +1034,32 @@ eap_send_request(eap_state *esp)
}
/* Obscure the pseudonym with SHA1 hash */
- 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);
- }
+ 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;
@@ -1607,26 +1578,26 @@ write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
dsize = SHA_DIGEST_LENGTH;
len -= dsize;
datp = inp + len;
- 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_DIGESTSIZE);
- } else {
- PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
- esp->es_client.ea_namelen);
- }
- PPP_DigestFinal(ctxt, dig, &diglen);
+ ctxt = PPP_MD_CTX_new();
+ if (ctxt) {
- for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
- *datp++ ^= *digp;
+ 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);
- }
+ PPP_MD_CTX_free(ctxt);
+ }
}
/* Now check that the result is sane */
@@ -1709,7 +1680,7 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
struct t_num sval, gval, Nval, *Ap, Bval;
u_char vals[2];
PPP_MD_CTX *ctxt;
- u_char dig[SHA_DIGESTSIZE];
+ u_char dig[SHA_DIGEST_LENGTH];
int diglen = sizeof(dig);
int fd;
#endif /* PPP_WITH_SRP */
@@ -1837,27 +1808,27 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
break;
}
- 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");
+ 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;
@@ -2135,7 +2106,7 @@ eap_request(eap_state *esp, u_char *inp, int id, 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 "
@@ -2145,7 +2116,7 @@ eap_request(eap_state *esp, u_char *inp, int id, 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);
}
}
@@ -2163,24 +2134,24 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
return;
}
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_DIGESTSIZE);
+ 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;
+ break;
default:
error("EAP: unknown SRP Subtype %d", vallen);
@@ -2356,15 +2327,15 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
int secret_len;
char secret[MAXSECRETLEN];
char rhostname[256];
- PPP_MD_CTX *mdctx;
+ PPP_MD_CTX *mdctx;
u_char hash[MD5_DIGEST_LENGTH];
- int hashlen = MD5_DIGEST_LENGTH;
+ int hashlen = MD5_DIGEST_LENGTH;
#ifdef PPP_WITH_SRP
struct t_server *ts;
struct t_num A;
PPP_MD_CTX *ctxt;
- u_char dig[SHA_DIGESTSIZE];
- int diglen = sizeof(dig);
+ u_char dig[SHA_DIGEST_LENGTH];
+ int diglen = sizeof(dig);
#endif /* PPP_WITH_SRP */
#ifdef PPP_WITH_EAPTLS
@@ -2597,40 +2568,39 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
break;
}
- mdctx = PPP_MD_CTX_new();
- if (mdctx != NULL) {
-
- if (PPP_DigestInit(mdctx, PPP_md5())) {
+ mdctx = PPP_MD_CTX_new();
+ if (mdctx != NULL) {
- if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
+ if (PPP_DigestInit(mdctx, PPP_md5())) {
- if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
+ if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
- BZERO(secret, sizeof(secret));
- if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
+ if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
- if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
+ BZERO(secret, sizeof(secret));
+ if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
- if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) {
+ if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
- esp->es_server.ea_type = EAPT_MD5CHAP;
- eap_send_success(esp);
- eap_figure_next_state(esp, 0);
+ 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;
- }
- }
- }
- }
- }
- }
+ if (esp->es_rechallenge != 0) {
+ TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
+ }
+ PPP_MD_CTX_free(mdctx);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
- PPP_MD_CTX_free(mdctx);
- }
+ PPP_MD_CTX_free(mdctx);
+ }
eap_send_failure(esp);
break;
@@ -2776,9 +2746,9 @@ eap_response(eap_state *esp, u_char *inp, int id, 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;
}
@@ -2815,37 +2785,37 @@ eap_response(eap_state *esp, u_char *inp, int id, 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;
}
- 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;
- }
+ 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;
@@ -3238,10 +3208,10 @@ eap_printpkt(u_char *inp, int inlen,
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) {
@@ -3411,7 +3381,7 @@ eap_printpkt(u_char *inp, int inlen,
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;
@@ -3421,9 +3391,9 @@ eap_printpkt(u_char *inp, int inlen,
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;
diff --git a/pppd/ppp-crypto-priv.h b/pppd/ppp-crypto-priv.h
index a0cc14c..984f08a 100644
--- a/pppd/ppp-crypto-priv.h
+++ b/pppd/ppp-crypto-priv.h
@@ -51,8 +51,6 @@ struct _PPP_MD_CTX
struct _PPP_CIPHER
{
int (*init_fn)(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv);
- void (*set_key_fn)(PPP_CIPHER_CTX *ctx, const unsigned char *key);
- void (*set_iv_fn)(PPP_CIPHER_CTX *ctx, const unsigned char *iv);
int (*update_fn)(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
int (*final_fn)(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
void (*clean_fn)(PPP_CIPHER_CTX *ctx);
diff --git a/pppd/ppp-crypto.c b/pppd/ppp-crypto.c
index 6dfe962..ca74327 100644
--- a/pppd/ppp-crypto.c
+++ b/pppd/ppp-crypto.c
@@ -139,14 +139,6 @@ int PPP_CipherFinal(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return 0;
}
-void PPP_CIPHER_CTX_set_cipher_data(PPP_CIPHER_CTX *ctx, const unsigned char *key)
-{
- if (ctx && ctx->cipher.set_key_fn) {
- ctx->cipher.set_key_fn(ctx, key);
- }
-}
-
-
int PPP_crypto_init()
{
int retval = 0;
@@ -206,7 +198,7 @@ int test_md4()
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
+ 0x6b, 0x65, 0x79, 0x2e
};
unsigned int hash_len;
@@ -254,7 +246,7 @@ int test_md5()
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
+ 0x6b, 0x65, 0x79, 0x2e
};
unsigned int hash_len;
@@ -302,7 +294,7 @@ int test_sha()
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
+ 0x6b, 0x65, 0x79, 0x2e
};
unsigned int hash_len;
@@ -357,16 +349,16 @@ int test_des_encrypt()
0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20
};
unsigned char expect[80] = {
- 0x5d, 0xa7, 0x47, 0xc5, 0x1a, 0xb1, 0x71, 0xff,
- 0xc8, 0x45, 0x7c, 0xa7, 0x07, 0xec, 0x4b, 0x13,
- 0x47, 0x55, 0x77, 0xbc, 0xcf, 0x71, 0xd9, 0x27,
- 0x23, 0x12, 0x2a, 0x17, 0x20, 0xad, 0xc1, 0x19,
- 0x3e, 0x74, 0x38, 0x29, 0x48, 0xb0, 0xd2, 0xe2,
- 0x18, 0x45, 0xdd, 0x8a, 0x9b, 0x8d, 0x40, 0xec,
- 0x9e, 0x0c, 0x41, 0xa3, 0x36, 0x40, 0xf5, 0x91,
- 0x41, 0x44, 0xde, 0xa1, 0xb5, 0x9d, 0x39, 0x99,
- 0x23, 0x12, 0x2a, 0x17, 0x20, 0xad, 0xc1, 0x19,
- 0xee, 0xe3, 0xbe, 0x0b, 0x83, 0x36, 0xe1, 0x25
+ 0x45, 0xdb, 0x80, 0x45, 0x16, 0xd0, 0x6d, 0x60,
+ 0x92, 0x23, 0x4b, 0xd3, 0x9d, 0x36, 0xb8, 0x1a,
+ 0xa4, 0x1a, 0xf7, 0xb1, 0x60, 0xfb, 0x74, 0x16,
+ 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a,
+ 0x2b, 0xed, 0x68, 0x9d, 0x19, 0xd6, 0xb1, 0xb8,
+ 0x91, 0xff, 0xea, 0x62, 0xac, 0xe7, 0x49, 0xdd,
+ 0xfa, 0x4d, 0xa4, 0x01, 0x3f, 0xea, 0xca, 0xb4,
+ 0xb6, 0xdc, 0xd3, 0x04, 0x45, 0x07, 0x74, 0xed,
+ 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a,
+ 0xbb, 0x9b, 0x13, 0x31, 0xf4, 0xa9, 0x32, 0x49
};
unsigned char cipher[80] = {};
@@ -409,16 +401,16 @@ int test_des_decrypt()
};
unsigned char cipher[80] = {
- 0x5d, 0xa7, 0x47, 0xc5, 0x1a, 0xb1, 0x71, 0xff,
- 0xc8, 0x45, 0x7c, 0xa7, 0x07, 0xec, 0x4b, 0x13,
- 0x47, 0x55, 0x77, 0xbc, 0xcf, 0x71, 0xd9, 0x27,
- 0x23, 0x12, 0x2a, 0x17, 0x20, 0xad, 0xc1, 0x19,
- 0x3e, 0x74, 0x38, 0x29, 0x48, 0xb0, 0xd2, 0xe2,
- 0x18, 0x45, 0xdd, 0x8a, 0x9b, 0x8d, 0x40, 0xec,
- 0x9e, 0x0c, 0x41, 0xa3, 0x36, 0x40, 0xf5, 0x91,
- 0x41, 0x44, 0xde, 0xa1, 0xb5, 0x9d, 0x39, 0x99,
- 0x23, 0x12, 0x2a, 0x17, 0x20, 0xad, 0xc1, 0x19,
- 0xee, 0xe3, 0xbe, 0x0b, 0x83, 0x36, 0xe1, 0x25
+ 0x45, 0xdb, 0x80, 0x45, 0x16, 0xd0, 0x6d, 0x60,
+ 0x92, 0x23, 0x4b, 0xd3, 0x9d, 0x36, 0xb8, 0x1a,
+ 0xa4, 0x1a, 0xf7, 0xb1, 0x60, 0xfb, 0x74, 0x16,
+ 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a,
+ 0x2b, 0xed, 0x68, 0x9d, 0x19, 0xd6, 0xb1, 0xb8,
+ 0x91, 0xff, 0xea, 0x62, 0xac, 0xe7, 0x49, 0xdd,
+ 0xfa, 0x4d, 0xa4, 0x01, 0x3f, 0xea, 0xca, 0xb4,
+ 0xb6, 0xdc, 0xd3, 0x04, 0x45, 0x07, 0x74, 0xed,
+ 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a,
+ 0xbb, 0x9b, 0x13, 0x31, 0xf4, 0xa9, 0x32, 0x49
};
unsigned char expect[80] = {
@@ -462,7 +454,8 @@ int test_des_decrypt()
return success;
}
-int main(int argc, char *argv[]) {
+int main(int argc, char *argv[])
+{
int failure = 0;
if (!PPP_crypto_init()) {
diff --git a/pppd/ppp-des.c b/pppd/ppp-des.c
index 94045ec..695caa4 100644
--- a/pppd/ppp-des.c
+++ b/pppd/ppp-des.c
@@ -6,7 +6,7 @@
*
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
* Copyright (c) 2022 Eivind Næss. All rights reserved.
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,90 +41,10 @@
#include <stddef.h>
#include <stdlib.h>
+#include <string.h>
#include "ppp-crypto-priv.h"
-/*
- * DES related functions are imported from openssl 3.0 project with the
- * follwoing license:
- *
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-typedef unsigned char DES_cblock[8];
-#define DES_KEY_SZ (sizeof(DES_cblock))
-
-static const unsigned char odd_parity[256] = {
- 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
- 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
- 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
- 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
- 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
- 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
- 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
- 110,
- 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
- 127,
- 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
- 143,
- 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
- 158,
- 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
- 174,
- 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
- 191,
- 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
- 206,
- 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
- 223,
- 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
- 239,
- 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
- 254
-};
-
-static void DES_set_odd_parity(DES_cblock *key)
-{
- unsigned int i;
- for (i = 0; i < DES_KEY_SZ; i++)
- (*key)[i] = odd_parity[(*key)[i]];
-}
-
-static unsigned char
-Get7Bits(const unsigned 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(const unsigned char *key, unsigned char *des_key)
-{
- /* key IN 56 bit DES key missing parity bits */
- /* 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);
-
- DES_set_odd_parity((DES_cblock *)des_key);
-}
-
-
#ifdef OPENSSL_HAVE_DES
#include <openssl/evp.h>
@@ -138,9 +58,14 @@ static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigne
if (ctx) {
EVP_CIPHER_CTX *cc = EVP_CIPHER_CTX_new();
if (cc) {
+
if (key) {
- MakeKey(key, ctx->key);
+ memcpy(ctx->key, key, 8);
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 8);
}
+
if (EVP_CipherInit(cc, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr)) {
if (EVP_CIPHER_CTX_set_padding(cc, 0)) {
@@ -148,6 +73,7 @@ static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigne
return 1;
}
}
+
EVP_CIPHER_CTX_free(cc);
}
}
@@ -178,22 +104,6 @@ static void des_clean(PPP_CIPHER_CTX *ctx)
}
}
-/**
- * Using the EVP_ interface with openssl, there is no replacement for the
- * DES_set_key() function, and each iteration of DesEncrypt(Clear,Key,Cipher)
- * per RFC2759 is another iteration of the EVP_CipherInit, EVP_CipherUpdate,
- * EVP_CipherFinal functions.
- *
- * As a work-around, we reset the EVP_CIPHER_CTX object, and re-initializes
- * the context by calling EVP_CipherInit() with the new key.
- */
-static void des_set_key(PPP_CIPHER_CTX *ctx, const unsigned char *key)
-{
- EVP_CIPHER_CTX_reset((EVP_CIPHER_CTX*) ctx->priv);
- MakeKey(key, ctx->key);
- EVP_CipherInit((EVP_CIPHER_CTX*) ctx->priv, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr);
-}
-
#else
/*
@@ -759,7 +669,14 @@ static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigne
if (ks) {
if (key) {
- MakeKey(key, ctx->key);
+ memcpy(ctx->key, key, 8);
+ }
+
+ if (iv) {
+ memcpy(ctx->iv, iv, 8);
+ }
+
+ if (key) {
DES_set_key((DES_cblock*) &ctx->key, ks);
}
@@ -797,19 +714,12 @@ static void des_clean(PPP_CIPHER_CTX *ctx)
}
}
-static void des_set_key(PPP_CIPHER_CTX *ctx, const unsigned char *key)
-{
- MakeKey(key, ctx->key);
- DES_set_key((DES_cblock*) &ctx->key, (DES_key_schedule*) ctx->priv);
-}
-
#endif
static PPP_CIPHER ppp_des = {
.init_fn = des_init,
.update_fn = des_update,
.final_fn = des_final,
- .set_key_fn = des_set_key,
.clean_fn = des_clean,
};
diff --git a/pppd/pppcrypt.c b/pppd/pppcrypt.c
new file mode 100644
index 0000000..cc4f5f7
--- /dev/null
+++ b/pppd/pppcrypt.c
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ *
+ * Sections of this code holds different copyright information.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+
+#include "pppcrypt.h"
+#include "ppp-crypto.h"
+
+
+/*
+ * DES_set_odd_parity function are imported from openssl 3.0 project with the
+ * follwoing license:
+ *
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+typedef unsigned char DES_cblock[8];
+#define DES_KEY_SZ (sizeof(DES_cblock))
+
+static const unsigned char odd_parity[256] = {
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
+ 110,
+ 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
+ 127,
+ 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
+ 143,
+ 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
+ 158,
+ 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
+ 174,
+ 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
+ 191,
+ 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
+ 206,
+ 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
+ 223,
+ 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
+ 239,
+ 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
+ 254
+};
+
+static void DES_set_odd_parity(DES_cblock *key)
+{
+ unsigned int i;
+ for (i = 0; i < DES_KEY_SZ; i++)
+ (*key)[i] = odd_parity[(*key)[i]];
+}
+
+static unsigned char
+Get7Bits(const unsigned 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(const unsigned char *key, unsigned char *des_key)
+{
+ /* key IN 56 bit DES key missing parity bits */
+ /* 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);
+
+ DES_set_odd_parity((DES_cblock *)des_key);
+}
+
+#include <openssl/evp.h>
+
+int
+DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
+{
+ int retval = 0;
+ unsigned int clen = 0;
+ unsigned char des_key[8];
+
+ PPP_CIPHER_CTX *ctx = PPP_CIPHER_CTX_new();
+ if (ctx) {
+
+ MakeKey(key, des_key);
+
+ if (PPP_CipherInit(ctx, PPP_des_ecb(), des_key, NULL, 1)) {
+
+ if (PPP_CipherUpdate(ctx, cipher, &clen, clear, 8)) {
+
+ if (PPP_CipherFinal(ctx, cipher + clen, &clen)) {
+
+ retval = 1;
+ }
+ }
+ }
+
+ PPP_CIPHER_CTX_free(ctx);
+ }
+
+ return (retval);
+}
+
+int
+DesDecrypt(unsigned char *cipher, unsigned char *key, unsigned char *clear)
+{
+ int retval = 0;
+ unsigned int clen = 0;
+ unsigned char des_key[8];
+
+ PPP_CIPHER_CTX *ctx = PPP_CIPHER_CTX_new();
+ if (ctx) {
+
+ MakeKey(key, des_key);
+
+ if (PPP_CipherInit(ctx, PPP_des_ecb(), des_key, NULL, 0)) {
+
+ if (PPP_CipherUpdate(ctx, clear, &clen, cipher, 8)) {
+
+ if (PPP_CipherFinal(ctx, clear + clen, &clen)) {
+
+ retval = 1;
+ }
+ }
+ }
+
+ PPP_CIPHER_CTX_free(ctx);
+ }
+
+ return (retval);
+}
+
+#ifdef UNIT_TEST_PPPCRYPT
+
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * The test-vectors are taken from RFC2759.
+ */
+int test_encrypt()
+{
+ unsigned char Challenge[8] = {
+ 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26
+ };
+
+ unsigned char ZPasswordHash[21] = {
+ 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6,
+ 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE
+ };
+
+ unsigned char expected[24] = {
+ 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E,
+ 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54,
+ 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF
+ };
+ unsigned char response[24] = {};
+ unsigned int retval = 0;
+
+ DesEncrypt(Challenge, ZPasswordHash + 0, response + 0);
+ DesEncrypt(Challenge, ZPasswordHash + 7, response + 8);
+ DesEncrypt(Challenge, ZPasswordHash + 14, response + 16);
+
+ return memcmp(response, expected, sizeof(response)) == 0;
+}
+
+int test_decrypt()
+{
+ unsigned char Challenge[8] = {
+ 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26
+ };
+
+ unsigned char ZPasswordHash[21] = {
+ 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6,
+ 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE
+ };
+
+ unsigned char Response[24] = {
+ 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E,
+ 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54,
+ 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF
+ };
+ unsigned char Output[8];
+ unsigned int failure = 0;
+
+ if (DesDecrypt(Response + 0, ZPasswordHash + 0, Output)) {
+ failure += memcmp(Challenge, Output, sizeof(Challenge));
+ }
+
+ if (DesDecrypt(Response + 8, ZPasswordHash + 7, Output)) {
+ failure += memcmp(Challenge, Output, sizeof(Challenge));
+ }
+
+ if (DesDecrypt(Response +16, ZPasswordHash +14, Output)) {
+ failure += memcmp(Challenge, Output, sizeof(Challenge));
+ }
+
+ return failure == 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int failure = 0;
+
+ if (!PPP_crypto_init()) {
+ printf("Couldn't initialize crypto test\n");
+ return -1;
+ }
+
+ if (!test_encrypt()) {
+ printf("CHAP DES encryption test failed\n");
+ failure++;
+ }
+
+ if (!test_decrypt()) {
+ printf("CHAP DES decryption test failed\n");
+ failure++;
+ }
+
+ if (!PPP_crypto_deinit()) {
+ printf("Couldn't deinitialize crypto test\n");
+ return -1;
+ }
+
+ return failure;
+}
+
+#endif
diff --git a/pppd/pppcrypt.h b/pppd/pppcrypt.h
new file mode 100644
index 0000000..9083594
--- /dev/null
+++ b/pppd/pppcrypt.h
@@ -0,0 +1,75 @@
+/*
+ * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
+ *
+ * Extracted from chap_ms.c by James Carlson.
+ * Updated to better reflect RFC2759 by Eivind Naess
+ *
+ * Copyright (c) 2022 Eivind Naess. All rights reserved.
+ * 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 PPP_PPPCRYPT_H
+#define PPP_PPPCRYPT_H
+
+#include "pppdconf.h"
+
+/**
+ * This is the DES encrypt functions as described by RFC2759.
+ *
+ * Parameters:
+ * unsigned char *clear:
+ * A 8 byte input array to be encrypted
+ *
+ * unsigned char *key:
+ * A raw 7-byte array to be expanded to 8 with odd-parity
+ *
+ * unsigned char *cipher:
+ * A 8 byte outut array providing space for the output data
+ *
+ * DesEncrypt returns 1 on success
+ */
+int DesEncrypt(unsigned char *clear, unsigned char *key,
+ unsigned char *cipher);
+
+/**
+ * This is the DES decrypt functions as described by RFC2759.
+ *
+ * Parameters:
+ * unsigned char *cipher:
+ * A 8 byte input array to be decrypted
+ *
+ * unsigned char *key:
+ * A raw 7-byte array to be expanded to a 8-byte key with odd-parity
+ *
+ * unsigned char *clear:
+ * A 8 byte output array providing space for the output data
+ *
+ * DesDecrypt returns 1 on success
+ */
+int DesDecrypt(unsigned char *cipher, unsigned char *key,
+ unsigned char *clear);
+
+#endif /* PPP_PPPCRYPT_H */