/** * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry * @priv: Private data pointer from eap_sim_db_init() * @identity: Identity of the user (may be permanent identity, pseudonym, or * reauth_id) * @identity_len: Length of identity * @len: Buffer for length of the returned permanent identity * Returns: Pointer to the re-auth entry, or %NULL if not found */ struct eap_sim_reauth * eap_sim_db_get_reauth_entry(void *priv, const u8 *identity, size_t identity_len) { struct eap_sim_db_data *data = priv; struct eap_sim_reauth *r; if (identity == NULL) return NULL; r = eap_sim_db_get_reauth(data, identity, identity_len); if (r == NULL) r = eap_sim_db_get_reauth_id(data, identity, identity_len); return r; }
/** * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry * @priv: Private data pointer from eap_sim_db_init() * @identity: Identity of the user (may be permanent identity or pseudonym) * @identity_len: Length of identity * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not * free it. * @mk: 16-byte MK from the previous full authentication * Returns: 0 on success, -1 on failure * * This function adds a new re-authentication entry for an EAP-SIM user. * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed * anymore. */ int eap_sim_db_add_reauth(void *priv, const u8 *identity, size_t identity_len, char *reauth_id, u16 counter, const u8 *mk) { struct eap_sim_db_data *data = priv; struct eap_sim_reauth *r; wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity", identity, identity_len); wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id); r = eap_sim_db_get_reauth(data, identity, identity_len); if (r == NULL) r = eap_sim_db_get_reauth_id(data, identity, identity_len); if (r) { wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " "reauth_id: %s", r->reauth_id); VM_FREE(r->reauth_id); r->reauth_id = reauth_id; } else { r = wpa_zalloc(sizeof(*r)); if (r == NULL) { VM_FREE(reauth_id); return -1; } r->next = data->reauths; r->identity = VM_MALLOC(identity_len); if (r->identity == NULL) { VM_FREE(r); VM_FREE(reauth_id); return -1; } memcpy(r->identity, identity, identity_len); r->identity_len = identity_len; r->reauth_id = reauth_id; data->reauths = r; wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry"); } r->counter = counter; memcpy(r->mk, mk, EAP_SIM_MK_LEN); return 0; }
static struct eap_sim_reauth * eap_sim_db_add_reauth_data(struct eap_sim_db_data *data, const u8 *identity, size_t identity_len, char *reauth_id, u16 counter) { struct eap_sim_reauth *r; wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity", identity, identity_len); wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id); r = eap_sim_db_get_reauth(data, identity, identity_len); if (r == NULL) r = eap_sim_db_get_reauth_id(data, identity, identity_len); if (r) { wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " "reauth_id: %s", r->reauth_id); os_free(r->reauth_id); r->reauth_id = reauth_id; } else { r = os_zalloc(sizeof(*r)); if (r == NULL) { os_free(reauth_id); return NULL; } r->next = data->reauths; r->identity = os_malloc(identity_len); if (r->identity == NULL) { os_free(r); os_free(reauth_id); return NULL; } os_memcpy(r->identity, identity, identity_len); r->identity_len = identity_len; r->reauth_id = reauth_id; data->reauths = r; wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry"); } r->counter = counter; return r; }
/** * eap_sim_db_identity_known - Verify whether the given identity is known * @priv: Private data pointer from eap_sim_db_init() * @identity: User name identity * @identity_len: Length of identity in bytes * Returns: 0 if the user is found or -1 on failure * * In most cases, the user name is ['0','1'] | IMSI, i.e., 1 followed by the * IMSI in ASCII format, ['2','3'] | pseudonym, or ['4','5'] | reauth_id. */ int eap_sim_db_identity_known(void *priv, const u8 *identity, size_t identity_len) { struct eap_sim_db_data *data = priv; if (identity == NULL || identity_len < 2) return -1; if (identity[0] == EAP_SIM_PSEUDONYM_PREFIX || identity[0] == EAP_AKA_PSEUDONYM_PREFIX) { struct eap_sim_pseudonym *p = eap_sim_db_get_pseudonym(data, identity, identity_len); return p ? 0 : -1; } if (identity[0] == EAP_SIM_REAUTH_ID_PREFIX || identity[0] == EAP_AKA_REAUTH_ID_PREFIX) { struct eap_sim_reauth *r = eap_sim_db_get_reauth(data, identity, identity_len); return r ? 0 : -1; } if (identity[0] != EAP_SIM_PERMANENT_PREFIX && identity[0] != EAP_AKA_PERMANENT_PREFIX) { /* Unknown identity prefix */ return -1; } /* TODO: Should consider asking HLR/AuC gateway whether this permanent * identity is known. If it is, EAP-SIM/AKA can skip identity request. * In case of EAP-AKA, this would reduce number of needed round-trips. * Ideally, this would be done with one wait, i.e., just request * authentication data and store it for the next use. This would then * need to use similar pending-request functionality as the normal * request for authentication data at later phase. */ return -1; }