From 45f4a97a3a3f7e064228e0e3b42a7eb6c667cba9 Mon Sep 17 00:00:00 2001 From: Deepthi Gowri Date: Thu, 7 Feb 2013 00:55:06 +0200 Subject: [PATCH] eap_proxy: Add mechanism for allowing EAP methods to be offloaded 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 --- src/eap_peer/eap_proxy.h | 48 ++++++++++++++++++ src/eapol_supp/eapol_supp_sm.c | 92 ++++++++++++++++++++++++++++++++++ wpa_supplicant/Android.mk | 6 +++ wpa_supplicant/Makefile | 7 +++ wpa_supplicant/android.config | 2 + 5 files changed, 155 insertions(+) create mode 100644 src/eap_peer/eap_proxy.h diff --git a/src/eap_peer/eap_proxy.h b/src/eap_peer/eap_proxy.h new file mode 100644 index 000000000..3b4dceffc --- /dev/null +++ b/src/eap_peer/eap_proxy.h @@ -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 */ diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index f90fb6257..2e560865e 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -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); diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index da9577d80..d08b3f760 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -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 diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f39a3d7b9..da2abfce3 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -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) diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config index 265501041..6eacd0161 100644 --- a/wpa_supplicant/android.config +++ b/wpa_supplicant/android.config @@ -498,3 +498,5 @@ CONFIG_NO_ROAMING=y # Enable P2P CONFIG_P2P=y CONFIG_AP=y + +include $(wildcard $(LOCAL_PATH)/android_config_*.inc)