eap_proxy: Add mechanism for allowing EAP methods to be offloaded
authorDeepthi Gowri <deepthi@codeaurora.org>
Wed, 6 Feb 2013 22:55:06 +0000 (00:55 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 8 Feb 2013 09:54:01 +0000 (11:54 +0200)
In addition to the offload mechanism, the Android configuration and
makefiles are extended to allow this to be configured for the build by
dropping in platform specific configuration files and makefile without
having to modify any existing files.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/eap_peer/eap_proxy.h [new file with mode: 0644]
src/eapol_supp/eapol_supp_sm.c
wpa_supplicant/Android.mk
wpa_supplicant/Makefile
wpa_supplicant/android.config

diff --git a/src/eap_peer/eap_proxy.h b/src/eap_peer/eap_proxy.h
new file mode 100644 (file)
index 0000000..3b4dcef
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * EAP proxy definitions
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef EAP_PROXY_H
+#define EAP_PROXY_H
+
+struct eap_proxy_sm;
+struct eapol_callbacks;
+struct eap_sm;
+struct eap_peer_config;
+
+enum eap_proxy_status {
+       EAP_PROXY_FAILURE = 0x00,
+       EAP_PROXY_SUCCESS
+};
+
+struct eap_proxy_sm *
+eap_proxy_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
+              void *msg_ctx);
+
+void eap_proxy_deinit(struct eap_proxy_sm *eap_proxy);
+
+int eap_proxy_key_available(struct eap_proxy_sm *sm);
+
+const u8 * eap_proxy_get_eapKeyData(struct eap_proxy_sm *sm, size_t *len);
+
+struct wpabuf * eap_proxy_get_eapRespData(struct eap_proxy_sm *sm);
+
+int eap_proxy_sm_step(struct eap_proxy_sm *sm, struct eap_sm *eap_sm);
+
+enum eap_proxy_status
+eap_proxy_packet_update(struct eap_proxy_sm *eap_proxy, u8 *eapReqData,
+                       int eapReqDataLen);
+
+int eap_proxy_sm_get_status(struct eap_proxy_sm *sm, char *buf, size_t buflen,
+                           int verbose);
+
+int eap_proxy_get_imsi(char *imsi_buf, size_t *imsi_len);
+
+int eap_proxy_notify_config(struct eap_proxy_sm *sm,
+                           struct eap_peer_config *config);
+
+#endif /* EAP_PROXY_H */
index f90fb62..2e56086 100644 (file)
@@ -16,6 +16,7 @@
 #include "crypto/md5.h"
 #include "common/eapol_common.h"
 #include "eap_peer/eap.h"
+#include "eap_peer/eap_proxy.h"
 #include "eapol_supp_sm.h"
 
 #define STATE_MACHINE_DATA struct eapol_sm
@@ -136,6 +137,10 @@ struct eapol_sm {
        Boolean cached_pmk;
 
        Boolean unicast_key_received, broadcast_key_received;
+#ifdef CONFIG_EAP_PROXY
+       Boolean use_eap_proxy;
+       struct eap_proxy_sm *eap_proxy;
+#endif /* CONFIG_EAP_PROXY */
 };
 
 
@@ -463,6 +468,17 @@ SM_STATE(SUPP_BE, SUCCESS)
        sm->keyRun = TRUE;
        sm->suppSuccess = TRUE;
 
+#ifdef CONFIG_EAP_PROXY
+       if (sm->use_eap_proxy) {
+               if (eap_proxy_key_available(sm->eap_proxy)) {
+                       /* New key received - clear IEEE 802.1X EAPOL-Key replay
+                        * counter */
+                       sm->replay_counter_valid = FALSE;
+               }
+               return;
+       }
+#endif /* CONFIG_EAP_PROXY */
+
        if (eap_key_available(sm->eap)) {
                /* New key received - clear IEEE 802.1X EAPOL-Key replay
                 * counter */
@@ -806,6 +822,19 @@ static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
        struct wpabuf *resp;
 
        wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
+
+#ifdef CONFIG_EAP_PROXY
+       if (sm->use_eap_proxy) {
+               /* Get EAP Response from EAP Proxy */
+               resp = eap_proxy_get_eapRespData(sm->eap_proxy);
+               if (resp == NULL) {
+                       wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy "
+                                  "response data not available");
+                       return;
+               }
+       } else
+#endif /* CONFIG_EAP_PROXY */
+
        resp = eap_get_eapRespData(sm->eap);
        if (resp == NULL) {
                wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
@@ -883,6 +912,13 @@ void eapol_sm_step(struct eapol_sm *sm)
                SM_STEP_RUN(SUPP_PAE);
                SM_STEP_RUN(KEY_RX);
                SM_STEP_RUN(SUPP_BE);
+#ifdef CONFIG_EAP_PROXY
+               if (sm->use_eap_proxy) {
+                       /* Drive the EAP proxy state machine */
+                       if (eap_proxy_sm_step(sm->eap_proxy, sm->eap))
+                               sm->changed = TRUE;
+               } else
+#endif /* CONFIG_EAP_PROXY */
                if (eap_peer_sm_step(sm->eap))
                        sm->changed = TRUE;
                if (!sm->changed)
@@ -1070,6 +1106,13 @@ int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
                len += ret;
        }
 
+#ifdef CONFIG_EAP_PROXY
+       if (sm->use_eap_proxy)
+               len += eap_proxy_sm_get_status(sm->eap_proxy,
+                                              buf + len, buflen - len,
+                                              verbose);
+       else
+#endif /* CONFIG_EAP_PROXY */
        len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
 
        return len;
@@ -1227,6 +1270,16 @@ int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
                        wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet "
                                   "frame");
                        sm->eapolEap = TRUE;
+#ifdef CONFIG_EAP_PROXY
+                       if (sm->use_eap_proxy) {
+                               eap_proxy_packet_update(
+                                       sm->eap_proxy,
+                                       wpabuf_mhead_u8(sm->eapReqData),
+                                       wpabuf_len(sm->eapReqData));
+                               wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy "
+                                          "EAP Req updated");
+                       }
+#endif /* CONFIG_EAP_PROXY */
                        eapol_sm_step(sm);
                }
                break;
@@ -1387,6 +1440,9 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
                return;
 
        sm->config = config;
+#ifdef CONFIG_EAP_PROXY
+       sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0;
+#endif /* CONFIG_EAP_PROXY */
 
        if (conf == NULL)
                return;
@@ -1395,6 +1451,12 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
        sm->conf.required_keys = conf->required_keys;
        sm->conf.fast_reauth = conf->fast_reauth;
        sm->conf.workaround = conf->workaround;
+#ifdef CONFIG_EAP_PROXY
+       if (sm->use_eap_proxy) {
+               /* Using EAP Proxy, so skip EAP state machine update */
+               return;
+       }
+#endif /* CONFIG_EAP_PROXY */
        if (sm->eap) {
                eap_set_fast_reauth(sm->eap, conf->fast_reauth);
                eap_set_workaround(sm->eap, conf->workaround);
@@ -1419,6 +1481,22 @@ int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
        const u8 *eap_key;
        size_t eap_len;
 
+#ifdef CONFIG_EAP_PROXY
+       if (sm->use_eap_proxy) {
+               /* Get key from EAP proxy */
+               if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) {
+                       wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
+                       return -1;
+               }
+               eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len);
+               if (eap_key == NULL) {
+                       wpa_printf(MSG_DEBUG, "EAPOL: Failed to get "
+                                  "eapKeyData");
+                       return -1;
+               }
+               goto key_fetched;
+       }
+#endif /* CONFIG_EAP_PROXY */
        if (sm == NULL || !eap_key_available(sm->eap)) {
                wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
                return -1;
@@ -1428,6 +1506,9 @@ int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
                wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData");
                return -1;
        }
+#ifdef CONFIG_EAP_PROXY
+key_fetched:
+#endif /* CONFIG_EAP_PROXY */
        if (len > eap_len) {
                wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not "
                           "available (len=%lu)",
@@ -1889,6 +1970,14 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
                return NULL;
        }
 
+#ifdef CONFIG_EAP_PROXY
+       sm->use_eap_proxy = FALSE;
+       sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx);
+       if (sm->eap_proxy == NULL) {
+               wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy");
+       }
+#endif /* CONFIG_EAP_PROXY */
+
        /* Initialize EAPOL state machines */
        sm->initialize = TRUE;
        eapol_sm_step(sm);
@@ -1915,6 +2004,9 @@ void eapol_sm_deinit(struct eapol_sm *sm)
        eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
        eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
        eap_peer_sm_deinit(sm->eap);
+#ifdef CONFIG_EAP_PROXY
+       eap_proxy_deinit(sm->eap_proxy);
+#endif /* CONFIG_EAP_PROXY */
        os_free(sm->last_rx_key);
        wpabuf_free(sm->eapReqData);
        os_free(sm->ctx);
index da9577d..d08b3f7 100644 (file)
@@ -1473,6 +1473,12 @@ ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
 LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
 endif
 LOCAL_SHARED_LIBRARIES := libc libcutils
+
+ifdef CONFIG_EAP_PROXY
+OBJS += src/eap_peer/eap_proxy_$(CONFIG_EAP_PROXY).c
+include $(LOCAL_PATH)/eap_proxy_$(CONFIG_EAP_PROXY).mk
+endif
+
 ifeq ($(CONFIG_TLS), openssl)
 LOCAL_SHARED_LIBRARIES += libcrypto libssl
 endif
index f39a3d7..da2abfc 100644 (file)
@@ -482,6 +482,13 @@ CONFIG_EAP_SIM_COMMON=y
 NEED_AES_CBC=y
 endif
 
+ifdef CONFIG_EAP_PROXY
+CFLAGS += -DCONFIG_EAP_PROXY
+OBJS += ../src/eap_peer/eap_proxy_$(CONFIG_EAP_PROXY).o
+include eap_proxy_$(CONFIG_EAP_PROXY).mk
+CONFIG_IEEE8021X_EAPOL=y
+endif
+
 ifdef CONFIG_EAP_AKA_PRIME
 # EAP-AKA'
 ifeq ($(CONFIG_EAP_AKA_PRIME), dyn)
index 2655010..6eacd01 100644 (file)
@@ -498,3 +498,5 @@ CONFIG_NO_ROAMING=y
 # Enable P2P
 CONFIG_P2P=y
 CONFIG_AP=y
+
+include $(wildcard $(LOCAL_PATH)/android_config_*.inc)