1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf) 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_peer/eap_i.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "pcsc_funcs.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_common/eap_sim_common.h" 21b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/sha1.h" 22b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/sha256.h" 23b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/crypto.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_peer/eap_config.h" 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef CONFIG_USIM_SIMULATOR 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "hlr_auc_gw/milenage.h" 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_USIM_SIMULATOR */ 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eap_aka_data { 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN]; 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t res_len; 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 nonce_s[EAP_SIM_NONCE_S_LEN]; 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 mk[EAP_SIM_MK_LEN]; 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN]; 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 k_encr[EAP_SIM_K_ENCR_LEN]; 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */ 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 msk[EAP_SIM_KEYING_DATA_LEN]; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 emsk[EAP_EMSK_LEN]; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN]; 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 auts[EAP_AKA_AUTS_LEN]; 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int num_id_req, num_notification; 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *pseudonym; 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t pseudonym_len; 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *reauth_id; 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t reauth_id_len; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reauth; 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int counter, counter_too_small; 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *last_eap_identity; 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t last_eap_identity_len; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt enum { 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } state; 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *id_msgs; 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int prev_id; 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int result_ind, use_result_ind; 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 eap_method; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *network_name; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t network_name_len; 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u16 kdf; 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int kdf_negotiation; 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic const char * eap_aka_state_txt(int state) 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (state) { 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CONTINUE: 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "CONTINUE"; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case RESULT_SUCCESS: 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "RESULT_SUCCESS"; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case RESULT_FAILURE: 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "RESULT_FAILURE"; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SUCCESS: 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "SUCCESS"; 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case FAILURE: 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "FAILURE"; 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return "?"; 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_aka_state(struct eap_aka_data *data, int state) 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s", 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state_txt(data->state), 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state_txt(state)); 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->state = state; 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void * eap_aka_init(struct eap_sm *sm) 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data; 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *phase1 = eap_get_config_phase1(sm); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data = os_zalloc(sizeof(*data)); 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data == NULL) 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->eap_method = EAP_TYPE_AKA; 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, CONTINUE); 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->prev_id = -1; 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->result_ind = phase1 && os_strstr(phase1, "result_ind=1") != NULL; 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data; 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void * eap_aka_prime_init(struct eap_sm *sm) 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = eap_aka_init(sm); 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data == NULL) 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->eap_method = EAP_TYPE_AKA_PRIME; 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_aka_deinit(struct eap_sm *sm, void *priv) 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data) { 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->pseudonym); 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->reauth_id); 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->last_eap_identity); 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(data->id_msgs); 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->network_name); 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data) 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_peer_config *conf; 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm"); 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conf = eap_get_config(sm); 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf == NULL) 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->pcsc) { 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return scard_umts_auth(sm->scard_ctx, data->rand, 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->autn, data->res, &data->res_len, 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->ik, data->ck, data->auts); 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef CONFIG_USIM_SIMULATOR 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->password) { 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 opc[16], k[16], sqn[6]; 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *pos; 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Use internal Milenage " 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "implementation for UMTS authentication"); 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->password_len < 78) { 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: invalid Milenage " 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "password"); 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = (const char *) conf->password; 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hexstr2bin(pos, k, 16)) 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += 32; 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos != ':') 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos++; 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hexstr2bin(pos, opc, 16)) 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += 32; 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos != ':') 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos++; 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hexstr2bin(pos, sqn, 6)) 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return milenage_check(opc, k, sqn, data->rand, data->autn, 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->ik, data->ck, 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->res, &data->res_len, data->auts); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_USIM_SIMULATOR */ 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef CONFIG_USIM_HARDCODED 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Use hardcoded Kc and SRES values for " 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "testing"); 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* These hardcoded Kc and SRES values are used for testing. 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Could consider making them configurable. */ 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN); 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->res_len = EAP_AKA_RES_MAX_LEN; 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(data->ik, '3', EAP_AKA_IK_LEN); 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(data->ck, '4', EAP_AKA_CK_LEN); 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 autn[EAP_AKA_AUTN_LEN]; 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(autn, '1', EAP_AKA_AUTN_LEN); 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) { 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match " 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "with expected value"); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt static int test_resync = 1; 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (test_resync) { 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Test Resynchronization */ 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt test_resync = 0; 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -2; 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* CONFIG_USIM_HARDCODED */ 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: No UMTS authentication algorith " 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "enabled"); 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_USIM_HARDCODED */ 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define CLEAR_PSEUDONYM 0x01 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define CLEAR_REAUTH_ID 0x02 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define CLEAR_EAP_ID 0x04 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_aka_clear_identities(struct eap_aka_data *data, int id) 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s", 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id & CLEAR_PSEUDONYM ? " pseudonym" : "", 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id & CLEAR_REAUTH_ID ? " reauth_id" : "", 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id & CLEAR_EAP_ID ? " eap_id" : ""); 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id & CLEAR_PSEUDONYM) { 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->pseudonym); 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym = NULL; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym_len = 0; 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id & CLEAR_REAUTH_ID) { 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->reauth_id); 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id = NULL; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len = 0; 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id & CLEAR_EAP_ID) { 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->last_eap_identity); 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->last_eap_identity = NULL; 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->last_eap_identity_len = 0; 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_learn_ids(struct eap_aka_data *data, 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->next_pseudonym) { 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->pseudonym); 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym = os_malloc(attr->next_pseudonym_len); 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->pseudonym == NULL) { 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for " 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "next pseudonym"); 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->pseudonym, attr->next_pseudonym, 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->next_pseudonym_len); 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym_len = attr->next_pseudonym_len; 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "EAP-AKA: (encr) AT_NEXT_PSEUDONYM", 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym, 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym_len); 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->next_reauth_id) { 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->reauth_id); 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id = os_malloc(attr->next_reauth_id_len); 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->reauth_id == NULL) { 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for " 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "next reauth_id"); 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->reauth_id, attr->next_reauth_id, 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->next_reauth_id_len); 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len = attr->next_reauth_id_len; 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "EAP-AKA: (encr) AT_NEXT_REAUTH_ID", 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id, 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len); 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_add_id_msg(struct eap_aka_data *data, 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *msg) 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (msg == NULL) 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->id_msgs == NULL) { 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->id_msgs = wpabuf_dup(msg); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data->id_msgs == NULL ? -1 : 0; 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0) 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_buf(data->id_msgs, msg); 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_aka_add_checkcode(struct eap_aka_data *data, 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg) 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr; 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len; 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_CHECKCODE"); 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->id_msgs == NULL) { 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * No EAP-AKA/Identity packets were exchanged - send empty 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * checkcode. 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0); 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */ 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr = wpabuf_head(data->id_msgs); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = wpabuf_len(data->id_msgs); 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len); 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha256_vector(1, &addr, &len, hash); 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_vector(1, &addr, &len, hash); 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash, 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->eap_method == EAP_TYPE_AKA_PRIME ? 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN); 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_verify_checkcode(struct eap_aka_data *data, 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *checkcode, size_t checkcode_len) 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr; 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len; 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t hash_len; 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (checkcode == NULL) 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->id_msgs == NULL) { 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (checkcode_len != 0) { 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server " 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "indicates that AKA/Identity messages were " 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "used, but they were not"); 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ? 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN; 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (checkcode_len != hash_len) { 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server " 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "indicates that AKA/Identity message were not " 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "used, but they were"); 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */ 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr = wpabuf_head(data->id_msgs); 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = wpabuf_len(data->id_msgs); 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha256_vector(1, &addr, &len, hash); 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_vector(1, &addr, &len, hash); 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_memcmp(hash, checkcode, hash_len) != 0) { 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE"); 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id, 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int err) 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, FAILURE); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_CLIENT_ERROR); 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, NULL, NULL, 0); 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data, 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id) 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, FAILURE); 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject " 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(id=%d)", id); 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT); 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, NULL, NULL, 0); 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_synchronization_failure( 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data, u8 id) 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure " 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(id=%d)", id); 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE); 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_AUTS"); 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts, 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_AUTS_LEN); 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, NULL, NULL, 0); 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_response_identity(struct eap_sm *sm, 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data, 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt enum eap_sim_id_req id_req) 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *identity = NULL; 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t identity_len = 0; 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth = 0; 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id_req == ANY_ID && data->reauth_id) { 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = data->reauth_id; 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity_len = data->reauth_id_len; 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth = 1; 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->pseudonym) { 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = data->pseudonym; 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity_len = data->pseudonym_len; 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_REAUTH_ID); 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (id_req != NO_ID_REQ) { 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = eap_get_config_identity(sm, &identity_len); 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (identity) { 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_PSEUDONYM | 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CLEAR_REAUTH_ID); 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id_req != NO_ID_REQ) 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_EAP_ID); 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id); 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_IDENTITY); 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (identity) { 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY", 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity, identity_len); 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len, 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity, identity_len); 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, NULL, NULL, 0); 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data, 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id) 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id); 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_CHALLENGE); 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_RES"); 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8, 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->res, data->res_len); 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_add_checkcode(data, msg); 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->use_result_ind) { 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_MAC"); 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, data->k_aut, (u8 *) "", 0); 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data, 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, int counter_too_small, 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *nonce_s) 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int counter; 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)", 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id); 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_REAUTHENTICATION); 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_IV"); 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (counter_too_small) { 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL"); 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0); 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter = data->counter_too_small; 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt counter = data->counter; 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter); 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "AT_ENCR_DATA"); 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_free(msg); 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_add_checkcode(data, msg); 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->use_result_ind) { 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_MAC"); 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, data->k_aut, nonce_s, 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_SIM_NONCE_S_LEN); 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data, 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, u16 notification) 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL; 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id); 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_NOTIFICATION); 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (k_aut && data->reauth) { 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_IV"); 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_SIM_AT_ENCR_DATA); 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter); 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, 0); 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_sim_msg_add_encr_end(msg, data->k_encr, 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_SIM_AT_PADDING)) { 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "AT_ENCR_DATA"); 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_free(msg); 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (k_aut) { 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_MAC"); 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0); 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_process_identity(struct eap_sm *sm, 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data, 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData, 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int id_error; 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *buf; 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity"); 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id_error = 0; 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (attr->id_req) { 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case NO_ID_REQ: 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ANY_ID: 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->num_id_req > 0) 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id_error++; 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req++; 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case FULLAUTH_ID: 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->num_id_req > 1) 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id_error++; 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req++; 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case PERMANENT_ID: 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->num_id_req > 2) 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id_error++; 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req++; 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id_error) { 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests " 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "used within one authentication"); 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf = eap_aka_response_identity(sm, data, id, attr->id_req); 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->prev_id != id) { 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_add_id_msg(data, reqData); 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_add_id_msg(data, buf); 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->prev_id = id; 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return buf; 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_verify_mac(struct eap_aka_data *data, 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *req, 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *mac, const u8 *extra, 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t extra_len) 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt extra_len); 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len); 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data, 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, u16 kdf) 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_msg *msg; 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->kdf_negotiation = 1; 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->kdf = kdf; 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF " 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "select)", id); 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_SUBTYPE_CHALLENGE); 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, " AT_KDF"); 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0); 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_sim_msg_finish(msg, NULL, NULL, 0); 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data, 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, struct eap_sim_attrs *attr) 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < attr->kdf_count; i++) { 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf[i] == EAP_AKA_PRIME_KDF) 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_prime_kdf_select(data, id, 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_PRIME_KDF); 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* No matching KDF found - fail authentication as if AUTN had been 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * incorrect */ 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_prime_kdf_valid(struct eap_aka_data *data, 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i, j; 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf_count == 0) 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* The only allowed (and required) duplication of a KDF is the addition 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * of the selected KDF into the beginning of the list. */ 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->kdf_negotiation) { 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf[0] != data->kdf) { 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': The server did not " 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "accept the selected KDF"); 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 1; i < attr->kdf_count; i++) { 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf[i] == data->kdf) 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (i == attr->kdf_count && 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->kdf_count < EAP_AKA_PRIME_KDF_MAX) { 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': The server did not " 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "duplicate the selected KDF"); 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: should check that the list is identical to the one 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * used in the previous Challenge message apart from the added 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * entry in the beginning. */ 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) { 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (j = i + 1; j < attr->kdf_count; j++) { 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf[i] == attr->kdf[j]) { 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': The server " 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "included a duplicated KDF"); 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 1; 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data, 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 id, 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData, 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *identity; 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t identity_len; 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int res; 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs eattr; 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge"); 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->checkcode && 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_verify_checkcode(data, attr->checkcode, 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->checkcode_len)) { 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message"); 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) { 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!attr->kdf_input || attr->kdf_input_len == 0) { 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message " 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "did not include non-empty AT_KDF_INPUT"); 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Fail authentication as if AUTN had been incorrect */ 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->network_name); 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->network_name = os_malloc(attr->kdf_input_len); 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->network_name == NULL) { 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': No memory for " 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "storing Network Name"); 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->network_name, attr->kdf_input, 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->kdf_input_len); 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->network_name_len = attr->kdf_input_len; 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name " 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(AT_KDF_INPUT)", 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->network_name, data->network_name_len); 790526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: check Network Name per 3GPP.33.402 */ 791526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 792526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!eap_aka_prime_kdf_valid(data, attr)) 793526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 794526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 795526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->kdf[0] != EAP_AKA_PRIME_KDF) 796526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_prime_kdf_neg(data, id, attr); 797526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 798526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->kdf = EAP_AKA_PRIME_KDF; 799526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf); 800526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA && attr->bidding) { 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u16 flags = WPA_GET_BE16(attr->bidding); 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((flags & EAP_AKA_BIDDING_FLAG_D) && 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_allowed_method(sm, EAP_VENDOR_IETF, 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_TYPE_AKA_PRIME)) { 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from " 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "AKA' to AKA detected"); 809526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Fail authentication as if AUTN had been incorrect */ 810526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 811526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 812526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 813526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 814526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 815526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth = 0; 816526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!attr->mac || !attr->rand || !attr->autn) { 817526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 818526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "did not include%s%s%s", 819526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !attr->mac ? " AT_MAC" : "", 820526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !attr->rand ? " AT_RAND" : "", 821526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !attr->autn ? " AT_AUTN" : ""); 822526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 823526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 824526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 825526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN); 826526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN); 827526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 828526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_umts_auth(sm, data); 829526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (res == -1) { 830526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 831526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "failed (AUTN)"); 832526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 833526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (res == -2) { 834526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 835526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "failed (AUTN seq# -> AUTS)"); 836526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_synchronization_failure(data, id); 837526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (res) { 838526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed"); 839526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 840526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 841526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 842526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 843526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) { 844526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the 845526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * needed 6-octet SQN ^ AK for CK',IK' derivation */ 846526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u16 amf = WPA_GET_BE16(data->autn + 6); 847526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!(amf & 0x8000)) { 848526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit " 849526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "not set (AMF=0x%4x)", amf); 850526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_authentication_reject(data, id); 851526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 852526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik, 853526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->autn, 854526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->network_name, 855526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->network_name_len); 856526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 857526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 858526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->last_eap_identity) { 859526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = data->last_eap_identity; 860526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity_len = data->last_eap_identity_len; 861526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (data->pseudonym) { 862526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = data->pseudonym; 863526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity_len = data->pseudonym_len; 864526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 865526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity = eap_get_config_identity(sm, &identity_len); 866526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK " 867526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "derivation", identity, identity_len); 868526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) { 869526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_prime_derive_keys(identity, identity_len, data->ik, 870526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->ck, data->k_encr, data->k_aut, 871526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->k_re, data->msk, data->emsk); 872526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 873526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_derive_mk(identity, identity_len, data->ik, data->ck, 874526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->mk); 875526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, 876526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->msk, data->emsk); 877526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 878526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 879526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 880526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "used invalid AT_MAC"); 881526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 882526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 883526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 884526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 885526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Old reauthentication and pseudonym identities must not be used 886526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * anymore. In other words, if no new identities are received, full 887526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * authentication will be used on next reauthentication. */ 888526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID | 889526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CLEAR_EAP_ID); 890526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 891526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->encr_data) { 892526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *decrypted; 893526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 894526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->encr_data_len, attr->iv, 895526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &eattr, 0); 896526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (decrypted == NULL) { 897526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error( 898526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); 899526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 900526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_learn_ids(data, &eattr); 901526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 902526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 903526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 904526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->result_ind && attr->result_ind) 905526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->use_result_ind = 1; 906526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 907526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->state != FAILURE && data->state != RESULT_FAILURE) { 908526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, data->use_result_ind ? 909526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RESULT_SUCCESS : SUCCESS); 910526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 911526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 912526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 913526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 914526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* RFC 4187 specifies that counter is initialized to one after 915526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * fullauth, but initializing it to zero makes it easier to implement 916526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * reauth verification. */ 917526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->counter = 0; 918526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_response_challenge(data, id); 919526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 920526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 921526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 922526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_process_notification_reauth(struct eap_aka_data *data, 923526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 924526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 925526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs eattr; 926526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *decrypted; 927526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 928526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->encr_data == NULL || attr->iv == NULL) { 929526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after " 930526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "reauth did not include encrypted data"); 931526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 932526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 933526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 934526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 935526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->encr_data_len, attr->iv, &eattr, 936526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0); 937526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (decrypted == NULL) { 938526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 939526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "data from notification message"); 940526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 941526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 942526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 943526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) { 944526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification " 945526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message does not match with counter in reauth " 946526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message"); 947526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 948526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 949526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 950526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 951526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 952526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 953526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 954526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 955526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 956526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_aka_process_notification_auth(struct eap_aka_data *data, 957526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData, 958526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs *attr) 959526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 960526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->mac == NULL) { 961526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth " 962526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Notification message"); 963526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 964526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 965526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 966526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 967526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Notification message " 968526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "used invalid AT_MAC"); 969526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 970526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 971526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 972526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->reauth && 973526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_process_notification_reauth(data, attr)) { 974526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification " 975526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message after reauth"); 976526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 977526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 978526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 979526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 980526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 981526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 982526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 983526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_process_notification( 984526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sm *sm, struct eap_aka_data *data, u8 id, 985526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData, struct eap_sim_attrs *attr) 986526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 987526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification"); 988526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->num_notification > 0) { 989526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: too many notification " 990526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "rounds (only one allowed)"); 991526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 992526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 993526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 994526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification++; 995526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->notification == -1) { 996526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in " 997526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Notification message"); 998526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 999526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1000526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1001526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1002526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((attr->notification & 0x4000) == 0 && 1003526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_process_notification_auth(data, reqData, attr)) { 1004526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1005526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1006526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1007526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1008526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_report_notification(sm->msg_ctx, attr->notification, 1); 1009526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->notification >= 0 && attr->notification < 32768) { 1010526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, FAILURE); 1011526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (attr->notification == EAP_SIM_SUCCESS && 1012526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->state == RESULT_SUCCESS) 1013526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, SUCCESS); 1014526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_response_notification(data, id, attr->notification); 1015526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1016526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1017526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1018526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_process_reauthentication( 1019526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sm *sm, struct eap_aka_data *data, u8 id, 1020526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData, struct eap_sim_attrs *attr) 1021526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1022526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs eattr; 1023526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *decrypted; 1024526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1025526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication"); 1026526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1027526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->checkcode && 1028526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_verify_checkcode(data, attr->checkcode, 1029526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->checkcode_len)) { 1030526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " 1031526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message"); 1032526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1033526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1034526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1035526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1036526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->reauth_id == NULL) { 1037526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying " 1038526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "reauthentication, but no reauth_id available"); 1039526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1040526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1041526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1042526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1043526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth = 1; 1044526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 1045526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 1046526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "did not have valid AT_MAC"); 1047526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1048526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1049526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1050526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1051526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (attr->encr_data == NULL || attr->iv == NULL) { 1052526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 1053526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "message did not include encrypted data"); 1054526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1055526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1056526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1057526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1058526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 1059526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt attr->encr_data_len, attr->iv, &eattr, 1060526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0); 1061526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (decrypted == NULL) { 1062526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 1063526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "data from reauthentication message"); 1064526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1065526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1066526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1067526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1068526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eattr.nonce_s == NULL || eattr.counter < 0) { 1069526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet", 1070526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !eattr.nonce_s ? " AT_NONCE_S" : "", 1071526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eattr.counter < 0 ? " AT_COUNTER" : ""); 1072526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 1073526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_client_error(data, id, 1074526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1075526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1076526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1077526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { 1078526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *res; 1079526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter " 1080526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(%d <= %d)", eattr.counter, data->counter); 1081526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->counter_too_small = eattr.counter; 1082526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1083526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current 1084526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * reauth_id must not be used to start a new reauthentication. 1085526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * However, since it was used in the last EAP-Response-Identity 1086526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * packet, it has to saved for the following fullauth to be 1087526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * used in MK derivation. */ 1088526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data->last_eap_identity); 1089526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->last_eap_identity = data->reauth_id; 1090526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->last_eap_identity_len = data->reauth_id_len; 1091526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id = NULL; 1092526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len = 0; 1093526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1094526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s); 1095526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 1096526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1097526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return res; 1098526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1099526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->counter = eattr.counter; 1100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); 1102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S", 1103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->nonce_s, EAP_SIM_NONCE_S_LEN); 1104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->eap_method == EAP_TYPE_AKA_PRIME) { 1106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_prime_derive_keys_reauth(data->k_re, data->counter, 1107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id, 1108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len, 1109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->nonce_s, 1110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->msk, data->emsk); 1111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 1112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sim_derive_keys_reauth(data->counter, data->reauth_id, 1113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->reauth_id_len, 1114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->nonce_s, data->mk, 1115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->msk, data->emsk); 1116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 1118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_learn_ids(data, &eattr); 1119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->result_ind && attr->result_ind) 1121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->use_result_ind = 1; 1122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->state != FAILURE && data->state != RESULT_FAILURE) { 1124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, data->use_result_ind ? 1125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RESULT_SUCCESS : SUCCESS); 1126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 1129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 1130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) { 1131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of " 1132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "fast reauths performed - force fullauth"); 1133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 1134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(decrypted); 1136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eap_aka_response_reauth(data, id, 0, data->nonce_s); 1137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv, 1141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_method_ret *ret, 1142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wpabuf *reqData) 1143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct eap_hdr *req; 1146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 subtype, id; 1147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *res; 1148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *pos; 1149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sim_attrs attr; 1150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len; 1151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData); 1153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_get_config_identity(sm, &len) == NULL) { 1154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured"); 1155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_request_identity(sm); 1156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->ignore = TRUE; 1157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData, 1161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &len); 1162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos == NULL || len < 1) { 1163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->ignore = TRUE; 1164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt req = wpabuf_head(reqData); 1167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id = req->identifier; 1168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = be_to_host16(req->length); 1169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->ignore = FALSE; 1171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->methodState = METHOD_MAY_CONT; 1172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->decision = DECISION_FAIL; 1173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->allowNotifications = TRUE; 1174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt subtype = *pos++; 1176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype); 1177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += 2; /* Reserved */ 1178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 1180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1, 1181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0)) { 1182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_client_error(data, id, 1183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto done; 1185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (subtype) { 1188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AKA_SUBTYPE_IDENTITY: 1189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_process_identity(sm, data, id, reqData, &attr); 1190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AKA_SUBTYPE_CHALLENGE: 1192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_process_challenge(sm, data, id, reqData, &attr); 1193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AKA_SUBTYPE_NOTIFICATION: 1195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_process_notification(sm, data, id, reqData, 1196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &attr); 1197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AKA_SUBTYPE_REAUTHENTICATION: 1199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_process_reauthentication(sm, data, id, reqData, 1200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &attr); 1201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AKA_SUBTYPE_CLIENT_ERROR: 1203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error"); 1204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_client_error(data, id, 1205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 1208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype); 1209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = eap_aka_client_error(data, id, 1210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtdone: 1215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->state == FAILURE) { 1216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->decision = DECISION_FAIL; 1217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->methodState = METHOD_DONE; 1218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (data->state == SUCCESS) { 1219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->decision = data->use_result_ind ? 1220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DECISION_UNCOND_SUCC : DECISION_COND_SUCC; 1221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 1222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * It is possible for the server to reply with AKA 1223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Notification, so we must allow the method to continue and 1224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * not only accept EAP-Success at this point. 1225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->methodState = data->use_result_ind ? 1227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt METHOD_DONE : METHOD_MAY_CONT; 1228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (data->state == RESULT_FAILURE) 1229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->methodState = METHOD_CONT; 1230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (data->state == RESULT_SUCCESS) 1231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->methodState = METHOD_CONT; 1232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret->methodState == METHOD_DONE) { 1234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret->allowNotifications = FALSE; 1235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return res; 1238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv) 1242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data->pseudonym || data->reauth_id; 1245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv) 1249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_clear_identities(data, CLEAR_EAP_ID); 1252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->prev_id = -1; 1253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(data->id_msgs); 1254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->id_msgs = NULL; 1255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->use_result_ind = 0; 1256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->kdf_negotiation = 0; 1257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv) 1261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_id_req = 0; 1264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data->num_notification = 0; 1265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_aka_state(data, CONTINUE); 1266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return priv; 1267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv, 1271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t *len) 1272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->reauth_id) { 1276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *len = data->reauth_id_len; 1277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data->reauth_id; 1278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->pseudonym) { 1281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *len = data->pseudonym_len; 1282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data->pseudonym; 1283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv) 1290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return data->state == SUCCESS; 1293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len) 1297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *key; 1300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->state != SUCCESS) 1302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt key = os_malloc(EAP_SIM_KEYING_DATA_LEN); 1305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key == NULL) 1306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *len = EAP_SIM_KEYING_DATA_LEN; 1309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN); 1310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return key; 1312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_aka_data *data = priv; 1318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *key; 1319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data->state != SUCCESS) 1321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt key = os_malloc(EAP_EMSK_LEN); 1324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key == NULL) 1325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *len = EAP_EMSK_LEN; 1328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(key, data->emsk, EAP_EMSK_LEN); 1329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return key; 1331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_peer_aka_register(void) 1335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_method *eap; 1337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 1338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA"); 1341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap == NULL) 1342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->init = eap_aka_init; 1345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->deinit = eap_aka_deinit; 1346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->process = eap_aka_process; 1347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->isKeyAvailable = eap_aka_isKeyAvailable; 1348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->getKey = eap_aka_getKey; 1349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->has_reauth_data = eap_aka_has_reauth_data; 1350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->deinit_for_reauth = eap_aka_deinit_for_reauth; 1351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->init_for_reauth = eap_aka_init_for_reauth; 1352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->get_identity = eap_aka_get_identity; 1353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->get_emsk = eap_aka_get_emsk; 1354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = eap_peer_method_register(eap); 1356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret) 1357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_peer_method_free(eap); 1358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 1359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef EAP_AKA_PRIME 1363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_peer_aka_prime_register(void) 1364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_method *eap; 1366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 1367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME, 1370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "AKA'"); 1371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap == NULL) 1372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->init = eap_aka_prime_init; 1375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->deinit = eap_aka_deinit; 1376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->process = eap_aka_process; 1377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->isKeyAvailable = eap_aka_isKeyAvailable; 1378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->getKey = eap_aka_getKey; 1379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->has_reauth_data = eap_aka_has_reauth_data; 1380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->deinit_for_reauth = eap_aka_deinit_for_reauth; 1381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->init_for_reauth = eap_aka_init_for_reauth; 1382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->get_identity = eap_aka_get_identity; 1383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap->get_emsk = eap_aka_get_emsk; 1384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = eap_peer_method_register(eap); 1386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret) 1387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_peer_method_free(eap); 1388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 1390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* EAP_AKA_PRIME */ 1392