From ec6acdbb6be9d448812afbf06cc207da7643ae16 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 21 Sep 2023 11:02:38 +0300 Subject: [PATCH] EAP-SIM/AKA server: Configurable limit to fast re-authentication Allow the EAP-SIM/AKA server to be configured to use a smaller limit for the number of times fast re-authentication can be used before falling back to running full authentication. This is particularly useful for EAP peer testing to cover cases when falling back from fast re-authentication to full authentication in various different cases. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 5 +++++ src/ap/ap_config.c | 1 + src/ap/ap_config.h | 1 + src/ap/authsrv.c | 2 ++ src/eap_server/eap.h | 4 ++++ src/eap_server/eap_server_aka.c | 24 +++++++++++++++++++++++- src/eap_server/eap_server_sim.c | 25 ++++++++++++++++++++++++- 8 files changed, 62 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 6c6cc69c41..4f3050841f 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2603,6 +2603,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "imsi_privacy_key") == 0) { os_free(bss->imsi_privacy_key); bss->imsi_privacy_key = os_strdup(pos); + } else if (os_strcmp(buf, "eap_sim_aka_fast_reauth_limit") == 0) { + bss->eap_sim_aka_fast_reauth_limit = atoi(pos); #endif /* EAP_SERVER_SIM */ #ifdef EAP_SERVER_TNC } else if (os_strcmp(buf, "tnc") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index b8d27112be..f02cd9274b 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1479,6 +1479,11 @@ eap_server=0 # permanent identity when using EAP-SIM/AKA/AKA'. #imsi_privacy_key=imsi-privacy-key.pem +# EAP-SIM and EAP-AKA fast re-authentication limit +# Maximum number of fast re-authentications allowed after each full +# authentication. +#eap_sim_aka_fast_reauth_limit=1000 + # Trusted Network Connect (TNC) # If enabled, TNC validation will be required before the peer is allowed to # connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 298216a474..2c66217e8d 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -90,6 +90,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss) bss->radius_server_auth_port = 1812; bss->eap_sim_db_timeout = 1; bss->eap_sim_id = 3; + bss->eap_sim_aka_fast_reauth_limit = 1000; bss->ap_max_inactivity = AP_MAX_INACTIVITY; bss->eapol_version = EAPOL_VERSION; diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8b3700be4d..5699a6be1e 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -448,6 +448,7 @@ struct hostapd_bss_config { int eap_sim_aka_result_ind; int eap_sim_id; char *imsi_privacy_key; + int eap_sim_aka_fast_reauth_limit; int tnc; int fragment_size; u16 pwd_group; diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c index cc1d722dad..1488dccc3d 100644 --- a/src/ap/authsrv.c +++ b/src/ap/authsrv.c @@ -224,6 +224,8 @@ static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd) cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind; cfg->eap_sim_id = hapd->conf->eap_sim_id; cfg->imsi_privacy_key = hapd->imsi_privacy_key; + cfg->eap_sim_aka_fast_reauth_limit = + hapd->conf->eap_sim_aka_fast_reauth_limit; cfg->tnc = hapd->conf->tnc; cfg->wps = hapd->wps; cfg->fragment_size = hapd->conf->fragment_size; diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h index 3696e1d27c..d965a25c40 100644 --- a/src/eap_server/eap.h +++ b/src/eap_server/eap.h @@ -220,6 +220,10 @@ struct eap_config { int eap_sim_aka_result_ind; int eap_sim_id; + /* Maximum number of fast re-authentications allowed after each full + * EAP-SIM/AKA authentication. */ + int eap_sim_aka_fast_reauth_limit; + /** * tnc - Trusted Network Connect (TNC) * diff --git a/src/eap_server/eap_server_aka.c b/src/eap_server/eap_server_aka.c index c154d7f6e8..880ffa3d68 100644 --- a/src/eap_server/eap_server_aka.c +++ b/src/eap_server/eap_server_aka.c @@ -110,7 +110,29 @@ static int eap_aka_check_identity_reauth(struct eap_sm *sm, return 0; } - wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast re-authentication"); + if (data->reauth->counter > sm->cfg->eap_sim_aka_fast_reauth_limit) { + wpa_printf(MSG_DEBUG, + "EAP-AKA: Too many fast re-authentication attemps - fall back to full authentication"); + if (sm->cfg->eap_sim_id & 0x04) { + wpa_printf(MSG_DEBUG, + "EAP-AKA: Permanent identity recognized - skip AKA-Identity exchange"); + os_strlcpy(data->permanent, data->reauth->permanent, + sizeof(data->permanent)); + os_strlcpy(sm->sim_aka_permanent, + data->reauth->permanent, + sizeof(sm->sim_aka_permanent)); + eap_sim_db_remove_reauth(sm->cfg->eap_sim_db_priv, + data->reauth); + data->reauth = NULL; + eap_aka_fullauth(sm, data); + return 1; + } + return 0; + } + + wpa_printf(MSG_DEBUG, + "EAP-AKA: Using fast re-authentication (counter=%d)", + data->reauth->counter); os_strlcpy(data->permanent, data->reauth->permanent, sizeof(data->permanent)); data->counter = data->reauth->counter; diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c index 51faca95f1..e418c076e2 100644 --- a/src/eap_server/eap_server_sim.c +++ b/src/eap_server/eap_server_sim.c @@ -514,7 +514,30 @@ skip_id_attr: /* Remain in START state for another round */ return; } - wpa_printf(MSG_DEBUG, "EAP-SIM: Using fast re-authentication"); + + if (data->reauth->counter > + sm->cfg->eap_sim_aka_fast_reauth_limit && + (sm->cfg->eap_sim_id & 0x04)) { + wpa_printf(MSG_DEBUG, + "EAP-SIM: Too many fast re-authentication attemps - fall back to full authentication"); + wpa_printf(MSG_DEBUG, + "EAP-SIM: Permanent identity recognized - skip new Identity query"); + os_strlcpy(data->permanent, + data->reauth->permanent, + sizeof(data->permanent)); + os_strlcpy(sm->sim_aka_permanent, + data->reauth->permanent, + sizeof(sm->sim_aka_permanent)); + eap_sim_db_remove_reauth( + sm->cfg->eap_sim_db_priv, + data->reauth); + data->reauth = NULL; + goto skip_id_update; + } + + wpa_printf(MSG_DEBUG, + "EAP-SIM: Using fast re-authentication (counter=%d)", + data->reauth->counter); os_strlcpy(data->permanent, data->reauth->permanent, sizeof(data->permanent)); data->counter = data->reauth->counter; -- 2.47.2