]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/eap.c
Create a new API to abstract the crypto functions used by pppd.
[ppp.git] / pppd / eap.c
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;