EAP-AKA': Derive keys using the new KDF (PRF')
authorJouni Malinen <j@w1.fi>
Wed, 3 Dec 2008 17:22:20 +0000 (19:22 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 3 Dec 2008 17:22:20 +0000 (19:22 +0200)
src/eap_common/eap_sim_common.c
src/eap_common/eap_sim_common.h
src/eap_peer/eap_aka_prime.c
src/eap_server/eap_aka_prime.c
src/eap_server/eap_sim_db.c
src/eap_server/eap_sim_db.h

index 7b7918c..e33fe3e 100644 (file)
@@ -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
+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,
                              const u8 *mac, const u8 *extra, size_t extra_len)
 {
index 7d2093c..15efcb3 100644 (file)
@@ -73,6 +73,7 @@
 
 #define EAP_AKA_PRIME_K_AUT_LEN 32
 #define EAP_AKA_PRIME_CHECKCODE_LEN 32
+#define EAP_AKA_PRIME_K_RE_LEN 32
 
 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);
 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);
+
+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,
                              const u8 *mac, const u8 *extra,
                              size_t extra_len);
index 367549b..544b0b8 100644 (file)
@@ -34,6 +34,7 @@ struct eap_aka_data {
        u8 mk[EAP_SIM_MK_LEN];
        u8 k_aut[EAP_AKA_PRIME_K_AUT_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 emsk[EAP_EMSK_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);
        wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
                          "derivation", identity, identity_len);
-       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 (data->eap_method == EAP_TYPE_AKA_PRIME) {
+               eap_aka_prime_derive_keys(identity, identity_len, data->ik,
+                                         data->ck, data->k_encr, data->k_aut,
+                                         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)) {
                wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
                           "used invalid AT_MAC");
@@ -910,10 +917,6 @@ static struct wpabuf * eap_aka_process_reauthentication(
                           "(%d <= %d)", eattr.counter, data->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
                 * reauth_id must not be used to start a new reauthentication.
                 * 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",
                    data->nonce_s, EAP_SIM_NONCE_S_LEN);
 
-       eap_sim_derive_keys_reauth(data->counter,
-                                  data->reauth_id, data->reauth_id_len,
-                                  data->nonce_s, data->mk, data->msk,
-                                  data->emsk);
+       if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+               eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
+                                                data->reauth_id,
+                                                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_learn_ids(data, &eattr);
 
index a065656..de50d3e 100644 (file)
@@ -28,6 +28,7 @@ struct eap_aka_data {
        u8 nonce_s[EAP_SIM_NONCE_S_LEN];
        u8 k_aut[EAP_AKA_PRIME_K_AUT_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 emsk[EAP_EMSK_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",
                        data->nonce_s, EAP_SIM_NONCE_S_LEN);
 
-       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);
+       if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+               eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
+                                                sm->identity,
+                                                sm->identity_len,
+                                                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,
                               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(
                                sm->eap_sim_db_priv, sm->identity,
                                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) {
                                wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast "
                                           "re-authentication");
                                identity = data->reauth->identity;
                                identity_len = data->reauth->identity_len;
                                data->counter = data->reauth->counter;
-                               os_memcpy(data->mk, data->reauth->mk,
-                                         EAP_SIM_MK_LEN);
+                               if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+                                       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",
                          sm->identity, identity_len);
 
-       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);
+       if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+               eap_aka_prime_derive_keys(identity, identity_len, data->ik,
+                                         data->ck, data->k_encr, data->k_aut,
+                                         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);
 }
@@ -741,10 +775,21 @@ static void eap_aka_process_challenge(struct eap_sm *sm,
                data->next_pseudonym = NULL;
        }
        if (data->next_reauth_id) {
-               eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
-                                     identity_len,
-                                     data->next_reauth_id, data->counter + 1,
-                                     data->mk);
+               if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+                       eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
+                                                   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;
        }
 }
@@ -867,9 +912,21 @@ static void eap_aka_process_reauth(struct eap_sm *sm,
                data->next_pseudonym = NULL;
        }
        if (data->next_reauth_id) {
-               eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
-                                     identity_len, data->next_reauth_id,
-                                     data->counter + 1, data->mk);
+               if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+                       eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
+                                                   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;
        } else {
                eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
index 29f1996..8befbd8 100644 (file)
@@ -942,27 +942,12 @@ int eap_sim_db_add_pseudonym(void *priv, const u8 *identity,
 }
 
 
-/**
- * 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)
+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_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);
@@ -980,7 +965,7 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
                r = os_zalloc(sizeof(*r));
                if (r == NULL) {
                        os_free(reauth_id);
-                       return -1;
+                       return NULL;
                }
 
                r->next = data->reauths;
@@ -988,7 +973,7 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
                if (r->identity == NULL) {
                        os_free(r);
                        os_free(reauth_id);
-                       return -1;
+                       return NULL;
                }
                os_memcpy(r->identity, identity, identity_len);
                r->identity_len = identity_len;
@@ -998,10 +983,82 @@ int eap_sim_db_add_reauth(void *priv, const u8 *identity,
        }
 
        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);
+       r->aka_prime = 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 */
 
 
 /**
index 15b5dce..6622181 100644 (file)
@@ -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,
                          size_t identity_len, char *reauth_id, u16 counter,
                          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,
                                    size_t identity_len, size_t *len);
@@ -64,7 +68,11 @@ struct eap_sim_reauth {
        size_t identity_len;
        char *reauth_id;
        u16 counter;
+       int aka_prime;
        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 *