From a25e52a87c3f5cbe2c2264f4e7c4c02439ac6717 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Eivind=20N=C3=A6ss?= Date: Sat, 13 Aug 2022 14:59:08 -0700 Subject: [PATCH] Adding back DesEncrypt/DesDecrypt functions as they are a special incarnation DES w.r.t. RFC2759 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Eivind Næss --- pppd/Makefile.am | 16 +- pppd/chap_ms.c | 37 +---- pppd/eap.c | 344 +++++++++++++++++++---------------------- pppd/ppp-crypto-priv.h | 2 - pppd/ppp-crypto.c | 57 +++---- pppd/ppp-des.c | 124 ++------------- pppd/pppcrypt.c | 280 +++++++++++++++++++++++++++++++++ pppd/pppcrypt.h | 75 +++++++++ 8 files changed, 574 insertions(+), 361 deletions(-) create mode 100644 pppd/pppcrypt.c create mode 100644 pppd/pppcrypt.h 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 #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, " ", 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, " ", 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, " ", 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 #include +#include #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 @@ -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 + +#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 + +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 +#include + +/** + * 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 */ -- 2.39.2