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 <jouni@qca.qualcomm.com>
This commit is contained in:
Deepthi Gowri 2013-02-07 00:55:06 +02:00 committed by Jouni Malinen
parent 83e7aedf72
commit 45f4a97a3a
5 changed files with 155 additions and 0 deletions

48
src/eap_peer/eap_proxy.h Normal file
View file

@ -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 */

View file

@ -16,6 +16,7 @@
#include "crypto/md5.h" #include "crypto/md5.h"
#include "common/eapol_common.h" #include "common/eapol_common.h"
#include "eap_peer/eap.h" #include "eap_peer/eap.h"
#include "eap_peer/eap_proxy.h"
#include "eapol_supp_sm.h" #include "eapol_supp_sm.h"
#define STATE_MACHINE_DATA struct eapol_sm #define STATE_MACHINE_DATA struct eapol_sm
@ -136,6 +137,10 @@ struct eapol_sm {
Boolean cached_pmk; Boolean cached_pmk;
Boolean unicast_key_received, broadcast_key_received; 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->keyRun = TRUE;
sm->suppSuccess = 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)) { if (eap_key_available(sm->eap)) {
/* New key received - clear IEEE 802.1X EAPOL-Key replay /* New key received - clear IEEE 802.1X EAPOL-Key replay
* counter */ * counter */
@ -806,6 +822,19 @@ static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
struct wpabuf *resp; struct wpabuf *resp;
wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp"); 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); resp = eap_get_eapRespData(sm->eap);
if (resp == NULL) { if (resp == NULL) {
wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data " 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(SUPP_PAE);
SM_STEP_RUN(KEY_RX); SM_STEP_RUN(KEY_RX);
SM_STEP_RUN(SUPP_BE); 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)) if (eap_peer_sm_step(sm->eap))
sm->changed = TRUE; sm->changed = TRUE;
if (!sm->changed) if (!sm->changed)
@ -1070,6 +1106,13 @@ int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
len += ret; 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); len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
return len; 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 " wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet "
"frame"); "frame");
sm->eapolEap = TRUE; 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); eapol_sm_step(sm);
} }
break; break;
@ -1387,6 +1440,9 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
return; return;
sm->config = config; 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) if (conf == NULL)
return; return;
@ -1395,6 +1451,12 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
sm->conf.required_keys = conf->required_keys; sm->conf.required_keys = conf->required_keys;
sm->conf.fast_reauth = conf->fast_reauth; sm->conf.fast_reauth = conf->fast_reauth;
sm->conf.workaround = conf->workaround; 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) { if (sm->eap) {
eap_set_fast_reauth(sm->eap, conf->fast_reauth); eap_set_fast_reauth(sm->eap, conf->fast_reauth);
eap_set_workaround(sm->eap, conf->workaround); 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; const u8 *eap_key;
size_t eap_len; 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)) { if (sm == NULL || !eap_key_available(sm->eap)) {
wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
return -1; 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"); wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData");
return -1; return -1;
} }
#ifdef CONFIG_EAP_PROXY
key_fetched:
#endif /* CONFIG_EAP_PROXY */
if (len > eap_len) { if (len > eap_len) {
wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not " wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not "
"available (len=%lu)", "available (len=%lu)",
@ -1889,6 +1970,14 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
return NULL; 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 */ /* Initialize EAPOL state machines */
sm->initialize = TRUE; sm->initialize = TRUE;
eapol_sm_step(sm); 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_sm_step_timeout, NULL, sm);
eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
eap_peer_sm_deinit(sm->eap); 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); os_free(sm->last_rx_key);
wpabuf_free(sm->eapReqData); wpabuf_free(sm->eapReqData);
os_free(sm->ctx); os_free(sm->ctx);

View file

@ -1473,6 +1473,12 @@ ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB) LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
endif endif
LOCAL_SHARED_LIBRARIES := libc libcutils 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) ifeq ($(CONFIG_TLS), openssl)
LOCAL_SHARED_LIBRARIES += libcrypto libssl LOCAL_SHARED_LIBRARIES += libcrypto libssl
endif endif

View file

@ -482,6 +482,13 @@ CONFIG_EAP_SIM_COMMON=y
NEED_AES_CBC=y NEED_AES_CBC=y
endif 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 ifdef CONFIG_EAP_AKA_PRIME
# EAP-AKA' # EAP-AKA'
ifeq ($(CONFIG_EAP_AKA_PRIME), dyn) ifeq ($(CONFIG_EAP_AKA_PRIME), dyn)

View file

@ -498,3 +498,5 @@ CONFIG_NO_ROAMING=y
# Enable P2P # Enable P2P
CONFIG_P2P=y CONFIG_P2P=y
CONFIG_AP=y CONFIG_AP=y
include $(wildcard $(LOCAL_PATH)/android_config_*.inc)