]> git.ozlabs.org Git - ppp.git/commitdiff
Adding back DesEncrypt/DesDecrypt functions as they are a special incarnation DES...
authorEivind Næss <eivnaes@yahoo.com>
Sat, 13 Aug 2022 21:59:08 +0000 (14:59 -0700)
committerEivind Næss <eivnaes@yahoo.com>
Fri, 19 Aug 2022 15:55:54 +0000 (08:55 -0700)
Signed-off-by: Eivind Næss <eivnaes@yahoo.com>
pppd/Makefile.am
pppd/chap_ms.c
pppd/eap.c
pppd/ppp-crypto-priv.h
pppd/ppp-crypto.c
pppd/ppp-des.c
pppd/pppcrypt.c [new file with mode: 0644]
pppd/pppcrypt.h [new file with mode: 0644]

index 0a13bb1ca15bb42d384e5896bb2da9a2e1d64d75..55d926b9d5e2dbf17b49caab823fbe1b4aa5ecfd 100644 (file)
@@ -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
 
index 71942fed0833d88868c157976cce4f4405ef3641..704052feee98989a94ade7e5fc9774fe226991a4 100644 (file)
@@ -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
index a6277563697b8b4f29ff26677dfd1d85435ca0d2..4dd31230f3627fca193f7ba4063a37d530284996 100644 (file)
@@ -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"
 #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;
index a0cc14c4231af3f0f6f7adb8d442d36d3ddfb67c..984f08ad3b3cbbc05c2dda3f1356bb114e728384 100644 (file)
@@ -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);
index 6dfe96266b2ada0d8898d2fa796b1e7538c588bb..ca743270a8598cc8f1e2a0a6ec6ef9ebe489c503 100644 (file)
@@ -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()) {
index 94045ec6f57233a4006f013d5000dad02ac10fde..695caa46dacb85bc80fdd6ff082a9084a3ea7902 100644 (file)
@@ -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
 
 #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 (file)
index 0000000..cc4f5f7
--- /dev/null
@@ -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 (file)
index 0000000..9083594
--- /dev/null
@@ -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 */