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:
parent
83e7aedf72
commit
45f4a97a3a
5 changed files with 155 additions and 0 deletions
48
src/eap_peer/eap_proxy.h
Normal file
48
src/eap_peer/eap_proxy.h
Normal 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 */
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue