ERP: External control of ERP key information
This allows ERP keys to be managed by external entities, e.g., when offloading FILS shared key authentication to a driver. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
42e69bda2a
commit
15def72fab
4 changed files with 140 additions and 2 deletions
|
@ -371,9 +371,8 @@ nak:
|
|||
|
||||
#ifdef CONFIG_ERP
|
||||
|
||||
static char * eap_home_realm(struct eap_sm *sm)
|
||||
static char * eap_get_realm(struct eap_sm *sm, struct eap_peer_config *config)
|
||||
{
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
char *realm;
|
||||
size_t i, realm_len;
|
||||
|
||||
|
@ -417,6 +416,12 @@ static char * eap_home_realm(struct eap_sm *sm)
|
|||
}
|
||||
|
||||
|
||||
static char * eap_home_realm(struct eap_sm *sm)
|
||||
{
|
||||
return eap_get_realm(sm, eap_get_config(sm));
|
||||
}
|
||||
|
||||
|
||||
static struct eap_erp_key *
|
||||
eap_erp_get_key(struct eap_sm *sm, const char *realm)
|
||||
{
|
||||
|
@ -469,6 +474,84 @@ static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 next_seq_num)
|
||||
{
|
||||
struct eap_erp_key *erp;
|
||||
char *home_realm;
|
||||
|
||||
home_realm = eap_home_realm(sm);
|
||||
if (!home_realm || os_strlen(home_realm) == 0) {
|
||||
os_free(home_realm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
erp = eap_erp_get_key(sm, home_realm);
|
||||
if (!erp) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP: Failed to find ERP key for realm: %s",
|
||||
home_realm);
|
||||
os_free(home_realm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((u32) next_seq_num < erp->next_seq) {
|
||||
/* Sequence number has wrapped around, clear this ERP
|
||||
* info and do a full auth next time.
|
||||
*/
|
||||
eap_peer_erp_free_key(erp);
|
||||
} else {
|
||||
erp->next_seq = (u32) next_seq_num;
|
||||
}
|
||||
|
||||
os_free(home_realm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
|
||||
const u8 **username, size_t *username_len,
|
||||
const u8 **realm, size_t *realm_len,
|
||||
u16 *erp_next_seq_num, const u8 **rrk,
|
||||
size_t *rrk_len)
|
||||
{
|
||||
struct eap_erp_key *erp;
|
||||
char *home_realm;
|
||||
char *pos;
|
||||
|
||||
home_realm = eap_get_realm(sm, config);
|
||||
if (!home_realm || os_strlen(home_realm) == 0) {
|
||||
os_free(home_realm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
erp = eap_erp_get_key(sm, home_realm);
|
||||
os_free(home_realm);
|
||||
if (!erp)
|
||||
return -1;
|
||||
|
||||
if (erp->next_seq >= 65536)
|
||||
return -1; /* SEQ has range of 0..65535 */
|
||||
|
||||
pos = os_strchr(erp->keyname_nai, '@');
|
||||
*username_len = pos - erp->keyname_nai;
|
||||
*username = (u8 *) erp->keyname_nai;
|
||||
|
||||
pos++;
|
||||
*realm_len = os_strlen(pos);
|
||||
*realm = (u8 *) pos;
|
||||
|
||||
*erp_next_seq_num = (u16) erp->next_seq;
|
||||
|
||||
*rrk_len = erp->rRK_len;
|
||||
*rrk = erp->rRK;
|
||||
|
||||
if (*username_len == 0 || *realm_len == 0 || *rrk_len == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ERP */
|
||||
|
||||
|
||||
|
|
|
@ -358,6 +358,11 @@ int eap_peer_was_failure_expected(struct eap_sm *sm);
|
|||
void eap_peer_erp_free_keys(struct eap_sm *sm);
|
||||
struct wpabuf * eap_peer_build_erp_reauth_start(struct eap_sm *sm, u8 eap_id);
|
||||
void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, size_t len);
|
||||
int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
|
||||
const u8 **username, size_t *username_len,
|
||||
const u8 **realm, size_t *realm_len, u16 *erp_seq_num,
|
||||
const u8 **rrk, size_t *rrk_len);
|
||||
int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 seq_num);
|
||||
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
|
|
|
@ -2195,3 +2195,33 @@ void eapol_sm_process_erp_finish(struct eapol_sm *sm, const u8 *buf,
|
|||
eap_peer_finish(sm->eap, (const struct eap_hdr *) buf, len);
|
||||
#endif /* CONFIG_ERP */
|
||||
}
|
||||
|
||||
|
||||
int eapol_sm_update_erp_next_seq_num(struct eapol_sm *sm, u16 next_seq_num)
|
||||
{
|
||||
#ifdef CONFIG_ERP
|
||||
if (!sm)
|
||||
return -1;
|
||||
return eap_peer_update_erp_next_seq_num(sm->eap, next_seq_num);
|
||||
#else /* CONFIG_ERP */
|
||||
return -1;
|
||||
#endif /* CONFIG_ERP */
|
||||
}
|
||||
|
||||
|
||||
int eapol_sm_get_erp_info(struct eapol_sm *sm, struct eap_peer_config *config,
|
||||
const u8 **username, size_t *username_len,
|
||||
const u8 **realm, size_t *realm_len,
|
||||
u16 *erp_next_seq_num, const u8 **rrk,
|
||||
size_t *rrk_len)
|
||||
{
|
||||
#ifdef CONFIG_ERP
|
||||
if (!sm)
|
||||
return -1;
|
||||
return eap_peer_get_erp_info(sm->eap, config, username, username_len,
|
||||
realm, realm_len, erp_next_seq_num, rrk,
|
||||
rrk_len);
|
||||
#else /* CONFIG_ERP */
|
||||
return -1;
|
||||
#endif /* CONFIG_ERP */
|
||||
}
|
||||
|
|
|
@ -340,6 +340,13 @@ struct wpabuf * eapol_sm_build_erp_reauth_start(struct eapol_sm *sm);
|
|||
void eapol_sm_process_erp_finish(struct eapol_sm *sm, const u8 *buf,
|
||||
size_t len);
|
||||
int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len);
|
||||
int eapol_sm_update_erp_next_seq_num(struct eapol_sm *sm, u16 next_seq_num);
|
||||
int eapol_sm_get_erp_info(struct eapol_sm *sm, struct eap_peer_config *config,
|
||||
const u8 **username, size_t *username_len,
|
||||
const u8 **realm, size_t *realm_len,
|
||||
u16 *erp_next_seq_num, const u8 **rrk,
|
||||
size_t *rrk_len);
|
||||
|
||||
#else /* IEEE8021X_EAPOL */
|
||||
static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
|
||||
{
|
||||
|
@ -458,6 +465,19 @@ static inline void eapol_sm_process_erp_finish(struct eapol_sm *sm,
|
|||
const u8 *buf, size_t len)
|
||||
{
|
||||
}
|
||||
static inline int eapol_sm_update_erp_next_seq_num(struct eapol_sm *sm,
|
||||
u16 next_seq_num)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int
|
||||
eapol_sm_get_erp_info(struct eapol_sm *sm, struct eap_peer_config *config,
|
||||
const u8 **username, size_t *username_len,
|
||||
const u8 **realm, size_t *realm_len,
|
||||
u16 *erp_next_seq_num, const u8 **rrk, size_t *rrk_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
#endif /* EAPOL_SUPP_SM_H */
|
||||
|
|
Loading…
Reference in a new issue