]> git.ozlabs.org Git - ppp.git/commitdiff
Create a new API to abstract the crypto functions used by pppd.
authorEivind Næss <eivnaes@yahoo.com>
Wed, 3 Aug 2022 15:46:28 +0000 (08:46 -0700)
committerEivind Næss <eivnaes@yahoo.com>
Fri, 12 Aug 2022 15:31:06 +0000 (08:31 -0700)
This re-introduces the missing DES encryption functions copied from Openssl 3.0 project. Incorporates a new API for performing MD4/MD5/SHA and encryption using DES-ECB mode.

Unit tests are included for respective digest/encryption functions using this new API. With this change, you can pass configure --without-openssl to use the internally provided functions. If you do have openssl, then it will default to use these functions. This also provides a framework to allow other vendors to provide crypto.

This closes #333, partially addresses #242 (except the pkcs11 engine support). Word has it that openssl is working on support for this, and the libp11 / opensc project are inclined not to support this.

Signed-off-by: Eivind Næss <eivnaes@yahoo.com>
23 files changed:
configure.ac
pppd/Makefile.am
pppd/chap-md5.c
pppd/chap_ms.c
pppd/eap.c
pppd/main.c
pppd/md4.c [deleted file]
pppd/md4.h [deleted file]
pppd/md5.c [deleted file]
pppd/md5.h [deleted file]
pppd/mppe.c
pppd/ppp-crypto-priv.h [new file with mode: 0644]
pppd/ppp-crypto.c [new file with mode: 0644]
pppd/ppp-crypto.h [new file with mode: 0644]
pppd/ppp-des.c [new file with mode: 0644]
pppd/ppp-md4.c [new file with mode: 0644]
pppd/ppp-md5.c [new file with mode: 0644]
pppd/ppp-sha1.c [new file with mode: 0644]
pppd/pppcrypt.c [deleted file]
pppd/pppcrypt.h [deleted file]
pppd/pppdconf.h.in
pppd/sha1.c [deleted file]
pppd/sha1.h [deleted file]

index 640f70e46352e8ed5a455e627ff9d92429c01f5a..7b4c84295cf086c081b54ada7062c6347b6672f2 100644 (file)
@@ -221,7 +221,9 @@ AC_SUBST(PPPD_LOGFILE_DIR)
 #
 # Check for OpenSSL
 AX_CHECK_OPENSSL
-AM_CONDITIONAL(WITH_OPENSSL, test "x${with_openssl}" != "xno")
+AM_CONDITIONAL(PPP_WITH_OPENSSL, test "x${with_openssl}" != "xno")
+AM_COND_IF([PPP_WITH_OPENSSL],
+    AC_DEFINE([PPP_WITH_OPENSSL], 1, [PPP is compiled with openssl support]))
 
 #
 # Check if OpenSSL has compiled in support for various ciphers
@@ -236,29 +238,20 @@ AS_IF([test "x${with_openssl}" != "xno" ], [
 ])
 
 AM_CONDITIONAL([OPENSSL_HAVE_MD4], test "x${ac_cv_openssl_md4}" = "xyes")
-AM_COND_IF([OPENSSL_HAVE_MD4],,
-    AC_DEFINE([USE_MD4], 1, [Use MD4 included with pppd]))
+AM_COND_IF([OPENSSL_HAVE_MD4],
+    AC_DEFINE([OPENSSL_HAVE_MD4], 1, [Use MD4 included with openssl]))
 
 AM_CONDITIONAL([OPENSSL_HAVE_MD5], test "x${ac_cv_openssl_md5}" = "xyes")
-AM_COND_IF([OPENSSL_HAVE_MD5],,
-    AC_DEFINE([USE_MD5], 1, [Use MD5 included with pppd]))
+AM_COND_IF([OPENSSL_HAVE_MD5],
+    AC_DEFINE([OPENSSL_HAVE_MD5], 1, [Use MD5 included with openssl]))
 
 AM_CONDITIONAL([OPENSSL_HAVE_SHA], test "x${ac_cv_openssl_sha}" = "xyes")
-AM_COND_IF([OPENSSL_HAVE_SHA],,
-    AC_DEFINE([USE_SHA], 1, [Use SHA included with pppd]))
+AM_COND_IF([OPENSSL_HAVE_SHA],
+    AC_DEFINE([OPENSSL_HAVE_SHA], 1, [Use SHA included with openssl]))
 
 AM_CONDITIONAL([OPENSSL_HAVE_DES], test "x${ac_cv_openssl_des}" = "xyes")
-AM_COND_IF([OPENSSL_HAVE_DES],,
-    AC_DEFINE([USE_CRYPT], 1, [Use DES included with pppd]))
-
-#
-# If OpenSSL doesn't support DES, then use the one from libcrypt (glibc dropped support for this in 2.27).
-AS_IF([test "x${ac_cv_openssl_des}" = "xno" ], [
-    AC_CHECK_LIB([crypt], [encrypt],
-        [LIBS="$LIBS -lcrypt"],
-        [AC_MSG_ERROR([OpenSSL not found or does not support DES, and libcrypt also doesn't support encrypt])]
-    )
-])
+AM_COND_IF([OPENSSL_HAVE_DES],
+    AC_DEFINE([OPENSSL_HAVE_DES], 1, [Use DES included with openssl]))
 
 #
 # With libsrp support
index b392f2e2e877b44a205e3c1bc5c8301820effd8d..0a13bb1ca15bb42d384e5896bb2da9a2e1d64d75 100644 (file)
@@ -2,7 +2,7 @@ sbin_PROGRAMS = pppd
 dist_man8_MANS = pppd.8
 check_PROGRAMS =
 
-utest_chap_SOURCES = chap_ms.c pppcrypt.c utils.c
+utest_chap_SOURCES = chap_ms.c utils.c
 utest_chap_CPPFLAGS = -DUNIT_TEST
 utest_chap_LDFLAGS =
 
@@ -10,6 +10,12 @@ utest_peap_SOURCES = peap.c utils.c mppe.c
 utest_peap_CPPFLAGS = -DUNIT_TEST
 utest_peap_LDFLAGS =
 
+utest_crypto_SOURCES = ppp-crypto.c
+utest_crypto_CPPFLAGS = -DUNIT_TEST
+utest_crypto_LDFLAGS =
+
+check_PROGRAMS += utest_crypto
+
 if WITH_SRP
 sbin_PROGRAMS += srp-entry
 dist_man8_MANS += srp-entry.8
@@ -34,16 +40,14 @@ pppd_include_HEADERS = \
     ipv6cp.h \
     lcp.h \
     magic.h \
-    md4.h \
-    md5.h \
     mppe.h \
     pathnames.h \
     peap.h \
-    pppcrypt.h \
     pppd.h \
     pppdconf.h \
+    ppp-crypto.h \
+    ppp-crypto-priv.h \
     session.h \
-    sha1.h \
     spinlock.h \
     tls.h \
     tdb.h \
@@ -85,12 +89,7 @@ endif
 
 if PPP_WITH_CHAPMS
 pppd_SOURCES += chap_ms.c
-pppd_SOURCES += pppcrypt.c
 check_PROGRAMS += utest_chap
-else
-if WITH_SRP
-pppd_SOURCES += pppcrypt.c
-endif
 endif
 
 if PPP_WITH_CBCP
@@ -147,27 +146,18 @@ check_PROGRAMS += utest_peap
 endif
 
 noinst_LTLIBRARIES = libppp_crypt.la
-libppp_crypt_la_SOURCES=
+libppp_crypt_la_SOURCES=ppp-crypto.c ppp-md5.c ppp-md4.c ppp-sha1.c ppp-des.c
 
-if !WITH_OPENSSL
-libppp_crypt_la_SOURCES += md4.c md5.c sha1.c
-else
+if PPP_WITH_OPENSSL
 libppp_crypt_la_CPPFLAGS=$(OPENSSL_INCLUDES)
 libppp_crypt_la_LDFLAGS=$(OPENSSL_LDFLAGS)
 libppp_crypt_la_LIBADD=$(OPENSSL_LIBS)
-if !OPENSSL_HAVE_SHA
-libppp_crypt_la_SOURCES += sha1.c
-endif
-if !OPENSSL_HAVE_MD5
-libppp_crypt_la_SOURCES += md5.c
-endif
-if !OPENSSL_HAVE_MD4
-libppp_crypt_la_SOURCES += md4.c
-endif
 endif
 
 utest_peap_LDADD = libppp_crypt.la
 utest_chap_LDADD = libppp_crypt.la
+utest_crypto_LDADD = libppp_crypt.la
+
 pppd_LIBS += libppp_crypt.la
 
 if WITH_SYSTEMD
index 000f880e89e3d0859698b018689437acb120023e..750a8d77bb7de01c86f22f59f80814bc0da4ee0e 100644 (file)
@@ -40,7 +40,7 @@
 #include "chap-new.h"
 #include "chap-md5.h"
 #include "magic.h"
-#include "md5.h"
+#include "ppp-crypto.h"
 
 #define MD5_HASH_SIZE          16
 #define MD5_MIN_CHALLENGE      16
@@ -63,27 +63,43 @@ chap_md5_verify_response(int id, char *name,
                         unsigned char *challenge, unsigned char *response,
                         char *message, int message_space)
 {
-       MD5_CTX ctx;
        unsigned char idbyte = id;
        unsigned char hash[MD5_HASH_SIZE];
+    unsigned int  hash_len = MD5_HASH_SIZE;
        int challenge_len, response_len;
+    bool success = 0;
 
        challenge_len = *challenge++;
        response_len = *response++;
        if (response_len == MD5_HASH_SIZE) {
+
                /* Generate hash of ID, secret, challenge */
-               MD5_Init(&ctx);
-               MD5_Update(&ctx, &idbyte, 1);
-               MD5_Update(&ctx, secret, secret_len);
-               MD5_Update(&ctx, challenge, challenge_len);
-               MD5_Final(hash, &ctx);
-
-               /* Test if our hash matches the peer's response */
-               if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
-                       slprintf(message, message_space, "Access granted");
-                       return 1;
-               }
+        PPP_MD_CTX* ctx = PPP_MD_CTX_new();
+        if (ctx) {
+
+            if (PPP_DigestInit(ctx, PPP_md5())) {
+
+                if (PPP_DigestUpdate(ctx, &idbyte, 1)) {
+
+                    if (PPP_DigestUpdate(ctx, secret, secret_len)) {
+
+                        if (PPP_DigestUpdate(ctx, challenge, challenge_len)) {
+
+                            if (PPP_DigestFinal(ctx, hash, &hash_len)) {
+
+                                success = 1;
+                            }
+                        }
+                    }
+                }
+            }
+            PPP_MD_CTX_free(ctx);
+        }
        }
+    if (success && memcmp(hash, response, hash_len) == 0) {
+        slprintf(message, message_space, "Access granted");
+        return 1;
+    }
        slprintf(message, message_space, "Access denied");
        return 0;
 }
@@ -93,16 +109,31 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name,
                       unsigned char *challenge, char *secret, int secret_len,
                       unsigned char *private)
 {
-       MD5_CTX ctx;
        unsigned char idbyte = id;
        int challenge_len = *challenge++;
+    int hash_len = MD5_HASH_SIZE;
+
+    PPP_MD_CTX* ctx = PPP_MD_CTX_new();
+    if (ctx) {
+
+        if (PPP_DigestInit(ctx, PPP_md5())) {
+
+            if (PPP_DigestUpdate(ctx, &idbyte, 1)) {
+
+                if (PPP_DigestUpdate(ctx, secret, secret_len)) {
+
+                    if (PPP_DigestUpdate(ctx, challenge, challenge_len)) {
+
+                        if (PPP_DigestFinal(ctx, &response[1], &hash_len)) {
 
-       MD5_Init(&ctx);
-       MD5_Update(&ctx, &idbyte, 1);
-       MD5_Update(&ctx, (u_char *)secret, secret_len);
-       MD5_Update(&ctx, challenge, challenge_len);
-       MD5_Final(&response[1], &ctx);
-       response[0] = MD5_HASH_SIZE;
+                            response[0] = hash_len;
+                        }
+                    }
+                }
+            }
+        }
+        PPP_MD_CTX_free(ctx);
+    }
 }
 
 static struct chap_digest_type md5_digest = {
index 8e59280cbee6aab7b284b13a5222fa2b322a2f8e..45a10f38cd76162dbc7aa4c6bf06f5dc908ee55b 100644 (file)
 #include "pppd.h"
 #include "chap-new.h"
 #include "chap_ms.h"
-#include "md4.h"
-#include "sha1.h"
-#include "pppcrypt.h"
 #include "magic.h"
 #include "mppe.h"
+#include "ppp-crypto.h"
 
 #ifdef UNIT_TEST
 #undef PPP_WITH_MPPE
 
 static void    ascii2unicode (char[], int, u_char[]);
 static void    NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
-static void    ChallengeResponse (u_char *, u_char *, u_char[24]);
+static int     ChallengeResponse (u_char *, u_char *, u_char[24]);
 static void    ChapMS_NT (u_char *, char *, int, u_char[24]);
 static void    ChapMS2_NT (u_char *, u_char[16], char *, char *, int,
                                u_char[24]);
@@ -504,12 +502,19 @@ print_msg:
        free(msg);
 }
 
-static void
+// TODO: Move this definition somewhere
+#define NT_RESPONSE_LEN 24
+
+static int
 ChallengeResponse(u_char *challenge,
                  u_char PasswordHash[MD4_SIGNATURE_SIZE],
-                 u_char response[24])
+                 u_char response[NT_RESPONSE_LEN])
 {
-    u_char    ZPasswordHash[21];
+    u_char ZPasswordHash[21];
+    PPP_CIPHER_CTX *ctx;
+    int outlen = NT_RESPONSE_LEN;
+    int offset = 0;
+    int retval = 0;
 
     BZERO(ZPasswordHash, sizeof(ZPasswordHash));
     BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
@@ -519,16 +524,38 @@ ChallengeResponse(u_char *challenge,
           sizeof(ZPasswordHash), ZPasswordHash);
 #endif
 
-    (void) DesSetkey(ZPasswordHash + 0);
-    DesEncrypt(challenge, response + 0);
-    (void) DesSetkey(ZPasswordHash + 7);
-    DesEncrypt(challenge, response + 8);
-    (void) DesSetkey(ZPasswordHash + 14);
-    DesEncrypt(challenge, response + 16);
+    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 0
     dbglog("ChallengeResponse - response %.24B", response);
 #endif
+    return retval;
 }
 
 void
@@ -536,8 +563,9 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
              char *username, u_char Challenge[8])
     
 {
-    SHA1_CTX   sha1Context;
-    u_char     sha1Hash[SHA1_SIGNATURE_SIZE];
+    PPP_MD_CTX* ctx;
+    u_char     hash[SHA1_SIGNATURE_SIZE];
+    int     hash_len;
     char       *user;
 
     /* remove domain from "domain\username" */
@@ -545,14 +573,30 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
        ++user;
     else
        user = username;
+    
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, PeerChallenge, 16)) {
+
+                if (PPP_DigestUpdate(ctx, rchallenge, 16)) {
 
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PeerChallenge, 16);
-    SHA1_Update(&sha1Context, rchallenge, 16);
-    SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user));
-    SHA1_Final(sha1Hash, &sha1Context);
+                    if (PPP_DigestUpdate(ctx, user, strlen(user))) {
+                        
+                        hash_len = SHA1_SIGNATURE_SIZE;
+                        if (PPP_DigestFinal(ctx, hash, &hash_len)) {
 
-    BCOPY(sha1Hash, Challenge, 8);
+                            BCOPY(hash, Challenge, 8);
+                        }
+                    }
+                }
+            }
+        }
+
+        PPP_MD_CTX_free(ctx);
+    }
 }
 
 /*
@@ -575,26 +619,20 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[])
 static void
 NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
 {
-#if defined(__NetBSD__) || !defined(USE_MD4)
-    /* NetBSD uses the libc md4 routines which take bytes instead of bits */
-    int                        mdlen = secret_len;
-#else
-    int                        mdlen = secret_len * 8;
-#endif
-    MD4_CTX            md4Context;
-
-    MD4Init(&md4Context);
-#if !defined(USE_MD4)
-    /* Internal MD4Update can take at most 64 bytes at a time */
-    while (mdlen > 512) {
-       MD4Update(&md4Context, secret, 512);
-       secret += 64;
-       mdlen -= 512;
-    }
-#endif
-    MD4Update(&md4Context, secret, mdlen);
-    MD4Final(hash, &md4Context);
+    PPP_MD_CTX* ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_md4())) {
+
+            if (PPP_DigestUpdate(ctx, secret, secret_len)) {
 
+                int hash_len = MD4_SIGNATURE_SIZE;
+                PPP_DigestFinal(ctx, hash, &hash_len);
+            }
+        }
+        
+        PPP_MD_CTX_free(ctx);
+    }
 }
 
 static void
@@ -674,27 +712,58 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
          0x6E };
 
     int                i;
-    SHA1_CTX   sha1Context;
+    PPP_MD_CTX *ctx;
     u_char     Digest[SHA1_SIGNATURE_SIZE];
+    int     hash_len;
     u_char     Challenge[8];
 
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, NTResponse, 24);
-    SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
-    SHA1_Final(Digest, &sha1Context);
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
 
+            if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_SIGNATURE_SIZE)) {
+
+                if (PPP_DigestUpdate(ctx, NTResponse, 24)) {
+
+                    if (PPP_DigestUpdate(ctx, Magic1, sizeof(Magic1))) {
+                        
+                        hash_len = sizeof(Digest);
+                        PPP_DigestFinal(ctx, Digest, &hash_len);
+                    }
+                }
+            }
+        }
+        PPP_MD_CTX_free(ctx);
+    }
+    
     ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
 
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, Digest, sizeof(Digest));
-    SHA1_Update(&sha1Context, Challenge, sizeof(Challenge));
-    SHA1_Update(&sha1Context, Magic2, sizeof(Magic2));
-    SHA1_Final(Digest, &sha1Context);
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, Digest, sizeof(Digest))) {
+
+                if (PPP_DigestUpdate(ctx, Challenge, sizeof(Challenge))) {
+
+                    if (PPP_DigestUpdate(ctx, Magic2, sizeof(Magic2))) {
+                        
+                        hash_len = sizeof(Digest);
+                        PPP_DigestFinal(ctx, Digest, &hash_len);
+                    }
+                }
+            }
+        }
+
+        PPP_MD_CTX_free(ctx);
+    }
 
     /* Convert to ASCII hex string. */
-    for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++)
-       sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]);
+    for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) {
+        sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]);
+    }
 }
 
 
@@ -874,10 +943,10 @@ void random_bytes(unsigned char *bytes, int len)
 
 
 int test_chap_v1(void) {
-    char *secret = "TestPassword";
+    char *secret = "MyPw";
 
     unsigned char challenge[8] = {
-        0x6c, 0x8d, 0x4b, 0xa1, 0x2b, 0x5c, 0x13, 0xc3
+        0x10, 0x2D, 0xB5, 0xDF, 0x08, 0x5D, 0x30, 0x41
     };
     unsigned char response[MS_CHAP_RESPONSE_LEN] = {
     };
@@ -886,9 +955,10 @@ int test_chap_v1(void) {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
-        0x91, 0x09, 0x61, 0x5a, 0x0c, 0xac, 0xac, 0x55,
-        0x1f, 0x60, 0xe2, 0x9c, 0x00, 0xac, 0x24, 0xda,
-        0x6e, 0xa5, 0x7b, 0xdb, 0x1d, 0x6a, 0x17, 0xc5,
+        0x4E, 0x9D, 0x3C, 0x8F, 0x9C, 0xFD, 0x38, 0x5D,
+        0x5B, 0xF4, 0xD3, 0x24, 0x67, 0x91, 0x95, 0x6C,
+        0xA4, 0xC3, 0x51, 0xAB, 0x40, 0x9A, 0x3D, 0x61,
+
         0x01
     };
 
@@ -929,6 +999,8 @@ int test_chap_v2(void) {
 }
 
 int main(int argc, char *argv[]) {
+    
+    PPP_crypto_init();
 
     if (test_chap_v1()) {
         printf("CHAPv1 failed\n");
@@ -940,6 +1012,8 @@ int main(int argc, char *argv[]) {
         return -1;
     }
 
+    PPP_crypto_deinit();
+
     printf("Success\n");
     return 0;
 }
index 305a8387b0e8b213f2983a76dca8287e86051d62..8e0a4497f756b678c05fb12d574161554be01e80 100644 (file)
@@ -65,7 +65,7 @@
 
 #include "pppd.h"
 #include "pathnames.h"
-#include "md5.h"
+#include "ppp-crypto.h"
 #include "eap.h"
 #ifdef PPP_WITH_PEAP
 #include "peap.h"
@@ -78,7 +78,6 @@
 #include <t_pwd.h>
 #include <t_server.h>
 #include <t_client.h>
-#include "pppcrypt.h"
 #endif /* PPP_WITH_SRP */
 
 #ifndef SHA_DIGESTSIZE
@@ -337,20 +336,30 @@ pncrypt_setkey(int timeoffs)
 {
        struct tm *tp;
        char tbuf[9];
-       SHA1_CTX ctxt;
+    PPP_MD_CTX *ctxt;
        u_char dig[SHA_DIGESTSIZE];
+    int diglen = sizeof(dig);
        time_t reftime;
 
        if (pn_secret == NULL)
                return (0);
        reftime = time(NULL) + timeoffs;
        tp = localtime(&reftime);
-       SHA1Init(&ctxt);
-       SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
-       strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
-       SHA1Update(&ctxt, tbuf, strlen(tbuf));
-       SHA1Final(dig, &ctxt);
-       return (DesSetkey(dig));
+    ctxt = PPP_MD_CTX_new();
+    if (ctxt) {
+
+           strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
+
+        PPP_DigestInit(ctxt, PPP_sha1());
+        PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
+        PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
+        PPP_DigestFinal(ctxt, dig, &diglen);
+
+        PPP_MD_CTX_free(ctxt);
+           return (DesSetkey(dig));
+   }
+
+   return (0);
 }
 
 static char base64[] =
@@ -813,9 +822,9 @@ eap_send_request(eap_state *esp)
 #ifdef PPP_WITH_SRP
        struct t_server *ts;
        u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
-       int i, j;
+       int i, j, diglen;
        struct b64state b64;
-       SHA1_CTX ctxt;
+       PPP_MD_CTX *ctxt;
 #endif /* PPP_WITH_SRP */
 
        /* Handle both initial auth and restart */
@@ -1025,24 +1034,33 @@ eap_send_request(eap_state *esp)
                        }
 
                        /* Obscure the pseudonym with SHA1 hash */
-                       SHA1Init(&ctxt);
-                       SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
-                       SHA1Update(&ctxt, esp->es_server.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, esp->es_server.ea_peer,
-                           esp->es_server.ea_peerlen);
-                       while (optr < outp) {
-                               SHA1Final(dig, &ctxt);
-                               cp = dig;
-                               while (cp < dig + SHA_DIGESTSIZE)
-                                       *optr++ ^= *cp++;
-                               SHA1Init(&ctxt);
-                               SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
-                               SHA1Update(&ctxt, esp->es_server.ea_skey,
-                                   SESSION_KEY_LEN);
-                               SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
-                                   SHA_DIGESTSIZE);
-                       }
+            ctxt = PPP_MD_CTX_new();
+            if (ctxt) {
+
+                PPP_DigestInit(ctxt, PPP_sha1());
+                PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
+                PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
+                        SESSION_KEY_LEN);
+                PPP_DigestUpdate(ctxt,  esp->es_server.ea_peer,
+                        esp->es_server.ea_peerlen);
+
+                while (optr < outp) {
+                    diglen = SHA_DIGEST_LENGTH;
+                    PPP_DigestFinal(ctxt, dig, &diglen);
+                    cp = dig;
+                    while (cp < dig + SHA_DIGEST_LENGTH)
+                        *optr++ ^= *cp++;
+
+                    PPP_DigestInit(ctxt, PPP_sha1());
+                    PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
+                    PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
+                            SESSION_KEY_LEN);
+                    PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
+                            SHA_DIGEST_LENGTH);
+                           }
+
+                PPP_MD_CTX_free(ctxt);
+            }
                }
                break;
 
@@ -1322,7 +1340,7 @@ eap_chap_response(eap_state *esp, u_char id, u_char *hash,
        int msglen;
 
        outp = outpacket_buf;
-    
+
        MAKEHEADER(outp, PPP_EAP);
 
        PUTCHAR(EAP_RESPONSE, outp);
@@ -1547,9 +1565,9 @@ write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
 {
        u_char val;
        u_char *datp, *digp;
-       SHA1_CTX ctxt;
+       PPP_MD_CTX *ctxt;
        u_char dig[SHA_DIGESTSIZE];
-       int dsize, fd, olen = len;
+       int dsize, fd, olen = len, diglen = sizeof(dig);
 
        /*
         * Do the decoding by working backwards.  This eliminates the need
@@ -1561,18 +1579,26 @@ write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
                        dsize = SHA_DIGESTSIZE;
                len -= dsize;
                datp = inp + len;
-               SHA1Init(&ctxt);
-               SHA1Update(&ctxt, &val, 1);
-               SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
-               if (len > 0) {
-                       SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
-               } else {
-                       SHA1Update(&ctxt, esp->es_client.ea_name,
-                           esp->es_client.ea_namelen);
-               }
-               SHA1Final(dig, &ctxt);
-               for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
-                       *datp++ ^= *digp;
+        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);
+
+            for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
+                *datp++ ^= *digp;
+
+            PPP_MD_CTX_free(ctxt);
+        }
        }
 
        /* Now check that the result is sane */
@@ -1642,8 +1668,9 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
        int secret_len;
        char secret[MAXWORDLEN];
        char rhostname[256];
-       MD5_CTX mdContext;
+    PPP_MD_CTX *mdctx;
        u_char hash[MD5_SIGNATURE_SIZE];
+    int hashlen = MD5_SIGNATURE_SIZE;
 #ifdef PPP_WITH_EAPTLS
        u_char flags;
        struct eaptls_session *ets = esp->es_client.ea_session;
@@ -1653,8 +1680,9 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
        struct t_client *tc;
        struct t_num sval, gval, Nval, *Ap, Bval;
        u_char vals[2];
-       SHA1_CTX ctxt;
+       PPP_MD_CTX *ctxt;
        u_char dig[SHA_DIGESTSIZE];
+    int diglen = sizeof(dig);
        int fd;
 #endif /* PPP_WITH_SRP */
 
@@ -1780,15 +1808,29 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
                        eap_send_nak(esp, id, EAPT_SRP);
                        break;
                }
-               MD5_Init(&mdContext);
-               typenum = id;
-               MD5_Update(&mdContext, &typenum, 1);
-               MD5_Update(&mdContext, (u_char *)secret, secret_len);
-               BZERO(secret, sizeof (secret));
-               MD5_Update(&mdContext, inp, vallen);
-               MD5_Final(hash, &mdContext);
-               eap_chap_response(esp, id, hash, esp->es_client.ea_name,
-                   esp->es_client.ea_namelen);
+
+        mdctx = PPP_MD_CTX_new();
+        if (mdctx != NULL) {
+            if (PPP_DigestInit(mdctx, PPP_md5())) {
+                typenum = id;
+                if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
+                    if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
+                        BZERO(secret, sizeof(secret));
+                        if (PPP_DigestUpdate(mdctx, inp, vallen)) {
+                            if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
+                                eap_chap_response(esp, id, hash, esp->es_client.ea_name,
+                                    esp->es_client.ea_namelen);
+                                PPP_MD_CTX_free(mdctx);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            PPP_MD_CTX_free(mdctx);
+        }
+        dbglog("EAP: Invalid MD5 checksum");
+        eap_send_nak(esp, id, EAPT_SRP);
                break;
 
 #ifdef PPP_WITH_EAPTLS
@@ -2092,18 +2134,25 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
                                warn("EAP: malformed Lightweight rechallenge");
                                return;
                        }
-                       SHA1Init(&ctxt);
-                       vals[0] = id;
-                       SHA1Update(&ctxt, vals, 1);
-                       SHA1Update(&ctxt, esp->es_client.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, inp, len);
-                       SHA1Update(&ctxt, esp->es_client.ea_name,
-                           esp->es_client.ea_namelen);
-                       SHA1Final(dig, &ctxt);
-                       eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
-                           SHA_DIGESTSIZE);
-                       break;
+                       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);
+                       }
+            break;
 
                default:
                        error("EAP: unknown SRP Subtype %d", vallen);
@@ -2112,7 +2161,7 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
                }
                break;
 #endif /* PPP_WITH_SRP */
-    
+
 #ifdef PPP_WITH_CHAPMS
         case EAPT_MSCHAPV2:
            if (len < 4) {
@@ -2279,13 +2328,15 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
        int secret_len;
        char secret[MAXSECRETLEN];
        char rhostname[256];
-       MD5_CTX mdContext;
+    PPP_MD_CTX *mdctx;
        u_char hash[MD5_SIGNATURE_SIZE];
+    int hashlen = MD5_SIGNATURE_SIZE;
 #ifdef PPP_WITH_SRP
        struct t_server *ts;
        struct t_num A;
-       SHA1_CTX ctxt;
+       PPP_MD_CTX *ctxt;
        u_char dig[SHA_DIGESTSIZE];
+    int diglen = sizeof(dig);
 #endif /* PPP_WITH_SRP */
 
 #ifdef PPP_WITH_EAPTLS
@@ -2517,21 +2568,43 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                        eap_send_failure(esp);
                        break;
                }
-               MD5_Init(&mdContext);
-               MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
-               MD5_Update(&mdContext, (u_char *)secret, secret_len);
-               BZERO(secret, sizeof (secret));
-               MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
-               MD5_Final(hash, &mdContext);
-               if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
-                       eap_send_failure(esp);
-                       break;
-               }
-               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);
+
+        mdctx = PPP_MD_CTX_new();
+        if (mdctx != NULL) {
+
+            if (PPP_DigestInit(mdctx, PPP_md5())) {
+
+                if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
+
+                    if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
+
+                        BZERO(secret, sizeof(secret));
+                        if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
+
+                            if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
+
+                                if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) == 0) {
+
+                                    esp->es_server.ea_type = EAPT_MD5CHAP;
+                                    eap_send_success(esp);
+                                    eap_figure_next_state(esp, 0);
+
+                                    if (esp->es_rechallenge != 0) {
+                                        TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
+                                    }
+                                    PPP_MD_CTX_free(mdctx);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            PPP_MD_CTX_free(mdctx);
+        }
+
+               eap_send_failure(esp);
                break;
 
 #ifdef PPP_WITH_CHAPMS
@@ -2719,24 +2792,32 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                                    "response");
                                return;
                        }
-                       SHA1Init(&ctxt);
-                       vallen = id;
-                       SHA1Update(&ctxt, &vallen, 1);
-                       SHA1Update(&ctxt, esp->es_server.ea_skey,
-                           SESSION_KEY_LEN);
-                       SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
-                       SHA1Update(&ctxt, esp->es_server.ea_peer,
-                           esp->es_server.ea_peerlen);
-                       SHA1Final(dig, &ctxt);
-                       if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
-                               error("EAP: failed Lightweight rechallenge");
-                               eap_send_failure(esp);
-                               break;
-                       }
-                       esp->es_server.ea_state = eapOpen;
-                       if (esp->es_lwrechallenge != 0)
-                               TIMEOUT(srp_lwrechallenge, esp,
-                                   esp->es_lwrechallenge);
+            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);
+            }
                        break;
                }
                break;
index 7e4775226d16eb25c64ee89a01fcaa723d257117..8d5f32bb6efc8d55f121272900d527f76cc08427 100644 (file)
 #include "ccp.h"
 #include "ecp.h"
 #include "pathnames.h"
+#include "ppp-crypto.h"
 
 #ifdef PPP_WITH_TDB
 #include "tdb.h"
@@ -294,6 +295,8 @@ main(int argc, char *argv[])
     struct protent *protp;
     char numbuf[16];
 
+    PPP_crypto_init();
+
     strlcpy(path_ipup, PPP_PATH_IPUP, MAXPATHLEN);
     strlcpy(path_ipdown, PPP_PATH_IPDOWN, MAXPATHLEN);
 
@@ -581,6 +584,7 @@ main(int argc, char *argv[])
        }
     }
 
+    PPP_crypto_deinit();
     die(status);
     return 0;
 }
diff --git a/pppd/md4.c b/pppd/md4.c
deleted file mode 100644 (file)
index 88f3413..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-** ********************************************************************
-** md4.c -- Implementation of MD4 Message Digest Algorithm           **
-** Updated: 2/16/90 by Ronald L. Rivest                              **
-** (C) 1990 RSA Data Security, Inc.                                  **
-** ********************************************************************
-*/
-
-/*
-** To use MD4:
-**   -- Include md4.h in your program
-**   -- Declare an MDstruct MD to hold the state of the digest
-**          computation.
-**   -- Initialize MD using MDbegin(&MD)
-**   -- For each full block (64 bytes) X you wish to process, call
-**          MD4Update(&MD,X,512)
-**      (512 is the number of bits in a full block.)
-**   -- For the last block (less than 64 bytes) you wish to process,
-**          MD4Update(&MD,X,n)
-**      where n is the number of bits in the partial block. A partial
-**      block terminates the computation, so every MD computation
-**      should terminate by processing a partial block, even if it
-**      has n = 0.
-**   -- The message digest is available in MD.buffer[0] ...
-**      MD.buffer[3].  (Least-significant byte of each word
-**      should be output first.)
-**   -- You can print out the digest using MDprint(&MD)
-*/
-
-/* Implementation notes:
-** This implementation assumes that ints are 32-bit quantities.
-*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define TRUE  1
-#define FALSE 0
-
-/* Compile-time includes
-*/
-#include <stdio.h>
-#include "md4.h"
-#include "pppd.h"
-
-/* Compile-time declarations of MD4 "magic constants".
-*/
-#define I0  0x67452301       /* Initial values for MD buffer */
-#define I1  0xefcdab89
-#define I2  0x98badcfe
-#define I3  0x10325476
-#define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
-#define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
-/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
-** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
-** Table 2, page 660.
-*/
-
-#define fs1  3               /* round 1 shift amounts */
-#define fs2  7
-#define fs3 11
-#define fs4 19
-#define gs1  3               /* round 2 shift amounts */
-#define gs2  5
-#define gs3  9
-#define gs4 13
-#define hs1  3               /* round 3 shift amounts */
-#define hs2  9
-#define hs3 11
-#define hs4 15
-
-/* Compile-time macro declarations for MD4.
-** Note: The "rot" operator uses the variable "tmp".
-** It assumes tmp is declared as unsigned int, so that the >>
-** operator will shift in zeros rather than extending the sign bit.
-*/
-#define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
-#define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
-#define h(X,Y,Z)             (X^Y^Z)
-#define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
-#define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
-#define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
-#define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
-
-/* MD4print(MDp)
-** Print message digest buffer MDp as 32 hexadecimal digits.
-** Order is from low-order byte of buffer[0] to high-order byte of
-** buffer[3].
-** Each byte is printed with high-order hexadecimal digit first.
-** This is a user-callable routine.
-*/
-void
-MD4Print(MD4_CTX *MDp)
-{
-  int i,j;
-  for (i=0;i<4;i++)
-    for (j=0;j<32;j=j+8)
-      printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
-}
-
-/* MD4Init(MDp)
-** Initialize message digest buffer MDp.
-** This is a user-callable routine.
-*/
-void
-MD4Init(MD4_CTX *MDp)
-{
-  int i;
-  MDp->buffer[0] = I0;
-  MDp->buffer[1] = I1;
-  MDp->buffer[2] = I2;
-  MDp->buffer[3] = I3;
-  for (i=0;i<8;i++) MDp->count[i] = 0;
-  MDp->done = 0;
-}
-
-/* MDblock(MDp,X)
-** Update message digest buffer MDp->buffer using 16-word data block X.
-** Assumes all 16 words of X are full of data.
-** Does not update MDp->count.
-** This routine is not user-callable.
-*/
-static void
-MDblock(MD4_CTX *MDp, unsigned char *Xb)
-{
-  register unsigned int tmp, A, B, C, D;
-  unsigned int X[16];
-  int i;
-
-  for (i = 0; i < 16; ++i) {
-    X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
-    Xb += 4;
-  }
-
-  A = MDp->buffer[0];
-  B = MDp->buffer[1];
-  C = MDp->buffer[2];
-  D = MDp->buffer[3];
-  /* Update the message digest buffer */
-  ff(A , B , C , D ,  0 , fs1); /* Round 1 */
-  ff(D , A , B , C ,  1 , fs2);
-  ff(C , D , A , B ,  2 , fs3);
-  ff(B , C , D , A ,  3 , fs4);
-  ff(A , B , C , D ,  4 , fs1);
-  ff(D , A , B , C ,  5 , fs2);
-  ff(C , D , A , B ,  6 , fs3);
-  ff(B , C , D , A ,  7 , fs4);
-  ff(A , B , C , D ,  8 , fs1);
-  ff(D , A , B , C ,  9 , fs2);
-  ff(C , D , A , B , 10 , fs3);
-  ff(B , C , D , A , 11 , fs4);
-  ff(A , B , C , D , 12 , fs1);
-  ff(D , A , B , C , 13 , fs2);
-  ff(C , D , A , B , 14 , fs3);
-  ff(B , C , D , A , 15 , fs4);
-  gg(A , B , C , D ,  0 , gs1); /* Round 2 */
-  gg(D , A , B , C ,  4 , gs2);
-  gg(C , D , A , B ,  8 , gs3);
-  gg(B , C , D , A , 12 , gs4);
-  gg(A , B , C , D ,  1 , gs1);
-  gg(D , A , B , C ,  5 , gs2);
-  gg(C , D , A , B ,  9 , gs3);
-  gg(B , C , D , A , 13 , gs4);
-  gg(A , B , C , D ,  2 , gs1);
-  gg(D , A , B , C ,  6 , gs2);
-  gg(C , D , A , B , 10 , gs3);
-  gg(B , C , D , A , 14 , gs4);
-  gg(A , B , C , D ,  3 , gs1);
-  gg(D , A , B , C ,  7 , gs2);
-  gg(C , D , A , B , 11 , gs3);
-  gg(B , C , D , A , 15 , gs4);
-  hh(A , B , C , D ,  0 , hs1); /* Round 3 */
-  hh(D , A , B , C ,  8 , hs2);
-  hh(C , D , A , B ,  4 , hs3);
-  hh(B , C , D , A , 12 , hs4);
-  hh(A , B , C , D ,  2 , hs1);
-  hh(D , A , B , C , 10 , hs2);
-  hh(C , D , A , B ,  6 , hs3);
-  hh(B , C , D , A , 14 , hs4);
-  hh(A , B , C , D ,  1 , hs1);
-  hh(D , A , B , C ,  9 , hs2);
-  hh(C , D , A , B ,  5 , hs3);
-  hh(B , C , D , A , 13 , hs4);
-  hh(A , B , C , D ,  3 , hs1);
-  hh(D , A , B , C , 11 , hs2);
-  hh(C , D , A , B ,  7 , hs3);
-  hh(B , C , D , A , 15 , hs4);
-  MDp->buffer[0] += A;
-  MDp->buffer[1] += B;
-  MDp->buffer[2] += C;
-  MDp->buffer[3] += D;
-}
-
-/* MD4Update(MDp,X,count)
-** Input: X -- a pointer to an array of unsigned characters.
-**        count -- the number of bits of X to use.
-**          (if not a multiple of 8, uses high bits of last byte.)
-** Update MDp using the number of bits of X given by count.
-** This is the basic input routine for an MD4 user.
-** The routine completes the MD computation when count < 512, so
-** every MD computation should end with one call to MD4Update with a
-** count less than 512.  A call with count 0 will be ignored if the
-** MD has already been terminated (done != 0), so an extra call with
-** count 0 can be given as a "courtesy close" to force termination
-** if desired.
-*/
-void
-MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count)
-{
-  unsigned int i, tmp, bit, byte, mask;
-  unsigned char XX[64];
-  unsigned char *p;
-
-  /* return with no error if this is a courtesy close with count
-  ** zero and MDp->done is true.
-  */
-  if (count == 0 && MDp->done) return;
-  /* check to see if MD is already done and report error */
-  if (MDp->done)
-  { printf("\nError: MD4Update MD already done."); return; }
-
-  /* Add count to MDp->count */
-  tmp = count;
-  p = MDp->count;
-  while (tmp)
-  { tmp += *p;
-  *p++ = tmp;
-  tmp = tmp >> 8;
-  }
-
-  /* Process data */
-  if (count == 512)
-  { /* Full block of data to handle */
-    MDblock(MDp,X);
-  }
-  else if (count > 512) /* Check for count too large */
-  {
-    printf("\nError: MD4Update called with illegal count value %d.",
-          count);
-    return;
-  }
-  else /* partial block -- must be last block so finish up */
-  {
-    /* Find out how many bytes and residual bits there are */
-    byte = count >> 3;
-    bit =  count & 7;
-    /* Copy X into XX since we need to modify it */
-    if (count)
-      for (i=0;i<=byte;i++) XX[i] = X[i];
-    for (i=byte+1;i<64;i++) XX[i] = 0;
-    /* Add padding '1' bit and low-order zeros in last byte */
-    mask = 1 << (7 - bit);
-    XX[byte] = (XX[byte] | mask) & ~( mask - 1);
-    /* If room for bit count, finish up with this block */
-    if (byte <= 55)
-    {
-      for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
-      MDblock(MDp,XX);
-    }
-    else /* need to do two blocks to finish up */
-    {
-      MDblock(MDp,XX);
-      for (i=0;i<56;i++) XX[i] = 0;
-      for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
-      MDblock(MDp,XX);
-    }
-    /* Set flag saying we're done with MD computation */
-    MDp->done = 1;
-  }
-}
-
-/*
-** Finish up MD4 computation and return message digest.
-*/
-void
-MD4Final(unsigned char *buf, MD4_CTX *MD)
-{
-  int i, j;
-  unsigned int w;
-
-  MD4Update(MD, NULL, 0);
-  for (i = 0; i < 4; ++i) {
-    w = MD->buffer[i];
-    for (j = 0; j < 4; ++j) {
-      *buf++ = w;
-      w >>= 8;
-    }
-  }
-}
-
-/*
-** End of md4.c
-****************************(cut)***********************************/
diff --git a/pppd/md4.h b/pppd/md4.h
deleted file mode 100644 (file)
index 546ea02..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-/*
-** ********************************************************************
-** md4.h -- Header file for implementation of                        **
-** MD4 Message Digest Algorithm                                      **
-** Updated: 2/13/90 by Ronald L. Rivest                              **
-** (C) 1990 RSA Data Security, Inc.                                  **
-** ********************************************************************
-*/
-#ifndef PPP_MD4_H
-#define PPP_MD4_H
-
-#include "pppdconf.h"
-
-#ifndef USE_MD4
-#include <openssl/md4.h>
-#define MD4Init MD4_Init
-#define MD4Update MD4_Update
-#define MD4Final MD4_Final
-#else
-
-/* MDstruct is the data structure for a message digest computation.
-*/
-typedef struct {
-       unsigned int buffer[4]; /* Holds 4-word result of MD computation */
-       unsigned char count[8]; /* Number of bits processed so far */
-       unsigned int done;      /* Nonzero means MD computation finished */
-} MD4_CTX;
-
-/* MD4Init(MD4_CTX *)
-** Initialize the MD4_CTX prepatory to doing a message digest
-** computation.
-*/
-extern void MD4Init(MD4_CTX *MD);
-
-/* MD4Update(MD,X,count)
-** Input: X -- a pointer to an array of unsigned characters.
-**        count -- the number of bits of X to use (an unsigned int).
-** Updates MD using the first "count" bits of X.
-** The array pointed to by X is not modified.
-** If count is not a multiple of 8, MD4Update uses high bits of
-** last byte.
-** This is the basic input routine for a user.
-** The routine terminates the MD computation when count < 512, so
-** every MD computation should end with one call to MD4Update with a
-** count less than 512.  Zero is OK for a count.
-*/
-extern void MD4Update(MD4_CTX *MD, unsigned char *X, unsigned int count);
-
-/* MD4Print(MD)
-** Prints message digest buffer MD as 32 hexadecimal digits.
-** Order is from low-order byte of buffer[0] to high-order byte
-** of buffer[3].
-** Each byte is printed with high-order hexadecimal digit first.
-*/
-extern void MD4Print(MD4_CTX *);
-
-/* MD4Final(buf, MD)
-** Returns message digest from MD and terminates the message
-** digest computation.
-*/
-extern void MD4Final(unsigned char *, MD4_CTX *);
-
-/*
-** End of md4.h
-****************************(cut)***********************************/
-#endif  /* USE_MD4 */
-#endif  /* PPP_MD4_H */
diff --git a/pppd/md5.c b/pppd/md5.c
deleted file mode 100644 (file)
index 9fb3397..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-
-
-/*
- ***********************************************************************
- ** md5.c -- the source code for MD5 routines                         **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include "md5.h"
-
-/*
- ***********************************************************************
- **  Message-digest routines:                                         **
- **  To form the message digest for a message M                       **
- **    (1) Initialize a context buffer mdContext using MD5_Init       **
- **    (2) Call MD5_Update on mdContext and M                         **
- **    (3) Call MD5_Final on mdContext                                **
- **  The message digest is now in mdContext->digest[0...15]           **
- ***********************************************************************
- */
-
-/* forward declaration */
-static void Transform (UINT4 *buf, UINT4 *in);
-
-static unsigned char PADDING[64] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G, H and I are basic MD5 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s, ac) \
-  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) \
-  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) \
-  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) \
-  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-
-#ifdef __STDC__
-#define UL(x)  x##U
-#else
-#define UL(x)  x
-#endif
-
-/* The routine MD5_Init initializes the message-digest context
-   mdContext. All fields are set to zero.
- */
-void MD5_Init (MD5_CTX *mdContext)
-{
-  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
-
-  /* Load magic initialization constants.
-   */
-  mdContext->buf[0] = (UINT4)0x67452301;
-  mdContext->buf[1] = (UINT4)0xefcdab89;
-  mdContext->buf[2] = (UINT4)0x98badcfe;
-  mdContext->buf[3] = (UINT4)0x10325476;
-}
-
-/* The routine MD5Update updates the message-digest context to
-   account for the presence of each of the characters inBuf[0..inLen-1]
-   in the message whose digest is being computed.
- */
-void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
-{
-  UINT4 in[16];
-  int mdi;
-  unsigned int i, ii;
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* update number of bits */
-  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
-    mdContext->i[1]++;
-  mdContext->i[0] += ((UINT4)inLen << 3);
-  mdContext->i[1] += ((UINT4)inLen >> 29);
-
-  while (inLen--) {
-    /* add new character to buffer, increment mdi */
-    mdContext->in[mdi++] = *inBuf++;
-
-    /* transform if necessary */
-    if (mdi == 0x40) {
-      for (i = 0, ii = 0; i < 16; i++, ii += 4)
-        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-                (((UINT4)mdContext->in[ii+2]) << 16) |
-                (((UINT4)mdContext->in[ii+1]) << 8) |
-                ((UINT4)mdContext->in[ii]);
-      Transform (mdContext->buf, in);
-      mdi = 0;
-    }
-  }
-}
-
-/* The routine MD5Final terminates the message-digest computation and
-   ends with the desired message digest in mdContext->digest[0...15].
- */
-void MD5_Final (unsigned char hash[], MD5_CTX *mdContext)
-{
-  UINT4 in[16];
-  int mdi;
-  unsigned int i, ii;
-  unsigned int padLen;
-
-  /* save number of bits */
-  in[14] = mdContext->i[0];
-  in[15] = mdContext->i[1];
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* pad out to 56 mod 64 */
-  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-  MD5_Update (mdContext, PADDING, padLen);
-
-  /* append length in bits and transform */
-  for (i = 0, ii = 0; i < 14; i++, ii += 4)
-    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-            (((UINT4)mdContext->in[ii+2]) << 16) |
-            (((UINT4)mdContext->in[ii+1]) << 8) |
-            ((UINT4)mdContext->in[ii]);
-  Transform (mdContext->buf, in);
-
-  /* store buffer in digest */
-  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-    mdContext->digest[ii+1] =
-      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-    mdContext->digest[ii+2] =
-      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-    mdContext->digest[ii+3] =
-      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-  }
-  memcpy(hash, mdContext->digest, 16);
-}
-
-/* Basic MD5 step. Transforms buf based on in.
- */
-static void Transform (UINT4 *buf, UINT4 *in)
-{
-  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
-  /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
-  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
-  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
-  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
-  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
-  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
-  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
-  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
-  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
-  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
-  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
-  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
-  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
-  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
-  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
-  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
-
-  /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
-  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
-  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
-  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
-  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
-  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
-  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
-  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
-  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
-  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
-  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
-  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
-  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
-  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
-  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
-  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
-
-  /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
-  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
-  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
-  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
-  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
-  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
-  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
-  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
-  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
-  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
-  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
-  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
-  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
-  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
-  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
-  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
-
-  /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
-  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
-  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
-  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
-  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
-  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
-  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
-  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
-  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
-  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
-  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
-  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
-  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
-  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
-  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
-  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
-
-  buf[0] += a;
-  buf[1] += b;
-  buf[2] += c;
-  buf[3] += d;
-}
-
-/*
- ***********************************************************************
- ** End of md5.c                                                      **
- ******************************** (cut) ********************************
- */
diff --git a/pppd/md5.h b/pppd/md5.h
deleted file mode 100644 (file)
index 31f410d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- ***********************************************************************
- ** md5.h -- header file for implementation of MD5                    **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **
- ** Revised (for MD5): RLR 4/27/91                                    **
- **   -- G modified to have y&~z instead of y&z                       **
- **   -- FF, GG, HH modified to add in last register done             **
- **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
- **   -- distinct additive constant for each step                     **
- **   -- round 4 added, working mod 7                                 **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-#ifndef PPP_MD5_H
-#define PPP_MD5_H
-
-#include "pppdconf.h"
-
-#ifndef USE_MD5
-#include <openssl/md5.h>
-#else
-
-/* typedef a 32-bit type */
-#ifdef _LP64
-typedef unsigned int UINT4;
-typedef int          INT4;
-#else
-typedef unsigned long UINT4;
-typedef long          INT4;
-#endif
-#define _UINT4_T
-
-/* Data structure for MD5 (Message-Digest) computation */
-typedef struct {
-  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
-  UINT4 buf[4];                                    /* scratch buffer */
-  unsigned char in[64];                              /* input buffer */
-  unsigned char digest[16];     /* actual digest after MD5Final call */
-} MD5_CTX;
-
-void MD5_Init (MD5_CTX *mdContext);
-void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
-void MD5_Final (unsigned char hash[], MD5_CTX *mdContext);
-
-#endif /* USE_MD5 */
-#endif /* PPP_MD5_H */
index f1b7abf0ab206b8f7fd31a78c2d23557c84d2245..d3019b6fdc312c64b504cffc45c7b7f598ce1378 100644 (file)
@@ -1,4 +1,4 @@
-/* mppe.c - MPPE key implementation
+/* mppe.c - MPPE key implementation
  *
  * Copyright (c) 2020 Eivind Naess. All rights reserved.
  * Copyright (c) 2008 Paul Mackerras. All rights reserved.
@@ -26,7 +26,6 @@
  * 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.
- *
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include "pppd.h"
 #include "fsm.h"
-#include "md4.h"
-#include "sha1.h"
 #include "ccp.h"
 #include "chap_ms.h"
 #include "mppe.h"
+#include "ppp-crypto.h"
 
 u_char mppe_send_key[MPPE_MAX_KEY_SIZE];
 u_char mppe_recv_key[MPPE_MAX_KEY_SIZE];
@@ -113,14 +111,31 @@ mppe_clear_keys(void)
 void
 mppe_set_chapv1(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE])
 {
-    SHA1_CTX   sha1Context;
-    u_char     Digest[SHA1_SIGNATURE_SIZE];
+    PPP_MD_CTX *ctx;
+    u_char Digest[SHA1_SIGNATURE_SIZE];
+    int DigestLen;
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_SIGNATURE_SIZE)) {
+
+                if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_SIGNATURE_SIZE)) {
+
+                    if (PPP_DigestUpdate(ctx, rchallenge, 8)) {
+                        
+                        DigestLen = SHA1_SIGNATURE_SIZE;
+                        PPP_DigestFinal(ctx, Digest, &DigestLen);
+                    }
+                }
+            }
+        }
+        
+        PPP_MD_CTX_free(ctx);
+    }
 
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, rchallenge, 8);
-    SHA1_Final(Digest, &sha1Context);
 
     /* Same key in both directions. */
     mppe_set_keys(Digest, Digest, sizeof(Digest));
@@ -136,10 +151,12 @@ void
 mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
               u_char NTResponse[MS_AUTH_NTRESP_LEN], int IsServer)
 {
-    SHA1_CTX   sha1Context;
+    PPP_MD_CTX *ctx;
+    
     u_char     MasterKey[SHA1_SIGNATURE_SIZE];
     u_char     SendKey[SHA1_SIGNATURE_SIZE];
     u_char     RecvKey[SHA1_SIGNATURE_SIZE];
+    int KeyLen;
 
     u_char SHApad1[40] =
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -183,11 +200,26 @@ mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
          0x6b, 0x65, 0x79, 0x2e };
     u_char *s;
 
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, NTResponse, 24);
-    SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
-    SHA1_Final(MasterKey, &sha1Context);
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_SIGNATURE_SIZE)) {
+
+                if (PPP_DigestUpdate(ctx, NTResponse, 24)) {
+
+                    if (PPP_DigestUpdate(ctx, Magic1, sizeof(Magic1))) {
+                        
+                        KeyLen = SHA1_SIGNATURE_SIZE;
+                        PPP_DigestFinal(ctx, MasterKey, &KeyLen);
+                    }
+                }
+            }
+        }
+        
+        PPP_MD_CTX_free(ctx);
+    }
 
     /*
      * generate send key
@@ -196,12 +228,31 @@ mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
        s = Magic3;
     else
        s = Magic2;
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, MasterKey, 16);
-    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
-    SHA1_Update(&sha1Context, s, 84);
-    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
-    SHA1_Final(SendKey, &sha1Context);
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, MasterKey, 16)) {
+
+                if (PPP_DigestUpdate(ctx, SHApad1, sizeof(SHApad1))) {
+
+                    if (PPP_DigestUpdate(ctx, s, 84)) {
+
+                        if (PPP_DigestUpdate(ctx, SHApad2, sizeof(SHApad2))) {
+                        
+                            KeyLen = SHA1_SIGNATURE_SIZE;
+                            PPP_DigestFinal(ctx, SendKey, &KeyLen);
+                        }
+                    }
+                }
+            }
+        }
+        
+        PPP_MD_CTX_free(ctx);
+    }
+
 
     /*
      * generate recv key
@@ -210,12 +261,30 @@ mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
        s = Magic2;
     else
        s = Magic3;
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, MasterKey, 16);
-    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
-    SHA1_Update(&sha1Context, s, 84);
-    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
-    SHA1_Final(RecvKey, &sha1Context);
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx != NULL) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, MasterKey, 16)) {
+
+                if (PPP_DigestUpdate(ctx, SHApad1, sizeof(SHApad1))) {
+
+                    if (PPP_DigestUpdate(ctx, s, 84)) {
+
+                        if (PPP_DigestUpdate(ctx, SHApad2, sizeof(SHApad2))) {
+                        
+                            KeyLen = SHA1_SIGNATURE_SIZE;
+                            PPP_DigestFinal(ctx, RecvKey, &KeyLen);
+                        }
+                    }
+                }
+            }
+        }
+        
+        PPP_MD_CTX_free(ctx);
+    }
 
     mppe_set_keys(SendKey, RecvKey, SHA1_SIGNATURE_SIZE);
 }
diff --git a/pppd/ppp-crypto-priv.h b/pppd/ppp-crypto-priv.h
new file mode 100644 (file)
index 0000000..a0cc14c
--- /dev/null
@@ -0,0 +1,71 @@
+/* ppp-crypo-priv.h - Crypto private data structures
+ *
+ * Copyright (c) 2022 Eivind Næss. 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_CRYPTO_PRIV_H
+#define PPP_CRYPTO_PRIV_H
+
+#include "ppp-crypto.h"
+
+#define MAX_KEY_SIZE 32
+#define MAX_IV_SIZE 32
+
+struct _PPP_MD
+{
+    int  (*init_fn)(PPP_MD_CTX *ctx);
+    int  (*update_fn)(PPP_MD_CTX *ctx, const void *data, size_t cnt);
+    int  (*final_fn)(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen);
+    void (*clean_fn)(PPP_MD_CTX *ctx);
+};
+
+struct _PPP_MD_CTX
+{
+    PPP_MD md;
+    void *priv;
+};
+
+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);
+};
+
+struct _PPP_CIPHER_CTX
+{
+    PPP_CIPHER cipher;
+    unsigned char key[MAX_KEY_SIZE];
+    unsigned char iv[MAX_IV_SIZE];
+    int is_encr;
+    void *priv;
+};
+
+
+#endif
diff --git a/pppd/ppp-crypto.c b/pppd/ppp-crypto.c
new file mode 100644 (file)
index 0000000..bf78b65
--- /dev/null
@@ -0,0 +1,508 @@
+/* ppp-crypto.c - Generic API for access to crypto/digest functions.
+ *
+ * Copyright (c) 2022 Eivind Næss. 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ppp-crypto.h"
+#include "ppp-crypto-priv.h"
+
+#ifdef PPP_WITH_OPENSSL
+#include <openssl/opensslv.h>
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/provider.h>
+struct crypto_ctx {
+
+    OSSL_PROVIDER *legacy;
+    OSSL_PROVIDER *provider;
+} g_crypto_ctx;
+#endif
+
+PPP_MD_CTX *PPP_MD_CTX_new()
+{
+    return (PPP_MD_CTX*) calloc(1, sizeof(PPP_MD_CTX));
+}
+
+void PPP_MD_CTX_free(PPP_MD_CTX* ctx)
+{
+    if (ctx) {
+        if (ctx->md.clean_fn) {
+            ctx->md.clean_fn(ctx);
+        }
+        free(ctx);
+    }
+}
+
+int PPP_DigestInit(PPP_MD_CTX *ctx, const PPP_MD *type)
+{
+    if (ctx) {
+        ctx->md = *type;
+        if (ctx->md.init_fn) {
+            return ctx->md.init_fn(ctx);
+        }
+    }
+    return 0;
+}
+
+int PPP_DigestUpdate(PPP_MD_CTX *ctx, const void *data, size_t length)
+{
+    if (ctx && ctx->md.update_fn) {
+        return ctx->md.update_fn(ctx, data, length);
+    }
+    return 0;
+}
+
+int PPP_DigestFinal(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen)
+{
+    if (ctx && ctx->md.final_fn) {
+        return ctx->md.final_fn(ctx, out, outlen);
+    }
+    return 0;
+}
+
+PPP_CIPHER_CTX *PPP_CIPHER_CTX_new(void)
+{
+    return calloc(1, sizeof(PPP_CIPHER_CTX));
+}
+
+void PPP_CIPHER_CTX_free(PPP_CIPHER_CTX *ctx)
+{
+    if (ctx) {
+        if (ctx->cipher.clean_fn) {
+            ctx->cipher.clean_fn(ctx);
+        }
+        memset(ctx->iv, 0, sizeof(ctx->iv));
+        memset(ctx->key, 0, sizeof(ctx->key));
+        free(ctx);
+    }
+}
+
+int PPP_CipherInit(PPP_CIPHER_CTX *ctx, const PPP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int encr)
+{
+    if (ctx && cipher) {
+        ctx->is_encr = encr;
+        ctx->cipher = *cipher;
+        if (ctx->cipher.init_fn) {
+            ctx->cipher.init_fn(ctx, key, iv);
+        }
+        return 1;
+    }
+    return 0;
+}
+
+int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
+{
+    if (ctx && ctx->cipher.update_fn) {
+        return ctx->cipher.update_fn(ctx, out, outl, in, inl);
+    }
+    return 0;
+}
+
+int PPP_CipherFinal(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    if (ctx && ctx->cipher.final_fn) {
+        return ctx->cipher.final_fn(ctx, out, 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;
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+    g_crypto_ctx.legacy = OSSL_PROVIDER_load(NULL, "legacy");
+    if (g_crypto_ctx.legacy == NULL)
+    {
+        goto done;
+    }
+
+    g_crypto_ctx.provider = OSSL_PROVIDER_load(NULL, "default");
+    if (g_crypto_ctx.provider == NULL)
+    {
+        goto done;
+    }
+#endif
+    retval = 1;
+
+done:
+
+    return retval;
+}
+
+int PPP_crypto_deinit()
+{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+    if (g_crypto_ctx.legacy) {
+        OSSL_PROVIDER_unload(g_crypto_ctx.legacy);
+        g_crypto_ctx.legacy = NULL;
+    }
+
+    if (g_crypto_ctx.provider) {
+        OSSL_PROVIDER_unload(g_crypto_ctx.provider);
+        g_crypto_ctx.provider = NULL;
+    }
+#endif
+    return 1;
+}
+
+#ifdef UNIT_TEST
+#include <stdio.h>
+
+int test_md4()
+{
+    PPP_MD_CTX* ctx = NULL;
+    int success = 0;
+
+    unsigned char data[84] = {
+        0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63,
+        0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69,
+        0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+        0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+        0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+           0x6b, 0x65, 0x79, 0x2e
+    };
+
+    unsigned int  hash_len;
+    unsigned char hash[MD4_DIGEST_LENGTH];
+    unsigned char result[MD4_DIGEST_LENGTH] = {
+        0x58, 0xcb, 0x37, 0x91, 0x1d, 0x06, 0x7b, 0xdf,
+        0xfd, 0x48, 0x6d, 0x87, 0x4a, 0x35, 0x5b, 0xd4
+    };
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx) {
+
+        if (PPP_DigestInit(ctx, PPP_md4())) {
+
+            if (PPP_DigestUpdate(ctx, &data, sizeof(data))) {
+
+                hash_len = sizeof(hash);
+                if (PPP_DigestFinal(ctx, hash, &hash_len)) {
+
+                    if (memcmp(hash, result, MD4_DIGEST_LENGTH) == 0) {
+                        success = 1;
+                    }
+                }
+            }
+        }
+        PPP_MD_CTX_free(ctx);
+    }
+
+    return success;
+}
+
+int test_md5()
+{
+    PPP_MD_CTX* ctx = NULL;
+    int success = 0;
+
+    unsigned char data[84] = {
+        0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63,
+        0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69,
+        0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+        0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+        0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+           0x6b, 0x65, 0x79, 0x2e
+    };
+
+    unsigned int  hash_len;
+    unsigned char hash[MD5_DIGEST_LENGTH];
+    unsigned char result[MD5_DIGEST_LENGTH] = {
+        0x8b, 0xe3, 0x5e, 0x2c, 0x9f, 0x95, 0xbf, 0x4e,
+        0x16, 0xe4, 0x53, 0xbe, 0x52, 0xf4, 0xbc, 0x4e
+    };
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx) {
+
+        if (PPP_DigestInit(ctx, PPP_md5())) {
+
+            if (PPP_DigestUpdate(ctx, &data, sizeof(data))) {
+
+                hash_len = sizeof(hash);
+                if (PPP_DigestFinal(ctx, hash, &hash_len)) {
+
+                    if (memcmp(hash, result, MD5_DIGEST_LENGTH) == 0) {
+                        success = 1;
+                    }
+                }
+            }
+        }
+        PPP_MD_CTX_free(ctx);
+    }
+
+    return success;
+}
+
+int test_sha()
+{
+    PPP_MD_CTX* ctx = NULL;
+    int success = 0;
+
+    unsigned char data[84] = {
+        0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63,
+        0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69,
+        0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+        0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+        0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+           0x6b, 0x65, 0x79, 0x2e
+    };
+
+    unsigned int  hash_len;
+    unsigned char hash[SHA_DIGEST_LENGTH];
+    unsigned char result[SHA_DIGEST_LENGTH] = {
+        0xa8, 0x03, 0xae, 0x21, 0x30, 0xd8, 0x40, 0xbe,
+        0x27, 0xa3, 0x47, 0xc7, 0x7a, 0x90, 0xe6, 0xa3,
+        0x5b, 0xd5, 0x0e, 0x45
+    };
+
+    ctx = PPP_MD_CTX_new();
+    if (ctx) {
+
+        if (PPP_DigestInit(ctx, PPP_sha1())) {
+
+            if (PPP_DigestUpdate(ctx, &data, sizeof(data))) {
+
+                hash_len = sizeof(hash);
+                if (PPP_DigestFinal(ctx, hash, &hash_len)) {
+
+                    if (memcmp(hash, result, SHA_DIGEST_LENGTH) == 0) {
+                        success = 1;
+                    }
+                }
+            }
+        }
+        PPP_MD_CTX_free(ctx);
+    }
+
+    return success;
+}
+
+int test_des_encrypt()
+{
+    PPP_CIPHER_CTX* ctx = NULL;
+    int success = 0;
+
+    unsigned char key[8] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+    };
+
+    unsigned char plain[80] = {
+        0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63,
+        0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69,
+        0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+        0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+        0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20
+    };
+    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
+    };
+
+    unsigned char cipher[80] = {};
+    int cipher_len = 0;
+    int offset = 0;
+
+
+    ctx = PPP_CIPHER_CTX_new();
+    if (ctx) {
+
+        if (PPP_CipherInit(ctx, PPP_des_ecb(), key, NULL, 1)) {
+
+            if (PPP_CipherUpdate(ctx, cipher, &cipher_len, plain, sizeof(plain))) {
+
+                offset += cipher_len;
+
+                if (PPP_CipherFinal(ctx, cipher+offset, &cipher_len)) {
+
+                    if (memcmp(cipher, expect, 80) == 0) {
+
+                        success = 1;
+                    }
+                }
+            }
+        }
+        PPP_CIPHER_CTX_free(ctx);
+    }
+
+    return success;
+}
+
+
+int test_des_decrypt()
+{
+    PPP_CIPHER_CTX* ctx = NULL;
+    int success = 0;
+
+    unsigned char key[8] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+    };
+
+    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
+    };
+
+    unsigned char expect[80] = {
+        0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63,
+        0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69,
+        0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+        0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
+        0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74,
+        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20
+    };
+
+    unsigned char plain[80] = {};
+    int outlen = 0;
+    int offset = 0;
+
+    ctx = PPP_CIPHER_CTX_new();
+    if (ctx) {
+
+        if (PPP_CipherInit(ctx, PPP_des_ecb(), key, NULL, 0)) {
+
+            if (PPP_CipherUpdate(ctx, plain, &outlen, cipher, sizeof(cipher))) {
+
+                offset += outlen;
+
+                if (PPP_CipherFinal(ctx, plain+offset, &outlen)) {
+
+                    if (memcmp(plain, expect, 80) == 0) {
+
+                        success = 1;
+                    }
+                }
+            }
+        }
+        PPP_CIPHER_CTX_free(ctx);
+    }
+
+    return success;
+}
+
+int main(int argc, char *argv[]) {
+    int failure = 0;
+
+    if (!PPP_crypto_init()) {
+        printf("Couldn't initialize crypto test\n");
+        return -1;
+    }
+
+    if (!test_md4()) {
+        printf("MD4 test failed\n");
+        failure++;
+    }
+
+    if (!test_md5()) {
+        printf("MD5 test failed\n");
+        failure++;
+    }
+
+    if (!test_sha()) {
+        printf("SHA test failed\n");
+        failure++;
+    }
+
+    if (!test_des_encrypt()) {
+        printf("DES encryption test failed\n");
+        failure++;
+    }
+
+    /* Bug in DES EVP decryption, TODO: file an issue
+    if (!test_des_decrypt()) {
+        printf("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/ppp-crypto.h b/pppd/ppp-crypto.h
new file mode 100644 (file)
index 0000000..b1688b8
--- /dev/null
@@ -0,0 +1,97 @@
+/* ppp-crypto.h - Generic API for access to crypto/digest functions.
+ *
+ * Copyright (c) 2022 Eivind Næss. 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_CRYPTO_H
+#define PPP_CRYPTO_H
+
+
+#ifndef SHA1_SIGNATURE_SIZE
+#ifdef SHA_DIGESTSIZE
+#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
+#else
+#define SHA1_SIGNATURE_SIZE 20
+#endif
+#endif
+
+
+struct _PPP_MD_CTX;
+struct _PPP_MD;
+
+typedef struct _PPP_MD_CTX PPP_MD_CTX;
+typedef struct _PPP_MD PPP_MD;
+
+
+PPP_MD_CTX *PPP_MD_CTX_new();
+void PPP_MD_CTX_free(PPP_MD_CTX*);
+
+
+const PPP_MD *PPP_md4(void);
+const PPP_MD *PPP_md5(void);
+const PPP_MD *PPP_sha1(void);
+
+
+int PPP_DigestInit(PPP_MD_CTX *ctx,
+        const PPP_MD *type);
+int PPP_DigestUpdate(PPP_MD_CTX *ctx,
+        const void *data, size_t cnt);
+int PPP_DigestFinal(PPP_MD_CTX *ctx,
+        unsigned char *out, unsigned int *outlen);
+
+
+struct _PPP_CIPHER_CTX;
+struct _PPP_CIPHER;
+
+typedef struct _PPP_CIPHER_CTX PPP_CIPHER_CTX;
+typedef struct _PPP_CIPHER PPP_CIPHER;
+
+
+PPP_CIPHER_CTX *PPP_CIPHER_CTX_new(void);
+void PPP_CIPHER_CTX_free(PPP_CIPHER_CTX *ctx);
+
+const PPP_CIPHER *PPP_des_ecb(void);
+
+void PPP_CIPHER_CTX_set_cipher_data(PPP_CIPHER_CTX *ctx,
+        const unsigned char *key);
+
+int PPP_CipherInit(PPP_CIPHER_CTX *ctx,
+        const PPP_CIPHER *cipher,
+        const unsigned char *key, const unsigned char *iv,
+        int encr);
+
+int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx,
+        unsigned char *out, int *outl,
+        const unsigned char *in, int inl);
+
+int PPP_CipherFinal(PPP_CIPHER_CTX *ctx,
+        unsigned char *out, int *outl);
+
+int PPP_crypto_init();
+int PPP_crypto_deinit();
+
+#endif
diff --git a/pppd/ppp-des.c b/pppd/ppp-des.c
new file mode 100644 (file)
index 0000000..9c93e9c
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+ * ppp-des.c - PPP/DES implementation for MS-CHAP and EAP SRP-SHA1
+ *
+ * Extracted from chap_ms.c by James Carlson.
+ * Added abstraction via PPP_Digest* callbacks by Eivind Næss
+ *
+ * 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.
+ *
+ * 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 <stdlib.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>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_cleanup
+#endif
+
+static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv)
+{
+    if (ctx) {
+        EVP_CIPHER_CTX *cc = EVP_CIPHER_CTX_new();
+        if (cc) {
+            if (key) {
+                MakeKey(key, ctx->key);
+            }
+            if (EVP_CipherInit(cc, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr)) {
+                ctx->priv = cc;
+                return 1;
+            }
+            EVP_CIPHER_CTX_free(cc);
+        }
+    }
+    return 0;
+}
+
+static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
+{
+    if (ctx) {
+        return EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx->priv, out, outl, in, inl);
+    }
+    return 0;
+}
+
+static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    if (ctx) {
+        return EVP_CipherFinal((EVP_CIPHER_CTX*) ctx->priv, out, outl);
+    }
+    return 0;
+}
+
+static void des_clean(PPP_CIPHER_CTX *ctx)
+{
+    if (ctx->priv) {
+        EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*) ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+/**
+ * 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
+
+/*
+ * DES related functions are imported from openssl 3.0 project with the 
+ * follwoing license:
+ *
+ * Copyright 1995-2016 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 int DES_LONG;
+typedef unsigned char DES_cblock[8];
+typedef struct DES_ks {
+    union {
+        DES_cblock cblock;
+        /*
+         * make sure things are correct size on machines with 8 byte longs
+         */
+        DES_LONG deslong[2];
+    } ks[16];
+} DES_key_schedule;
+
+
+#define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
+                         l|=((DES_LONG)(*((c)++)))<<16L, \
+                         l|=((DES_LONG)(*((c)++)))<<24L)
+
+# define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+#define ITERATIONS 16
+
+#define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
+
+# define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+        (b)^=(t),\
+        (a)^=((t)<<(n)))
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+        (a)=(a)^(t)^(t>>(16-(n))))
+
+# define IP(l,r) \
+        { \
+        register DES_LONG tt; \
+        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+        PERM_OP(l,r,tt,16,0x0000ffffL); \
+        PERM_OP(r,l,tt, 2,0x33333333L); \
+        PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+        PERM_OP(r,l,tt, 1,0x55555555L); \
+        }
+
+# define FP(l,r) \
+        { \
+        register DES_LONG tt; \
+        PERM_OP(l,r,tt, 1,0x55555555L); \
+        PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+        PERM_OP(l,r,tt, 2,0x33333333L); \
+        PERM_OP(r,l,tt,16,0x0000ffffL); \
+        PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+        }
+
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+        u=R^s[S  ]; \
+        t=R^s[S+1]
+
+#define D_ENCRYPT(LL,R,S) { \
+        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+        t=ROTATE(t,4); \
+        LL^= \
+            DES_SPtrans[0][(u>> 2L)&0x3f]^ \
+            DES_SPtrans[2][(u>>10L)&0x3f]^ \
+            DES_SPtrans[4][(u>>18L)&0x3f]^ \
+            DES_SPtrans[6][(u>>26L)&0x3f]^ \
+            DES_SPtrans[1][(t>> 2L)&0x3f]^ \
+            DES_SPtrans[3][(t>>10L)&0x3f]^ \
+            DES_SPtrans[5][(t>>18L)&0x3f]^ \
+            DES_SPtrans[7][(t>>26L)&0x3f]; }
+
+
+static const DES_LONG DES_SPtrans[8][64] = {
+    {
+        /* nibble 0 */
+        0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+        0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+        0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+        0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+        0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+        0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+        0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+        0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+        0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+        0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+        0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+        0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+        0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+        0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+        0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+        0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+    },
+    {
+        /* nibble 1 */
+        0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+        0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+        0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+        0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+        0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+        0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+        0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+        0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+        0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+        0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+        0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+        0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+        0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+        0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+        0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+        0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+    },
+    {
+        /* nibble 2 */
+        0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+        0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+        0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+        0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+        0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+        0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+        0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+        0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+        0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+        0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+        0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+        0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+        0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+        0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+        0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+        0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+    },
+    {
+        /* nibble 3 */
+        0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+        0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+        0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+        0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+        0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+        0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+        0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+        0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+        0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+        0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+        0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+        0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+        0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+        0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+        0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+        0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+    },
+    {
+        /* nibble 4 */
+        0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+        0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+        0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+        0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+        0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+        0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+        0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+        0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+        0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+        0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+        0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+        0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+        0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+        0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+        0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+        0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+    },
+    {
+        /* nibble 5 */
+        0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+        0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+        0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+        0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+        0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+        0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+        0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+        0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+        0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+        0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+        0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+        0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+        0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+        0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+        0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+        0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+    },
+    {
+        /* nibble 6 */
+        0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+        0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+        0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+        0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+        0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+        0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+        0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+        0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+        0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+        0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+        0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+        0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+        0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+        0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+        0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+        0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+    },
+    {
+        /* nibble 7 */
+        0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+        0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+        0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+        0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+        0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+        0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+        0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+        0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+        0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+        0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+        0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+        0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+        0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+        0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+        0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+        0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+    }
+};
+
+static const DES_LONG des_skb[8][64] = {
+    {
+     /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+     0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
+     0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
+     0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
+     0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
+     0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
+     0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
+     0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
+     0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
+     0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
+     0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
+     0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
+     0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
+     0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
+     0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
+     0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
+     0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+     0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
+     0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
+     0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
+     0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
+     0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
+     0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
+     0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
+     0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
+     0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
+     0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
+     0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
+     0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
+     0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
+     0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
+     0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
+     0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+     0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
+     0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
+     0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
+     0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
+     0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
+     0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
+     0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
+     0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
+     0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
+     0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
+     0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
+     0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
+     0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
+     0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
+     0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
+     0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+     0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
+     0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
+     0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
+     0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
+     0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
+     0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
+     0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
+     0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
+     0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
+     0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
+     0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
+     0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
+     0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
+     0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
+     0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
+     0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+     0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
+     0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
+     0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
+     0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
+     0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
+     0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
+     0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
+     0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
+     0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
+     0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
+     0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
+     0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
+     0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
+     0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
+     0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
+     0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
+     },
+    {   
+     /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+     0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
+     0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
+     0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
+     0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
+     0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
+     0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
+     0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
+     0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
+     0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
+     0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
+     0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
+     0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
+     0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
+     0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
+     0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
+     0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+     0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
+     0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
+     0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
+     0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
+     0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
+     0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
+     0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
+     0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
+     0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
+     0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
+     0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
+     0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
+     0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
+     0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
+     0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
+     0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+     0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
+     0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
+     0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
+     0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
+     0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
+     0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
+     0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
+     0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
+     0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
+     0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
+     0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
+     0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
+     0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
+     0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
+     0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
+     0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
+     }
+};
+
+
+static void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+{
+    register DES_LONG l, r, t, u;
+    register DES_LONG *s; 
+
+    r = data[0];
+    l = data[1];
+
+    IP(r, l); 
+    /*  
+     * Things have been modified so that the initial rotate is done outside
+     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
+     * 1 bit to the right. One perl script later and things have a 5% speed
+     * up on a sparc2. Thanks to Richard Outerbridge for pointing this out.
+     */
+    /* clear the top bits on machines with 8byte longs */
+    /* shift left by 2 */
+    r = ROTATE(r, 29) & 0xffffffffL;
+    l = ROTATE(l, 29) & 0xffffffffL;
+
+    s = ks->ks->deslong;
+    /*  
+     * I don't know if it is worth the effort of loop unrolling the inner
+     * loop
+     */
+    if (enc) {
+        D_ENCRYPT(l, r, 0);     /* 1 */
+        D_ENCRYPT(r, l, 2);     /* 2 */
+        D_ENCRYPT(l, r, 4);     /* 3 */
+        D_ENCRYPT(r, l, 6);     /* 4 */
+        D_ENCRYPT(l, r, 8);     /* 5 */
+        D_ENCRYPT(r, l, 10);    /* 6 */
+        D_ENCRYPT(l, r, 12);    /* 7 */
+        D_ENCRYPT(r, l, 14);    /* 8 */
+        D_ENCRYPT(l, r, 16);    /* 9 */
+        D_ENCRYPT(r, l, 18);    /* 10 */
+        D_ENCRYPT(l, r, 20);    /* 11 */
+        D_ENCRYPT(r, l, 22);    /* 12 */
+        D_ENCRYPT(l, r, 24);    /* 13 */
+        D_ENCRYPT(r, l, 26);    /* 14 */
+        D_ENCRYPT(l, r, 28);    /* 15 */
+        D_ENCRYPT(r, l, 30);    /* 16 */
+    } else {
+        D_ENCRYPT(l, r, 30);    /* 16 */
+        D_ENCRYPT(r, l, 28);    /* 15 */
+        D_ENCRYPT(l, r, 26);    /* 14 */
+        D_ENCRYPT(r, l, 24);    /* 13 */
+        D_ENCRYPT(l, r, 22);    /* 12 */
+        D_ENCRYPT(r, l, 20);    /* 11 */
+        D_ENCRYPT(l, r, 18);    /* 10 */
+        D_ENCRYPT(r, l, 16);    /* 9 */
+        D_ENCRYPT(l, r, 14);    /* 8 */
+        D_ENCRYPT(r, l, 12);    /* 7 */
+        D_ENCRYPT(l, r, 10);    /* 6 */
+        D_ENCRYPT(r, l, 8);     /* 5 */
+        D_ENCRYPT(l, r, 6);     /* 4 */
+        D_ENCRYPT(r, l, 4);     /* 3 */
+        D_ENCRYPT(l, r, 2);     /* 2 */
+        D_ENCRYPT(r, l, 0);     /* 1 */
+    }   
+
+    /* rotate and clear the top bits on machines with 8byte longs */
+    l = ROTATE(l, 3) & 0xffffffffL;
+    r = ROTATE(r, 3) & 0xffffffffL;
+
+    FP(r, l); 
+    data[0] = l;
+    data[1] = r;
+    l = r = t = u = 0;
+}
+
+
+static void DES_ecb_encrypt(const DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks, int enc)
+{
+    register DES_LONG l;
+    DES_LONG ll[2];
+    const unsigned char *in = &(*input)[0];
+    unsigned char *out = &(*output)[0];
+
+    c2l(in, l); 
+    ll[0] = l;
+    c2l(in, l); 
+    ll[1] = l;
+    DES_encrypt1(ll, ks, enc);
+    l = ll[0];
+    l2c(l, out);
+    l = ll[1];
+    l2c(l, out);
+    l = ll[0] = ll[1] = 0;
+}
+
+
+static void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule)
+{
+    static const int shifts2[16] =
+        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
+    register DES_LONG c, d, t, s, t2;
+    register const unsigned char *in;
+    register DES_LONG *k;
+    register int i;
+
+#ifdef OPENBSD_DEV_CRYPTO
+    memcpy(schedule->key, key, sizeof(schedule->key));
+    schedule->session = NULL;
+#endif
+    k = &schedule->ks->deslong[0];
+    in = &(*key)[0];
+
+    c2l(in, c);
+    c2l(in, d);
+
+    /*
+     * do PC1 in 47 simple operations. Thanks to John Fletcher
+     * for the inspiration.
+     */
+    PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
+    HPERM_OP(c, t, -2, 0xcccc0000L);
+    HPERM_OP(d, t, -2, 0xcccc0000L);
+    PERM_OP(d, c, t, 1, 0x55555555L);
+    PERM_OP(c, d, t, 8, 0x00ff00ffL);
+    PERM_OP(d, c, t, 1, 0x55555555L);
+    d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
+         ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
+    c &= 0x0fffffffL;
+
+    for (i = 0; i < ITERATIONS; i++) {
+        if (shifts2[i]) {
+            c = ((c >> 2L) | (c << 26L));
+            d = ((d >> 2L) | (d << 26L));
+        } else {
+            c = ((c >> 1L) | (c << 27L));
+            d = ((d >> 1L) | (d << 27L));
+        }
+        c &= 0x0fffffffL;
+        d &= 0x0fffffffL;
+        /*
+         * could be a few less shifts but I am to lazy at this point in time
+         * to investigate
+         */
+        s = des_skb[0][(c) & 0x3f] |
+            des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
+            des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
+            des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
+                       ((c >> 22L) & 0x38)];
+        t = des_skb[4][(d) & 0x3f] |
+            des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
+            des_skb[6][(d >> 15L) & 0x3f] |
+            des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
+
+        /* table contained 0213 4657 */
+        t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
+        *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+
+        t2 = ((s >> 16L) | (t & 0xffff0000L));
+        *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+    }
+}
+
+/* End of import of OpenSSL DES encryption functions */
+
+static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv)
+{
+    DES_key_schedule *ks = calloc(1, sizeof(DES_key_schedule));
+    if (ks) {
+
+        if (key) {
+            MakeKey(key, ctx->key);
+            DES_set_key((DES_cblock*) &ctx->key, ks);
+        }
+
+        ctx->priv = ks;
+        return 1;
+    }
+
+    return 0;
+}
+
+static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
+{
+    int offset = 0;
+    inl = inl / 8;
+    while (offset < inl) {
+        DES_ecb_encrypt((DES_cblock *)in + offset, (DES_cblock *)out + offset,
+            (DES_key_schedule*) ctx->priv, ctx->is_encr);
+        offset ++;
+    }
+
+    *outl = offset * 8;
+    return 1;
+}
+
+static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    return 1;
+}
+
+static void des_clean(PPP_CIPHER_CTX *ctx)
+{
+    if (ctx->priv) {
+        free(ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+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,
+};
+
+const PPP_CIPHER *PPP_des_ecb(void)
+{
+    return &ppp_des;
+}
+
diff --git a/pppd/ppp-md4.c b/pppd/ppp-md4.c
new file mode 100644 (file)
index 0000000..305bfa8
--- /dev/null
@@ -0,0 +1,444 @@
+/* ppp-md4.c - MD4 Digest implementation
+ *
+ * Copyright (c) 2022 Eivind Næss. 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 <stdio.h>
+#include <stdlib.h>
+
+#include "ppp-crypto-priv.h"
+
+
+#ifdef OPENSSL_HAVE_MD4
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#endif
+
+
+static int md4_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+        if (mctx) {
+            if (EVP_DigestInit(mctx, EVP_md4())) {
+                ctx->priv = mctx;
+                return 1;
+            }
+            EVP_MD_CTX_free(mctx);
+        }
+    }
+    return 0;
+}
+
+static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len)
+{
+    if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void md4_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        EVP_MD_CTX_free(ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+
+#else // !OPENSSL_HAVE_MD4
+
+#define TRUE  1
+#define FALSE 0
+
+/*
+** ********************************************************************
+** md4.c -- Implementation of MD4 Message Digest Algorithm           **
+** Updated: 2/16/90 by Ronald L. Rivest                              **
+** (C) 1990 RSA Data Security, Inc.                                  **
+** ********************************************************************
+*/
+
+/*
+** To use MD4:
+**   -- Include md4.h in your program
+**   -- Declare an MDstruct MD to hold the state of the digest
+**          computation.
+**   -- Initialize MD using MDbegin(&MD)
+**   -- For each full block (64 bytes) X you wish to process, call
+**          MD4Update(&MD,X,512)
+**      (512 is the number of bits in a full block.)
+**   -- For the last block (less than 64 bytes) you wish to process,
+**          MD4Update(&MD,X,n)
+**      where n is the number of bits in the partial block. A partial
+**      block terminates the computation, so every MD computation
+**      should terminate by processing a partial block, even if it
+**      has n = 0.
+**   -- The message digest is available in MD.buffer[0] ...
+**      MD.buffer[3].  (Least-significant byte of each word
+**      should be output first.)
+**   -- You can print out the digest using MDprint(&MD)
+*/
+
+/* Implementation notes:
+** This implementation assumes that ints are 32-bit quantities.
+*/
+
+/* MDstruct is the data structure for a message digest computation.
+*/
+typedef struct {
+       unsigned int buffer[4]; /* Holds 4-word result of MD computation */
+       unsigned char count[8]; /* Number of bits processed so far */
+       unsigned int done;      /* Nonzero means MD computation finished */
+} MD4_CTX;
+
+
+/* Compile-time declarations of MD4 "magic constants".
+*/
+#define I0  0x67452301       /* Initial values for MD buffer */
+#define I1  0xefcdab89
+#define I2  0x98badcfe
+#define I3  0x10325476
+#define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
+#define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
+/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+** Table 2, page 660.
+*/
+
+#define fs1  3               /* round 1 shift amounts */
+#define fs2  7
+#define fs3 11
+#define fs4 19
+#define gs1  3               /* round 2 shift amounts */
+#define gs2  5
+#define gs3  9
+#define gs4 13
+#define hs1  3               /* round 3 shift amounts */
+#define hs2  9
+#define hs3 11
+#define hs4 15
+
+/* Compile-time macro declarations for MD4.
+** Note: The "rot" operator uses the variable "tmp".
+** It assumes tmp is declared as unsigned int, so that the >>
+** operator will shift in zeros rather than extending the sign bit.
+*/
+#define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
+#define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
+#define h(X,Y,Z)             (X^Y^Z)
+#define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+#define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
+#define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
+#define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+/* MD4print(MDp)
+** Print message digest buffer MDp as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte of
+** buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+** This is a user-callable routine.
+*/
+static void
+MD4Print(MD4_CTX *MDp)
+{
+  int i,j;
+  for (i=0;i<4;i++)
+    for (j=0;j<32;j=j+8)
+      printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+}
+
+/* MD4Init(MDp)
+** Initialize message digest buffer MDp.
+** This is a user-callable routine.
+*/
+static void
+MD4Init(MD4_CTX *MDp)
+{
+  int i;
+  MDp->buffer[0] = I0;
+  MDp->buffer[1] = I1;
+  MDp->buffer[2] = I2;
+  MDp->buffer[3] = I3;
+  for (i=0;i<8;i++) MDp->count[i] = 0;
+  MDp->done = 0;
+}
+
+/* MDblock(MDp,X)
+** Update message digest buffer MDp->buffer using 16-word data block X.
+** Assumes all 16 words of X are full of data.
+** Does not update MDp->count.
+** This routine is not user-callable.
+*/
+static void
+MDblock(MD4_CTX *MDp, unsigned char *Xb)
+{
+  register unsigned int tmp, A, B, C, D;
+  unsigned int X[16];
+  int i;
+
+  for (i = 0; i < 16; ++i) {
+    X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
+    Xb += 4;
+  }
+
+  A = MDp->buffer[0];
+  B = MDp->buffer[1];
+  C = MDp->buffer[2];
+  D = MDp->buffer[3];
+  /* Update the message digest buffer */
+  ff(A , B , C , D ,  0 , fs1); /* Round 1 */
+  ff(D , A , B , C ,  1 , fs2);
+  ff(C , D , A , B ,  2 , fs3);
+  ff(B , C , D , A ,  3 , fs4);
+  ff(A , B , C , D ,  4 , fs1);
+  ff(D , A , B , C ,  5 , fs2);
+  ff(C , D , A , B ,  6 , fs3);
+  ff(B , C , D , A ,  7 , fs4);
+  ff(A , B , C , D ,  8 , fs1);
+  ff(D , A , B , C ,  9 , fs2);
+  ff(C , D , A , B , 10 , fs3);
+  ff(B , C , D , A , 11 , fs4);
+  ff(A , B , C , D , 12 , fs1);
+  ff(D , A , B , C , 13 , fs2);
+  ff(C , D , A , B , 14 , fs3);
+  ff(B , C , D , A , 15 , fs4);
+  gg(A , B , C , D ,  0 , gs1); /* Round 2 */
+  gg(D , A , B , C ,  4 , gs2);
+  gg(C , D , A , B ,  8 , gs3);
+  gg(B , C , D , A , 12 , gs4);
+  gg(A , B , C , D ,  1 , gs1);
+  gg(D , A , B , C ,  5 , gs2);
+  gg(C , D , A , B ,  9 , gs3);
+  gg(B , C , D , A , 13 , gs4);
+  gg(A , B , C , D ,  2 , gs1);
+  gg(D , A , B , C ,  6 , gs2);
+  gg(C , D , A , B , 10 , gs3);
+  gg(B , C , D , A , 14 , gs4);
+  gg(A , B , C , D ,  3 , gs1);
+  gg(D , A , B , C ,  7 , gs2);
+  gg(C , D , A , B , 11 , gs3);
+  gg(B , C , D , A , 15 , gs4);
+  hh(A , B , C , D ,  0 , hs1); /* Round 3 */
+  hh(D , A , B , C ,  8 , hs2);
+  hh(C , D , A , B ,  4 , hs3);
+  hh(B , C , D , A , 12 , hs4);
+  hh(A , B , C , D ,  2 , hs1);
+  hh(D , A , B , C , 10 , hs2);
+  hh(C , D , A , B ,  6 , hs3);
+  hh(B , C , D , A , 14 , hs4);
+  hh(A , B , C , D ,  1 , hs1);
+  hh(D , A , B , C ,  9 , hs2);
+  hh(C , D , A , B ,  5 , hs3);
+  hh(B , C , D , A , 13 , hs4);
+  hh(A , B , C , D ,  3 , hs1);
+  hh(D , A , B , C , 11 , hs2);
+  hh(C , D , A , B ,  7 , hs3);
+  hh(B , C , D , A , 15 , hs4);
+  MDp->buffer[0] += A;
+  MDp->buffer[1] += B;
+  MDp->buffer[2] += C;
+  MDp->buffer[3] += D;
+}
+
+/* MD4Update(MDp,X,count)
+** Input: X -- a pointer to an array of unsigned characters.
+**        count -- the number of bits of X to use.
+**          (if not a multiple of 8, uses high bits of last byte.)
+** Update MDp using the number of bits of X given by count.
+** This is the basic input routine for an MD4 user.
+** The routine completes the MD computation when count < 512, so
+** every MD computation should end with one call to MD4Update with a
+** count less than 512.  A call with count 0 will be ignored if the
+** MD has already been terminated (done != 0), so an extra call with
+** count 0 can be given as a "courtesy close" to force termination
+** if desired.
+*/
+static void
+MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count)
+{
+  unsigned int i, tmp, bit, byte, mask;
+  unsigned char XX[64];
+  unsigned char *p;
+
+  /* return with no error if this is a courtesy close with count
+  ** zero and MDp->done is true.
+  */
+  if (count == 0 && MDp->done) return;
+  /* check to see if MD is already done and report error */
+  if (MDp->done)
+  { printf("\nError: MD4Update MD already done."); return; }
+
+  /* Add count to MDp->count */
+  tmp = count;
+  p = MDp->count;
+  while (tmp)
+  { tmp += *p;
+  *p++ = tmp;
+  tmp = tmp >> 8;
+  }
+
+  /* Process data */
+  if (count == 512)
+  { /* Full block of data to handle */
+    MDblock(MDp,X);
+  }
+  else if (count > 512) /* Check for count too large */
+  {
+    printf("\nError: MD4Update called with illegal count value %d.",
+          count);
+    return;
+  }
+  else /* partial block -- must be last block so finish up */
+  {
+    /* Find out how many bytes and residual bits there are */
+    byte = count >> 3;
+    bit =  count & 7;
+    /* Copy X into XX since we need to modify it */
+    if (count)
+      for (i=0;i<=byte;i++) XX[i] = X[i];
+    for (i=byte+1;i<64;i++) XX[i] = 0;
+    /* Add padding '1' bit and low-order zeros in last byte */
+    mask = 1 << (7 - bit);
+    XX[byte] = (XX[byte] | mask) & ~( mask - 1);
+    /* If room for bit count, finish up with this block */
+    if (byte <= 55)
+    {
+      for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+      MDblock(MDp,XX);
+    }
+    else /* need to do two blocks to finish up */
+    {
+      MDblock(MDp,XX);
+      for (i=0;i<56;i++) XX[i] = 0;
+      for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
+      MDblock(MDp,XX);
+    }
+    /* Set flag saying we're done with MD computation */
+    MDp->done = 1;
+  }
+}
+
+/*
+** Finish up MD4 computation and return message digest.
+*/
+static void
+MD4Final(unsigned char *buf, MD4_CTX *MD)
+{
+  int i, j;
+  unsigned int w;
+
+  MD4Update(MD, NULL, 0);
+  for (i = 0; i < 4; ++i) {
+    w = MD->buffer[i];
+    for (j = 0; j < 4; ++j) {
+      *buf++ = w;
+      w >>= 8;
+    }
+  }
+}
+
+/*
+** End of md4.c
+****************************(cut)***********************************/
+
+static int md4_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        MD4_CTX *mctx = calloc(1, sizeof(MD4_CTX));
+        if (mctx) {
+            MD4Init(mctx);
+            ctx->priv = mctx;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len)
+{
+#if defined(__NetBSD__)
+    /* NetBSD uses the libc md4 routines which take bytes instead of bits */
+    int                        mdlen = len;
+#else
+    int                        mdlen = len * 8;
+#endif
+
+    /* Internal MD4Update can take at most 64 bytes at a time */
+    while (mdlen > 512) {
+        MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, 512);
+        data += 64;
+        mdlen -= 512;
+    }
+    MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, mdlen);
+    return 1;
+}
+
+static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    MD4Final(out, (MD4_CTX*) ctx->priv);
+    return 1;
+}
+
+static void md4_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        free(ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+#endif
+
+static PPP_MD ppp_md4 = {
+    .init_fn = md4_init,
+    .update_fn = md4_update,
+    .final_fn = md4_final,
+    .clean_fn = md4_clean,
+};
+
+const PPP_MD *PPP_md4(void)
+{
+    return &ppp_md4;
+}
diff --git a/pppd/ppp-md5.c b/pppd/ppp-md5.c
new file mode 100644 (file)
index 0000000..dffb046
--- /dev/null
@@ -0,0 +1,451 @@
+/* ppp-md5.c - MD5 Digest implementation
+ *
+ * Copyright (c) 2022 Eivind Næss. 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 <stdlib.h>
+#include <string.h>
+
+#include "ppp-crypto-priv.h"
+
+#ifdef OPENSSL_HAVE_MD5
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#endif
+
+static int md5_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+        if (mctx) {
+            if (EVP_DigestInit((EVP_MD_CTX*) mctx, EVP_md5())) {
+                ctx->priv = mctx;
+                return 1;
+            }
+            EVP_MD_CTX_free(mctx);
+        }
+    }
+    return 0;
+}
+
+static int md5_update(PPP_MD_CTX *ctx, const void *data, size_t len)
+{
+    if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static int md5_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void md5_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        EVP_MD_CTX_free((EVP_MD_CTX*) ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+#else // !OPENSSL_HAVE_MD5
+
+/*
+ ***********************************************************************
+ ** md5.c -- the source code for MD5 routines                         **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
+ ** Created: 2/17/90 RLR                                              **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
+ **                                                                   **
+ ** License to copy and use this software is granted provided that    **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
+ ** Digest Algorithm" in all material mentioning or referencing this  **
+ ** software or this function.                                        **
+ **                                                                   **
+ ** License is also granted to make and use derivative works          **
+ ** provided that such works are identified as "derived from the RSA  **
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
+ ** material mentioning or referencing the derived work.              **
+ **                                                                   **
+ ** RSA Data Security, Inc. makes no representations concerning       **
+ ** either the merchantability of this software or the suitability    **
+ ** of this software for any particular purpose.  It is provided "as  **
+ ** is" without express or implied warranty of any kind.              **
+ **                                                                   **
+ ** These notices must be retained in any copies of any part of this  **
+ ** documentation and/or software.                                    **
+ ***********************************************************************
+ */
+
+
+/* typedef a 32-bit type */
+#ifdef _LP64
+typedef unsigned int UINT4;
+typedef int          INT4;
+#else
+typedef unsigned long UINT4;
+typedef long          INT4;
+#endif
+#define _UINT4_T
+
+/* Data structure for MD5 (Message-Digest) computation */
+typedef struct {
+  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
+  UINT4 buf[4];                                    /* scratch buffer */
+  unsigned char in[64];                              /* input buffer */
+  unsigned char digest[16];     /* actual digest after MD5Final call */
+} MD5_CTX;
+
+
+/*
+ ***********************************************************************
+ **  Message-digest routines:                                         **
+ **  To form the message digest for a message M                       **
+ **    (1) Initialize a context buffer mdContext using MD5_Init       **
+ **    (2) Call MD5_Update on mdContext and M                         **
+ **    (3) Call MD5_Final on mdContext                                **
+ **  The message digest is now in mdContext->digest[0...15]           **
+ ***********************************************************************
+ */
+
+/* forward declaration */
+static void Transform (UINT4 *buf, UINT4 *in);
+
+static unsigned char PADDING[64] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G, H and I are basic MD5 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) \
+  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) \
+  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) \
+  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+
+#ifdef __STDC__
+#define UL(x)  x##U
+#else
+#define UL(x)  x
+#endif
+
+/* The routine MD5_Init initializes the message-digest context
+   mdContext. All fields are set to zero.
+ */
+static void MD5_Init (MD5_CTX *mdContext)
+{
+  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
+
+  /* Load magic initialization constants.
+   */
+  mdContext->buf[0] = (UINT4)0x67452301;
+  mdContext->buf[1] = (UINT4)0xefcdab89;
+  mdContext->buf[2] = (UINT4)0x98badcfe;
+  mdContext->buf[3] = (UINT4)0x10325476;
+}
+
+/* The routine MD5Update updates the message-digest context to
+   account for the presence of each of the characters inBuf[0..inLen-1]
+   in the message whose digest is being computed.
+ */
+static void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* update number of bits */
+  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+    mdContext->i[1]++;
+  mdContext->i[0] += ((UINT4)inLen << 3);
+  mdContext->i[1] += ((UINT4)inLen >> 29);
+
+  while (inLen--) {
+    /* add new character to buffer, increment mdi */
+    mdContext->in[mdi++] = *inBuf++;
+
+    /* transform if necessary */
+    if (mdi == 0x40) {
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)
+        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+                (((UINT4)mdContext->in[ii+2]) << 16) |
+                (((UINT4)mdContext->in[ii+1]) << 8) |
+                ((UINT4)mdContext->in[ii]);
+      Transform (mdContext->buf, in);
+      mdi = 0;
+    }
+  }
+}
+
+/* The routine MD5Final terminates the message-digest computation and
+   ends with the desired message digest in mdContext->digest[0...15].
+ */
+static void MD5_Final (unsigned char hash[], MD5_CTX *mdContext)
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+  unsigned int padLen;
+
+  /* save number of bits */
+  in[14] = mdContext->i[0];
+  in[15] = mdContext->i[1];
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* pad out to 56 mod 64 */
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+  MD5_Update (mdContext, PADDING, padLen);
+
+  /* append length in bits and transform */
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)
+    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+            (((UINT4)mdContext->in[ii+2]) << 16) |
+            (((UINT4)mdContext->in[ii+1]) << 8) |
+            ((UINT4)mdContext->in[ii]);
+  Transform (mdContext->buf, in);
+
+  /* store buffer in digest */
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+    mdContext->digest[ii+1] =
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+    mdContext->digest[ii+2] =
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+    mdContext->digest[ii+3] =
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+  }
+  memcpy(hash, mdContext->digest, 16);
+}
+
+/* Basic MD5 step. Transforms buf based on in.
+ */
+static void Transform (UINT4 *buf, UINT4 *in)
+{
+  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+  /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
+  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
+  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
+  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
+  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
+  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
+  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
+  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
+  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
+  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
+  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
+  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
+  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
+  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
+  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
+  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
+
+  /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
+  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
+  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
+  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
+  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
+  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
+  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
+  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
+  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
+  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
+  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
+  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
+  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
+  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
+  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
+  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
+
+  /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
+  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
+  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
+  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
+  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
+  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
+  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
+  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
+  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
+  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
+  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
+  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
+  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
+  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
+  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
+  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
+
+  /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
+  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
+  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
+  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
+  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
+  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
+  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
+  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
+  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
+  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
+  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
+  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
+  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
+  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
+  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
+  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+/*
+ ***********************************************************************
+ ** End of md5.c                                                      **
+ ******************************** (cut) ********************************
+ */
+
+static int md5_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        MD5_CTX *md5 = calloc(1, sizeof(MD5_CTX));
+        if (md5 != NULL) {
+            MD5_Init(md5);
+            ctx->priv = md5;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int md5_update(PPP_MD_CTX *ctx, const void *data, size_t len)
+{
+    MD5_Update((MD5_CTX*) ctx->priv, (void*) data, len);
+    return 1;
+}
+
+static int md5_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    MD5_Final(out, (MD5_CTX*) ctx->priv);
+    return 1;
+}
+
+static void md5_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        free(ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+#endif
+
+static PPP_MD ppp_md5 = {
+    .init_fn = md5_init,
+    .update_fn = md5_update,
+    .final_fn = md5_final,
+    .clean_fn  = md5_clean,
+};
+
+const PPP_MD *PPP_md5(void)
+{
+    return &ppp_md5;
+}
+
diff --git a/pppd/ppp-sha1.c b/pppd/ppp-sha1.c
new file mode 100644 (file)
index 0000000..437c8ba
--- /dev/null
@@ -0,0 +1,312 @@
+/* ppp-sha1.c - SHA1 Digest implementation
+ *
+ * Copyright (c) 2022 Eivind Næss. 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 <stdlib.h>
+#include <stddef.h>
+
+#include "ppp-crypto-priv.h"
+
+
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+#ifdef OPENSSL_HAVE_SHA
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#endif
+
+static int sha1_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+        if (mctx) {
+            if (EVP_DigestInit(mctx, EVP_sha1())) {
+                ctx->priv = mctx;
+                return 1;
+            }
+            EVP_MD_CTX_free(mctx);
+        }
+    }
+    return 0;
+}
+
+static int sha1_update(PPP_MD_CTX *ctx, const void *data, size_t len)
+{
+    if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static int sha1_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void sha1_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        EVP_MD_CTX_free((EVP_MD_CTX*) ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+
+#else // !OPENSSL_HAVE_SHA
+
+/*
+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
+ *
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ *
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ */
+
+#include <string.h>
+#include <netinet/in.h>        /* htonl() */
+
+typedef struct {
+    u_int32_t state[5];
+    u_int32_t count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+
+static void
+SHA1_Transform(u_int32_t[5], const unsigned char[64]);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#define blk0(i) (block->l[i] = htonl(block->l[i]))
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+static void
+SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64])
+{
+    u_int32_t a, b, c, d, e;
+    typedef union {
+       unsigned char c[64];
+       u_int32_t l[16];
+    } CHAR64LONG16;
+    CHAR64LONG16 *block;
+
+#ifdef SHA1HANDSOFF
+    static unsigned char workspace[64];
+    block = (CHAR64LONG16 *) workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16 *) buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+static void
+SHA1_Init(SHA1_CTX *context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+static void
+SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
+{
+    unsigned int i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+    context->count[1] += (len >> 29);
+    i = 64 - j;
+    while (len >= i) {
+       memcpy(&context->buffer[j], data, i);
+       SHA1_Transform(context->state, context->buffer);
+       data += i;
+       len -= i;
+       i = 64;
+       j = 0;
+    }
+
+    memcpy(&context->buffer[j], data, len);
+}
+
+
+/* Add padding and return the message digest. */
+
+static void
+SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
+{
+    u_int32_t i, j;
+    unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1_Update(context, (unsigned char *) "\200", 1);
+    while ((context->count[0] & 504) != 448) {
+       SHA1_Update(context, (unsigned char *) "\0", 1);
+    }
+    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+       digest[i] = (unsigned char)
+                    ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+static int sha1_init(PPP_MD_CTX *ctx)
+{
+    if (ctx) {
+        SHA1_CTX *mctx = calloc(1, sizeof(SHA1_CTX));
+        if (mctx) {
+            SHA1_Init(mctx);
+            ctx->priv = mctx;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static int sha1_update(PPP_MD_CTX* ctx, const void *data, size_t len)
+{
+    SHA1_Update((SHA1_CTX*) ctx->priv, (void*) data, len);
+    return 1;
+}
+
+static int sha1_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len)
+{
+    SHA1_Final(out, (SHA1_CTX*) ctx->priv);
+    return 1;
+}
+
+static void sha1_clean(PPP_MD_CTX *ctx)
+{
+    if (ctx->priv) {
+        free(ctx->priv);
+        ctx->priv = NULL;
+    }
+}
+
+#endif
+
+static PPP_MD ppp_sha1 = {
+    .init_fn = sha1_init,
+    .update_fn = sha1_update,
+    .final_fn = sha1_final,
+    .clean_fn = sha1_clean,
+};
+
+const PPP_MD *PPP_sha1(void)
+{
+    return &ppp_sha1;
+}
+
diff --git a/pppd/pppcrypt.c b/pppd/pppcrypt.c
deleted file mode 100644 (file)
index a954d62..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <errno.h>
-
-#include "pppd.h"
-#include "pppcrypt.h"
-
-static u_char
-Get7Bits(u_char *input, int startBit)
-{
-       unsigned int word;
-
-       word  = (unsigned)input[startBit / 8] << 8;
-       word |= (unsigned)input[startBit / 8 + 1];
-
-       word >>= 15 - (startBit % 8 + 7);
-
-       return word & 0xFE;
-}
-
-static void
-MakeKey(u_char *key, u_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);
-
-#ifndef USE_CRYPT
-       DES_set_odd_parity((DES_cblock *)des_key);
-#endif
-}
-
-#ifdef USE_CRYPT
-/*
- * in == 8-byte string (expanded version of the 56-bit key)
- * out == 64-byte string where each byte is either 1 or 0
- * Note that the low-order "bit" is always ignored by by setkey()
- */
-static void
-Expand(u_char *in, u_char *out)
-{
-        int j, c;
-        int i;
-
-        for (i = 0; i < 64; in++){
-               c = *in;
-                for (j = 7; j >= 0; j--)
-                        *out++ = (c >> j) & 01;
-                i += 8;
-        }
-}
-
-/* The inverse of Expand
- */
-static void
-Collapse(u_char *in, u_char *out)
-{
-        int j;
-        int i;
-       unsigned int c;
-
-       for (i = 0; i < 64; i += 8, out++) {
-           c = 0;
-           for (j = 7; j >= 0; j--, in++)
-               c |= *in << j;
-           *out = c & 0xff;
-       }
-}
-
-bool
-DesSetkey(u_char *key)
-{
-       u_char des_key[8];
-       u_char crypt_key[66];
-
-       MakeKey(key, des_key);
-       Expand(des_key, crypt_key);
-       errno = 0;
-       setkey((const char *)crypt_key);
-       if (errno != 0)
-               return (0);
-       return (1);
-}
-
-bool
-DesEncrypt(u_char *clear, u_char *cipher)
-{
-       u_char des_input[66];
-
-       Expand(clear, des_input);
-       errno = 0;
-       encrypt((char *)des_input, 0);
-       if (errno != 0)
-               return (0);
-       Collapse(des_input, cipher);
-       return (1);
-}
-
-bool
-DesDecrypt(u_char *cipher, u_char *clear)
-{
-       u_char des_input[66];
-
-       Expand(cipher, des_input);
-       errno = 0;
-       encrypt((char *)des_input, 1);
-       if (errno != 0)
-               return (0);
-       Collapse(des_input, clear);
-       return (1);
-}
-
-#else /* USE_CRYPT */
-static DES_key_schedule        key_schedule;
-
-bool
-DesSetkey(u_char *key)
-{
-       DES_cblock des_key;
-       MakeKey(key, des_key);
-       DES_set_key(&des_key, &key_schedule);
-       return (1);
-}
-
-bool
-DesEncrypt(u_char *clear, u_char *cipher)
-{
-       DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
-           &key_schedule, 1);
-       return (1);
-}
-
-bool
-DesDecrypt(u_char *cipher, u_char *clear)
-{
-       DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear,
-           &key_schedule, 0);
-       return (1);
-}
-
-#endif /* USE_CRYPT */
diff --git a/pppd/pppcrypt.h b/pppd/pppcrypt.h
deleted file mode 100644 (file)
index fff396c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
- *
- * Extracted from chap_ms.c by James Carlson.
- *
- * Copyright (c) 1995 Eric Rosenquist.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The name(s) of the authors of this software must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission.
- *
- * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
- * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef PPP_PPPCRYPT_H
-#define        PPP_PPPCRYPT_H
-
-#include "pppdconf.h"
-
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
-#ifndef USE_CRYPT
-#include <openssl/des.h>
-#endif
-
-extern bool    DesSetkey(u_char *);
-extern bool    DesEncrypt(u_char *, u_char *);
-extern bool    DesDecrypt(u_char *, u_char *);
-
-#endif /* PPP_PPPCRYPT_H */
index 64c37f7f6c97b77f49535a53a216a0761c01b375..ad25dca63d06c1f141b769c5e3d8501f320588b9 100644 (file)
 /* Have PEAP authentication support */
 #undef PPP_WITH_PEAP
 
-/* Use included des included with pppd */
-#undef USE_CRYPT
-
-/* Use included md4 included with pppd */
-#undef USE_MD4
-
-/* Use included md5 included with pppd */
-#undef USE_MD5
-
-/* Use included sha included with pppd */
-#undef USE_SHA
-
 /* The pppd version */
 #undef PPPD_VERSION
 
diff --git a/pppd/sha1.c b/pppd/sha1.c
deleted file mode 100644 (file)
index 4fc5345..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
- * 
- * SHA-1 in C
- * By Steve Reid <steve@edmweb.com>
- * 100% Public Domain
- * 
- * Test Vectors (from FIPS PUB 180-1)
- * "abc"
- * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
- * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
- * A million repetitions of "a"
- * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-#include <string.h>
-#include <time.h>
-#include <netinet/in.h>        /* htonl() */
-#include "sha1.h"
-
-static void
-SHA1_Transform(u_int32_t[5], const unsigned char[64]);
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#define blk0(i) (block->l[i] = htonl(block->l[i]))
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-    ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-static void
-SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64])
-{
-    u_int32_t a, b, c, d, e;
-    typedef union {
-       unsigned char c[64];
-       u_int32_t l[16];
-    } CHAR64LONG16;
-    CHAR64LONG16 *block;
-
-#ifdef SHA1HANDSOFF
-    static unsigned char workspace[64];
-    block = (CHAR64LONG16 *) workspace;
-    memcpy(block, buffer, 64);
-#else
-    block = (CHAR64LONG16 *) buffer;
-#endif
-    /* Copy context->state[] to working vars */
-    a = state[0];
-    b = state[1];
-    c = state[2];
-    d = state[3];
-    e = state[4];
-    /* 4 rounds of 20 operations each. Loop unrolled. */
-    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-    /* Add the working vars back into context.state[] */
-    state[0] += a;
-    state[1] += b;
-    state[2] += c;
-    state[3] += d;
-    state[4] += e;
-    /* Wipe variables */
-    a = b = c = d = e = 0;
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void
-SHA1_Init(SHA1_CTX *context)
-{
-    /* SHA1 initialization constants */
-    context->state[0] = 0x67452301;
-    context->state[1] = 0xEFCDAB89;
-    context->state[2] = 0x98BADCFE;
-    context->state[3] = 0x10325476;
-    context->state[4] = 0xC3D2E1F0;
-    context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void
-SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
-{
-    unsigned int i, j;
-
-    j = (context->count[0] >> 3) & 63;
-    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
-    context->count[1] += (len >> 29);
-    i = 64 - j;
-    while (len >= i) {
-       memcpy(&context->buffer[j], data, i);
-       SHA1_Transform(context->state, context->buffer);
-       data += i;
-       len -= i;
-       i = 64;
-       j = 0;
-    }
-
-    memcpy(&context->buffer[j], data, len);
-}
-
-
-/* Add padding and return the message digest. */
-
-void
-SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
-{
-    u_int32_t i, j;
-    unsigned char finalcount[8];
-
-    for (i = 0; i < 8; i++) {
-        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
-    }
-    SHA1_Update(context, (unsigned char *) "\200", 1);
-    while ((context->count[0] & 504) != 448) {
-       SHA1_Update(context, (unsigned char *) "\0", 1);
-    }
-    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
-    for (i = 0; i < 20; i++) {
-       digest[i] = (unsigned char)
-                    ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-    }
-    /* Wipe variables */
-    i = j = 0;
-    memset(context->buffer, 0, 64);
-    memset(context->state, 0, 20);
-    memset(context->count, 0, 8);
-    memset(&finalcount, 0, 8);
-#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
-    SHA1Transform(context->state, context->buffer);
-#endif
-}
-
diff --git a/pppd/sha1.h b/pppd/sha1.h
deleted file mode 100644 (file)
index 2325133..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* sha1.h */
-
-#ifndef PPP_SHA1_H
-#define PPP_SHA1_H
-
-#include "pppdconf.h"
-
-#ifndef USE_SHA
-#include <openssl/sha.h>
-
-#define SHA1_CTX SHA_CTX
-#define SHA1_SIGNATURE_SIZE SHA_DIGEST_LENGTH
-
-#else
-
-#ifndef SHA1_SIGNATURE_SIZE
-#ifdef SHA_DIGESTSIZE
-#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
-#else
-#define SHA1_SIGNATURE_SIZE 20
-#endif
-#endif
-
-typedef struct {
-    u_int32_t state[5];
-    u_int32_t count[2];
-    unsigned char buffer[64];
-} SHA1_CTX;
-
-extern void SHA1_Init(SHA1_CTX *);
-extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
-extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
-
-#endif /* USE_SHA */
-#endif /* PPP_SHA1_H */