EAP-AKA': Derive keys using the new KDF (PRF')
This commit is contained in:
parent
f07688e37d
commit
9881795e2c
6 changed files with 320 additions and 51 deletions
|
@ -234,6 +234,134 @@ void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
|
||||||
|
|
||||||
|
|
||||||
#ifdef EAP_AKA_PRIME
|
#ifdef EAP_AKA_PRIME
|
||||||
|
static void prf_prime(const u8 *k, const char *seed1,
|
||||||
|
const u8 *seed2, size_t seed2_len,
|
||||||
|
const u8 *seed3, size_t seed3_len,
|
||||||
|
u8 *res, size_t res_len)
|
||||||
|
{
|
||||||
|
const u8 *addr[5];
|
||||||
|
size_t len[5];
|
||||||
|
u8 hash[SHA256_MAC_LEN];
|
||||||
|
u8 iter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRF'(K,S) = T1 | T2 | T3 | T4 | ...
|
||||||
|
* T1 = HMAC-SHA-256 (K, S | 0x01)
|
||||||
|
* T2 = HMAC-SHA-256 (K, T1 | S | 0x02)
|
||||||
|
* T3 = HMAC-SHA-256 (K, T2 | S | 0x03)
|
||||||
|
* T4 = HMAC-SHA-256 (K, T3 | S | 0x04)
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
addr[0] = hash;
|
||||||
|
len[0] = 0;
|
||||||
|
addr[1] = (const u8 *) seed1;
|
||||||
|
len[1] = os_strlen(seed1);
|
||||||
|
addr[2] = seed2;
|
||||||
|
len[2] = seed2_len;
|
||||||
|
addr[3] = seed3;
|
||||||
|
len[3] = seed3_len;
|
||||||
|
addr[4] = &iter;
|
||||||
|
len[4] = 1;
|
||||||
|
|
||||||
|
iter = 0;
|
||||||
|
while (res_len) {
|
||||||
|
size_t hlen;
|
||||||
|
iter++;
|
||||||
|
hmac_sha256_vector(k, 32, 5, addr, len, hash);
|
||||||
|
len[0] = SHA256_MAC_LEN;
|
||||||
|
hlen = res_len > SHA256_MAC_LEN ? SHA256_MAC_LEN : res_len;
|
||||||
|
os_memcpy(res, hash, hlen);
|
||||||
|
res += hlen;
|
||||||
|
res_len -= hlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
|
||||||
|
const u8 *ik, const u8 *ck, u8 *k_encr,
|
||||||
|
u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk)
|
||||||
|
{
|
||||||
|
u8 key[EAP_AKA_IK_LEN + EAP_AKA_CK_LEN];
|
||||||
|
u8 keys[EAP_SIM_K_ENCR_LEN + EAP_AKA_PRIME_K_AUT_LEN +
|
||||||
|
EAP_AKA_PRIME_K_RE_LEN + EAP_MSK_LEN + EAP_EMSK_LEN];
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MK = PRF'(IK'|CK',"EAP-AKA'"|Identity)
|
||||||
|
* K_encr = MK[0..127]
|
||||||
|
* K_aut = MK[128..383]
|
||||||
|
* K_re = MK[384..639]
|
||||||
|
* MSK = MK[640..1151]
|
||||||
|
* EMSK = MK[1152..1663]
|
||||||
|
*/
|
||||||
|
|
||||||
|
os_memcpy(key, ik, EAP_AKA_IK_LEN);
|
||||||
|
os_memcpy(key + EAP_AKA_IK_LEN, ck, EAP_AKA_CK_LEN);
|
||||||
|
|
||||||
|
prf_prime(key, "EAP-AKA'", identity, identity_len, NULL, 0,
|
||||||
|
keys, sizeof(keys));
|
||||||
|
|
||||||
|
pos = keys;
|
||||||
|
os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_encr",
|
||||||
|
k_encr, EAP_SIM_K_ENCR_LEN);
|
||||||
|
pos += EAP_SIM_K_ENCR_LEN;
|
||||||
|
|
||||||
|
os_memcpy(k_aut, pos, EAP_AKA_PRIME_K_AUT_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_aut",
|
||||||
|
k_aut, EAP_AKA_PRIME_K_AUT_LEN);
|
||||||
|
pos += EAP_AKA_PRIME_K_AUT_LEN;
|
||||||
|
|
||||||
|
os_memcpy(k_re, pos, EAP_AKA_PRIME_K_RE_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_re",
|
||||||
|
k_re, EAP_AKA_PRIME_K_RE_LEN);
|
||||||
|
pos += EAP_AKA_PRIME_K_RE_LEN;
|
||||||
|
|
||||||
|
os_memcpy(msk, pos, EAP_MSK_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
|
||||||
|
pos += EAP_MSK_LEN;
|
||||||
|
|
||||||
|
os_memcpy(emsk, pos, EAP_EMSK_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
|
||||||
|
const u8 *identity, size_t identity_len,
|
||||||
|
const u8 *nonce_s, u8 *msk, u8 *emsk)
|
||||||
|
{
|
||||||
|
u8 seed3[2 + EAP_SIM_NONCE_S_LEN];
|
||||||
|
u8 keys[EAP_MSK_LEN + EAP_EMSK_LEN];
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MK = PRF'(K_re,"EAP-AKA' re-auth"|Identity|counter|NONCE_S)
|
||||||
|
* MSK = MK[0..511]
|
||||||
|
* EMSK = MK[512..1023]
|
||||||
|
*/
|
||||||
|
|
||||||
|
WPA_PUT_BE16(seed3, counter);
|
||||||
|
os_memcpy(seed3 + 2, nonce_s, EAP_SIM_NONCE_S_LEN);
|
||||||
|
|
||||||
|
prf_prime(k_re, "EAP-AKA' re-auth", identity, identity_len,
|
||||||
|
seed3, sizeof(seed3),
|
||||||
|
keys, sizeof(keys));
|
||||||
|
|
||||||
|
pos = keys;
|
||||||
|
os_memcpy(msk, pos, EAP_MSK_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
|
||||||
|
pos += EAP_MSK_LEN;
|
||||||
|
|
||||||
|
os_memcpy(emsk, pos, EAP_EMSK_LEN);
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
|
||||||
|
|
||||||
|
os_memset(keys, 0, sizeof(keys));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
|
int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
|
||||||
const u8 *mac, const u8 *extra, size_t extra_len)
|
const u8 *mac, const u8 *extra, size_t extra_len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
|
|
||||||
#define EAP_AKA_PRIME_K_AUT_LEN 32
|
#define EAP_AKA_PRIME_K_AUT_LEN 32
|
||||||
#define EAP_AKA_PRIME_CHECKCODE_LEN 32
|
#define EAP_AKA_PRIME_CHECKCODE_LEN 32
|
||||||
|
#define EAP_AKA_PRIME_K_RE_LEN 32
|
||||||
|
|
||||||
struct wpabuf;
|
struct wpabuf;
|
||||||
|
|
||||||
|
@ -92,6 +93,13 @@ int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
|
||||||
const u8 *mac, const u8 *extra, size_t extra_len);
|
const u8 *mac, const u8 *extra, size_t extra_len);
|
||||||
void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
|
void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
|
||||||
const u8 *extra, size_t extra_len);
|
const u8 *extra, size_t extra_len);
|
||||||
|
|
||||||
|
void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
|
||||||
|
const u8 *ik, const u8 *ck, u8 *k_encr,
|
||||||
|
u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk);
|
||||||
|
int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
|
||||||
|
const u8 *identity, size_t identity_len,
|
||||||
|
const u8 *nonce_s, u8 *msk, u8 *emsk);
|
||||||
int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
|
int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
|
||||||
const u8 *mac, const u8 *extra,
|
const u8 *mac, const u8 *extra,
|
||||||
size_t extra_len);
|
size_t extra_len);
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct eap_aka_data {
|
||||||
u8 mk[EAP_SIM_MK_LEN];
|
u8 mk[EAP_SIM_MK_LEN];
|
||||||
u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
|
u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
|
||||||
u8 k_encr[EAP_SIM_K_ENCR_LEN];
|
u8 k_encr[EAP_SIM_K_ENCR_LEN];
|
||||||
|
u8 k_re[EAP_AKA_PRIME_K_RE_LEN];
|
||||||
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
||||||
u8 emsk[EAP_EMSK_LEN];
|
u8 emsk[EAP_EMSK_LEN];
|
||||||
u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
|
u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
|
||||||
|
@ -701,10 +702,16 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
identity = eap_get_config_identity(sm, &identity_len);
|
identity = eap_get_config_identity(sm, &identity_len);
|
||||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
|
wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
|
||||||
"derivation", identity, identity_len);
|
"derivation", identity, identity_len);
|
||||||
eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
data->mk);
|
eap_aka_prime_derive_keys(identity, identity_len, data->ik,
|
||||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
data->ck, data->k_encr, data->k_aut,
|
||||||
data->emsk);
|
data->k_re, data->msk, data->emsk);
|
||||||
|
} else {
|
||||||
|
eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
|
||||||
|
data->mk);
|
||||||
|
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
}
|
||||||
if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
|
if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
|
||||||
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
|
||||||
"used invalid AT_MAC");
|
"used invalid AT_MAC");
|
||||||
|
@ -910,10 +917,6 @@ static struct wpabuf * eap_aka_process_reauthentication(
|
||||||
"(%d <= %d)", eattr.counter, data->counter);
|
"(%d <= %d)", eattr.counter, data->counter);
|
||||||
data->counter_too_small = eattr.counter;
|
data->counter_too_small = eattr.counter;
|
||||||
|
|
||||||
eap_sim_derive_keys_reauth(eattr.counter, data->reauth_id,
|
|
||||||
data->reauth_id_len, eattr.nonce_s,
|
|
||||||
data->mk, NULL, NULL);
|
|
||||||
|
|
||||||
/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
|
/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
|
||||||
* reauth_id must not be used to start a new reauthentication.
|
* reauth_id must not be used to start a new reauthentication.
|
||||||
* However, since it was used in the last EAP-Response-Identity
|
* However, since it was used in the last EAP-Response-Identity
|
||||||
|
@ -936,10 +939,18 @@ static struct wpabuf * eap_aka_process_reauthentication(
|
||||||
wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
|
wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
|
||||||
data->nonce_s, EAP_SIM_NONCE_S_LEN);
|
data->nonce_s, EAP_SIM_NONCE_S_LEN);
|
||||||
|
|
||||||
eap_sim_derive_keys_reauth(data->counter,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
data->reauth_id, data->reauth_id_len,
|
eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
|
||||||
data->nonce_s, data->mk, data->msk,
|
data->reauth_id,
|
||||||
data->emsk);
|
data->reauth_id_len,
|
||||||
|
data->nonce_s,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
} else {
|
||||||
|
eap_sim_derive_keys_reauth(data->counter, data->reauth_id,
|
||||||
|
data->reauth_id_len,
|
||||||
|
data->nonce_s, data->mk,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
}
|
||||||
eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
|
eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
|
||||||
eap_aka_learn_ids(data, &eattr);
|
eap_aka_learn_ids(data, &eattr);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct eap_aka_data {
|
||||||
u8 nonce_s[EAP_SIM_NONCE_S_LEN];
|
u8 nonce_s[EAP_SIM_NONCE_S_LEN];
|
||||||
u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
|
u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
|
||||||
u8 k_encr[EAP_SIM_K_ENCR_LEN];
|
u8 k_encr[EAP_SIM_K_ENCR_LEN];
|
||||||
|
u8 k_re[EAP_AKA_PRIME_K_RE_LEN];
|
||||||
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
u8 msk[EAP_SIM_KEYING_DATA_LEN];
|
||||||
u8 emsk[EAP_EMSK_LEN];
|
u8 emsk[EAP_EMSK_LEN];
|
||||||
u8 rand[EAP_AKA_RAND_LEN];
|
u8 rand[EAP_AKA_RAND_LEN];
|
||||||
|
@ -365,11 +366,19 @@ static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm,
|
||||||
wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S",
|
wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S",
|
||||||
data->nonce_s, EAP_SIM_NONCE_S_LEN);
|
data->nonce_s, EAP_SIM_NONCE_S_LEN);
|
||||||
|
|
||||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
data->emsk);
|
eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
|
||||||
eap_sim_derive_keys_reauth(data->counter, sm->identity,
|
sm->identity,
|
||||||
sm->identity_len, data->nonce_s, data->mk,
|
sm->identity_len,
|
||||||
data->msk, data->emsk);
|
data->nonce_s,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
} else {
|
||||||
|
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
eap_sim_derive_keys_reauth(data->counter, sm->identity,
|
||||||
|
sm->identity_len, data->nonce_s,
|
||||||
|
data->mk, data->msk, data->emsk);
|
||||||
|
}
|
||||||
|
|
||||||
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
|
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
|
||||||
EAP_AKA_SUBTYPE_REAUTHENTICATION);
|
EAP_AKA_SUBTYPE_REAUTHENTICATION);
|
||||||
|
@ -545,14 +554,33 @@ static void eap_aka_determine_identity(struct eap_sm *sm,
|
||||||
data->reauth = eap_sim_db_get_reauth_entry(
|
data->reauth = eap_sim_db_get_reauth_entry(
|
||||||
sm->eap_sim_db_priv, sm->identity,
|
sm->eap_sim_db_priv, sm->identity,
|
||||||
sm->identity_len);
|
sm->identity_len);
|
||||||
|
if (data->reauth &&
|
||||||
|
data->reauth->aka_prime !=
|
||||||
|
(data->eap_method == EAP_TYPE_AKA_PRIME)) {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-AKA: Reauth data "
|
||||||
|
"was for different AKA version");
|
||||||
|
data->reauth = NULL;
|
||||||
|
}
|
||||||
if (data->reauth) {
|
if (data->reauth) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast "
|
wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast "
|
||||||
"re-authentication");
|
"re-authentication");
|
||||||
identity = data->reauth->identity;
|
identity = data->reauth->identity;
|
||||||
identity_len = data->reauth->identity_len;
|
identity_len = data->reauth->identity_len;
|
||||||
data->counter = data->reauth->counter;
|
data->counter = data->reauth->counter;
|
||||||
os_memcpy(data->mk, data->reauth->mk,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
EAP_SIM_MK_LEN);
|
os_memcpy(data->k_encr,
|
||||||
|
data->reauth->k_encr,
|
||||||
|
EAP_SIM_K_ENCR_LEN);
|
||||||
|
os_memcpy(data->k_aut,
|
||||||
|
data->reauth->k_aut,
|
||||||
|
EAP_AKA_PRIME_K_AUT_LEN);
|
||||||
|
os_memcpy(data->k_re,
|
||||||
|
data->reauth->k_re,
|
||||||
|
EAP_AKA_PRIME_K_RE_LEN);
|
||||||
|
} else {
|
||||||
|
os_memcpy(data->mk, data->reauth->mk,
|
||||||
|
EAP_SIM_MK_LEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,10 +646,16 @@ static void eap_aka_determine_identity(struct eap_sm *sm,
|
||||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",
|
wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",
|
||||||
sm->identity, identity_len);
|
sm->identity, identity_len);
|
||||||
|
|
||||||
eap_aka_derive_mk(sm->identity, identity_len, data->ik, data->ck,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
data->mk);
|
eap_aka_prime_derive_keys(identity, identity_len, data->ik,
|
||||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
data->ck, data->k_encr, data->k_aut,
|
||||||
data->emsk);
|
data->k_re, data->msk, data->emsk);
|
||||||
|
} else {
|
||||||
|
eap_aka_derive_mk(sm->identity, identity_len, data->ik,
|
||||||
|
data->ck, data->mk);
|
||||||
|
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
|
||||||
|
data->msk, data->emsk);
|
||||||
|
}
|
||||||
|
|
||||||
eap_aka_state(data, CHALLENGE);
|
eap_aka_state(data, CHALLENGE);
|
||||||
}
|
}
|
||||||
|
@ -741,10 +775,21 @@ static void eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
data->next_pseudonym = NULL;
|
data->next_pseudonym = NULL;
|
||||||
}
|
}
|
||||||
if (data->next_reauth_id) {
|
if (data->next_reauth_id) {
|
||||||
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
identity_len,
|
eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
|
||||||
data->next_reauth_id, data->counter + 1,
|
identity,
|
||||||
data->mk);
|
identity_len,
|
||||||
|
data->next_reauth_id,
|
||||||
|
data->counter + 1,
|
||||||
|
data->k_encr, data->k_aut,
|
||||||
|
data->k_re);
|
||||||
|
} else {
|
||||||
|
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
||||||
|
identity_len,
|
||||||
|
data->next_reauth_id,
|
||||||
|
data->counter + 1,
|
||||||
|
data->mk);
|
||||||
|
}
|
||||||
data->next_reauth_id = NULL;
|
data->next_reauth_id = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -867,9 +912,21 @@ static void eap_aka_process_reauth(struct eap_sm *sm,
|
||||||
data->next_pseudonym = NULL;
|
data->next_pseudonym = NULL;
|
||||||
}
|
}
|
||||||
if (data->next_reauth_id) {
|
if (data->next_reauth_id) {
|
||||||
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
|
||||||
identity_len, data->next_reauth_id,
|
eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
|
||||||
data->counter + 1, data->mk);
|
identity,
|
||||||
|
identity_len,
|
||||||
|
data->next_reauth_id,
|
||||||
|
data->counter + 1,
|
||||||
|
data->k_encr, data->k_aut,
|
||||||
|
data->k_re);
|
||||||
|
} else {
|
||||||
|
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
||||||
|
identity_len,
|
||||||
|
data->next_reauth_id,
|
||||||
|
data->counter + 1,
|
||||||
|
data->mk);
|
||||||
|
}
|
||||||
data->next_reauth_id = NULL;
|
data->next_reauth_id = NULL;
|
||||||
} else {
|
} else {
|
||||||
eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
|
eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
|
||||||
|
|
|
@ -942,27 +942,12 @@ int eap_sim_db_add_pseudonym(void *priv, const u8 *identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
static struct eap_sim_reauth *
|
||||||
* eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry
|
eap_sim_db_add_reauth_data(struct eap_sim_db_data *data, const u8 *identity,
|
||||||
* @priv: Private data pointer from eap_sim_db_init()
|
size_t identity_len, char *reauth_id, u16 counter)
|
||||||
* @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;
|
struct eap_sim_reauth *r;
|
||||||
|
|
||||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity",
|
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity",
|
||||||
identity, identity_len);
|
identity, identity_len);
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id);
|
wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id);
|
||||||
|
@ -980,7 +965,7 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
|
||||||
r = os_zalloc(sizeof(*r));
|
r = os_zalloc(sizeof(*r));
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
os_free(reauth_id);
|
os_free(reauth_id);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->next = data->reauths;
|
r->next = data->reauths;
|
||||||
|
@ -988,7 +973,7 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
|
||||||
if (r->identity == NULL) {
|
if (r->identity == NULL) {
|
||||||
os_free(r);
|
os_free(r);
|
||||||
os_free(reauth_id);
|
os_free(reauth_id);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
os_memcpy(r->identity, identity, identity_len);
|
os_memcpy(r->identity, identity, identity_len);
|
||||||
r->identity_len = identity_len;
|
r->identity_len = identity_len;
|
||||||
|
@ -998,12 +983,84 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
r->counter = counter;
|
r->counter = counter;
|
||||||
|
|
||||||
|
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 or %NULL
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
r = eap_sim_db_add_reauth_data(data, identity, identity_len, reauth_id,
|
||||||
|
counter);
|
||||||
|
if (r == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
os_memcpy(r->mk, mk, EAP_SIM_MK_LEN);
|
os_memcpy(r->mk, mk, EAP_SIM_MK_LEN);
|
||||||
|
r->aka_prime = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef EAP_AKA_PRIME
|
||||||
|
/**
|
||||||
|
* eap_sim_db_add_reauth_prime - EAP-AKA' 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.
|
||||||
|
* @k_re: 32-byte K_re from the previous full authentication or %NULL
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
* This function adds a new re-authentication entry for an EAP-AKA' user.
|
||||||
|
* EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
|
||||||
|
* anymore.
|
||||||
|
*/
|
||||||
|
int eap_sim_db_add_reauth_prime(void *priv, const u8 *identity,
|
||||||
|
size_t identity_len, char *reauth_id,
|
||||||
|
u16 counter, const u8 *k_encr, const u8 *k_aut,
|
||||||
|
const u8 *k_re)
|
||||||
|
{
|
||||||
|
struct eap_sim_db_data *data = priv;
|
||||||
|
struct eap_sim_reauth *r;
|
||||||
|
|
||||||
|
r = eap_sim_db_add_reauth_data(data, identity, identity_len, reauth_id,
|
||||||
|
counter);
|
||||||
|
if (r == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
r->aka_prime = 1;
|
||||||
|
os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN);
|
||||||
|
os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN);
|
||||||
|
os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* EAP_AKA_PRIME */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity
|
* eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity
|
||||||
* @priv: Private data pointer from eap_sim_db_init()
|
* @priv: Private data pointer from eap_sim_db_init()
|
||||||
|
|
|
@ -54,6 +54,10 @@ int eap_sim_db_add_pseudonym(void *priv, const u8 *identity,
|
||||||
int eap_sim_db_add_reauth(void *priv, const u8 *identity,
|
int eap_sim_db_add_reauth(void *priv, const u8 *identity,
|
||||||
size_t identity_len, char *reauth_id, u16 counter,
|
size_t identity_len, char *reauth_id, u16 counter,
|
||||||
const u8 *mk);
|
const u8 *mk);
|
||||||
|
int eap_sim_db_add_reauth_prime(void *priv, const u8 *identity,
|
||||||
|
size_t identity_len, char *reauth_id,
|
||||||
|
u16 counter, const u8 *k_encr, const u8 *k_aut,
|
||||||
|
const u8 *k_re);
|
||||||
|
|
||||||
const u8 * eap_sim_db_get_permanent(void *priv, const u8 *identity,
|
const u8 * eap_sim_db_get_permanent(void *priv, const u8 *identity,
|
||||||
size_t identity_len, size_t *len);
|
size_t identity_len, size_t *len);
|
||||||
|
@ -64,7 +68,11 @@ struct eap_sim_reauth {
|
||||||
size_t identity_len;
|
size_t identity_len;
|
||||||
char *reauth_id;
|
char *reauth_id;
|
||||||
u16 counter;
|
u16 counter;
|
||||||
|
int aka_prime;
|
||||||
u8 mk[EAP_SIM_MK_LEN];
|
u8 mk[EAP_SIM_MK_LEN];
|
||||||
|
u8 k_encr[EAP_SIM_K_ENCR_LEN];
|
||||||
|
u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
|
||||||
|
u8 k_re[EAP_AKA_PRIME_K_RE_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eap_sim_reauth *
|
struct eap_sim_reauth *
|
||||||
|
|
Loading…
Reference in a new issue