aboutsummaryrefslogtreecommitdiffstats
path: root/src/eap_server/eap_sim.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2007-12-21 04:38:58 (GMT)
committerJouni Malinen <j@w1.fi>2007-12-21 04:38:58 (GMT)
commite64253704cea60133925a5291e792fd76c47e89b (patch)
treefedd36079ea68fac38a6f231e7f7c7cdb989126b /src/eap_server/eap_sim.c
parent1ab01393cba793ec0a4c3e96953df1f0709bc2ca (diff)
downloadhostap-history-e64253704cea60133925a5291e792fd76c47e89b.zip
hostap-history-e64253704cea60133925a5291e792fd76c47e89b.tar.gz
hostap-history-e64253704cea60133925a5291e792fd76c47e89b.tar.bz2
Added support for protected result indication with AT_RESULT_IND for
EAP-SIM and EAP-AKA. This is disabled by default, but can be enabled in configuration file (hostapd: eap_sim_aka_result_ind=1 and wpa_supplicant: phase1="result_ind=1").
Diffstat (limited to 'src/eap_server/eap_sim.c')
-rw-r--r--src/eap_server/eap_sim.c93
1 files changed, 90 insertions, 3 deletions
diff --git a/src/eap_server/eap_sim.c b/src/eap_server/eap_sim.c
index 41ff7a2..bc67116 100644
--- a/src/eap_server/eap_sim.c
+++ b/src/eap_server/eap_sim.c
@@ -32,11 +32,15 @@ struct eap_sim_data {
u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN];
u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN];
int num_chal;
- enum { START, CHALLENGE, REAUTH, SUCCESS, FAILURE } state;
+ enum {
+ START, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE
+ } state;
char *next_pseudonym;
char *next_reauth_id;
u16 counter;
struct eap_sim_reauth *reauth;
+ u16 notification;
+ int use_result_ind;
};
@@ -53,6 +57,8 @@ static const char * eap_sim_state_txt(int state)
return "SUCCESS";
case FAILURE:
return "FAILURE";
+ case NOTIFICATION:
+ return "NOTIFICATION";
default:
return "Unknown?!";
}
@@ -200,6 +206,11 @@ static struct wpabuf * eap_sim_build_challenge(struct eap_sm *sm,
return NULL;
}
+ if (sm->eap_sim_aka_result_ind) {
+ wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
+ eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+ }
+
wpa_printf(MSG_DEBUG, " AT_MAC");
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
return eap_sim_msg_finish(msg, data->k_aut, data->nonce_mt,
@@ -233,12 +244,53 @@ static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm,
return NULL;
}
+ if (sm->eap_sim_aka_result_ind) {
+ wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
+ eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+ }
+
wpa_printf(MSG_DEBUG, " AT_MAC");
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
}
+static struct wpabuf * eap_sim_build_notification(struct eap_sm *sm,
+ struct eap_sim_data *data,
+ u8 id)
+{
+ struct eap_sim_msg *msg;
+
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Notification");
+ msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
+ EAP_SIM_SUBTYPE_NOTIFICATION);
+ wpa_printf(MSG_DEBUG, " AT_NOTIFICATION");
+ eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification,
+ NULL, 0);
+ if (data->use_result_ind) {
+ wpa_printf(MSG_DEBUG, " AT_IV");
+ wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
+ eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
+ EAP_SIM_AT_ENCR_DATA);
+ wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)", data->counter);
+ eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, NULL,
+ 0);
+
+ if (eap_sim_msg_add_encr_end(msg, data->k_encr,
+ EAP_SIM_AT_PADDING)) {
+ wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
+ "AT_ENCR_DATA");
+ eap_sim_msg_free(msg);
+ return NULL;
+ }
+
+ wpa_printf(MSG_DEBUG, " AT_MAC");
+ eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
+ }
+ return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
static struct wpabuf * eap_sim_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
struct eap_sim_data *data = priv;
@@ -250,6 +302,8 @@ static struct wpabuf * eap_sim_buildReq(struct eap_sm *sm, void *priv, u8 id)
return eap_sim_build_challenge(sm, data, id);
case REAUTH:
return eap_sim_build_reauth(sm, data, id);
+ case NOTIFICATION:
+ return eap_sim_build_notification(sm, data, id);
default:
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "
"buildReq", data->state);
@@ -299,6 +353,13 @@ static Boolean eap_sim_check(struct eap_sm *sm, void *priv,
return TRUE;
}
break;
+ case NOTIFICATION:
+ if (subtype != EAP_SIM_SUBTYPE_NOTIFICATION) {
+ wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
+ "subtype %d", subtype);
+ return TRUE;
+ }
+ break;
default:
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected state (%d) for "
"processing a response", data->state);
@@ -448,7 +509,12 @@ static void eap_sim_process_challenge(struct eap_sm *sm,
wpa_printf(MSG_DEBUG, "EAP-SIM: Challenge response includes the "
"correct AT_MAC");
- eap_sim_state(data, SUCCESS);
+ if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+ data->use_result_ind = 1;
+ data->notification = EAP_SIM_SUCCESS;
+ eap_sim_state(data, NOTIFICATION);
+ } else
+ eap_sim_state(data, SUCCESS);
identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,
sm->identity_len, &identity_len);
@@ -517,7 +583,12 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes "
"the correct AT_MAC");
- eap_sim_state(data, SUCCESS);
+ if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+ data->use_result_ind = 1;
+ data->notification = EAP_SIM_SUCCESS;
+ eap_sim_state(data, NOTIFICATION);
+ } else
+ eap_sim_state(data, SUCCESS);
if (data->reauth) {
identity = data->reauth->identity;
@@ -570,6 +641,19 @@ static void eap_sim_process_client_error(struct eap_sm *sm,
}
+static void eap_sim_process_notification(struct eap_sm *sm,
+ struct eap_sim_data *data,
+ struct wpabuf *respData,
+ struct eap_sim_attrs *attr)
+{
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Client replied to notification");
+ if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)
+ eap_sim_state(data, SUCCESS);
+ else
+ eap_sim_state(data, FAILURE);
+}
+
+
static void eap_sim_process(struct eap_sm *sm, void *priv,
struct wpabuf *respData)
{
@@ -608,6 +692,9 @@ static void eap_sim_process(struct eap_sm *sm, void *priv,
case REAUTH:
eap_sim_process_reauth(sm, data, respData, &attr);
break;
+ case NOTIFICATION:
+ eap_sim_process_notification(sm, data, respData, &attr);
+ break;
default:
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "
"process", data->state);