eap_server_aka.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen/* 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf) 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi> 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * This software may be distributed under the terms of the BSD license. 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * See README for more details. 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "includes.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "common.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "crypto/sha256.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "crypto/crypto.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/random.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "eap_common/eap_sim_common.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "eap_server/eap_i.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "eap_server/eap_sim_db.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct eap_aka_data { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 mk[EAP_SIM_MK_LEN]; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 nonce_s[EAP_SIM_NONCE_S_LEN]; 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN]; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 k_encr[EAP_SIM_K_ENCR_LEN]; 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */ 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 msk[EAP_SIM_KEYING_DATA_LEN]; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 emsk[EAP_EMSK_LEN]; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 rand[EAP_AKA_RAND_LEN]; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 autn[EAP_AKA_AUTN_LEN]; 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 ck[EAP_AKA_CK_LEN]; 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick u8 ik[EAP_AKA_IK_LEN]; 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen u8 res[EAP_AKA_RES_MAX_LEN]; 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t res_len; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IDENTITY, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } state; 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen char *next_pseudonym; 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick char *next_reauth_id; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u16 counter; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_reauth *reauth; 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int auts_reported; /* whether the current AUTS has been reported to the 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * eap_sim_db */ 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick u16 notification; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int use_result_ind; 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct wpabuf *id_msgs; 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int pending_id; 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick u8 eap_method; 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen u8 *network_name; 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t network_name_len; 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick u16 kdf; 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic void eap_aka_determine_identity(struct eap_sm *sm, 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct eap_aka_data *data, 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int before_identity, int after_reauth); 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char * eap_aka_state_txt(int state) 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick{ 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (state) { 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case IDENTITY: 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "IDENTITY"; 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case CHALLENGE: 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "CHALLENGE"; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case REAUTH: 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "REAUTH"; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case SUCCESS: 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "SUCCESS"; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case FAILURE: 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "FAILURE"; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case NOTIFICATION: 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "NOTIFICATION"; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "Unknown?!"; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_state(struct eap_aka_data *data, int state) 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s", 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state_txt(data->state), 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state_txt(state)); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->state = state; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void * eap_aka_init(struct eap_sm *sm) 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{ 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->eap_sim_db_priv == NULL) { 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: eap_sim_db not configured"); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data = os_zalloc(sizeof(*data)); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data == NULL) 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return NULL; 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->eap_method = EAP_TYPE_AKA; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->state = IDENTITY; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_determine_identity(sm, data, 1, 0); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->pending_id = -1; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data; 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void * eap_aka_prime_init(struct eap_sm *sm) 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data; 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* TODO: make ANID configurable; see 3GPP TS 24.302 */ 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char *network_name = "WLAN"; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (sm->eap_sim_db_priv == NULL) { 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick wpa_printf(MSG_WARNING, "EAP-AKA: eap_sim_db not configured"); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data = os_zalloc(sizeof(*data)); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data == NULL) 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->eap_method = EAP_TYPE_AKA_PRIME; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->network_name = (u8 *) os_strdup(network_name); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->network_name == NULL) { 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data->network_name_len = os_strlen(network_name); 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data->state = IDENTITY; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_determine_identity(sm, data, 1, 0); 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen data->pending_id = -1; 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return data; 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif /* EAP_SERVER_AKA_PRIME */ 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_reset(struct eap_sm *sm, void *priv) 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data->next_pseudonym); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data->next_reauth_id); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpabuf_free(data->id_msgs); 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data->network_name); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int eap_aka_add_id_msg(struct eap_aka_data *data, 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const struct wpabuf *msg) 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (msg == NULL) 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->id_msgs == NULL) { 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->id_msgs = wpabuf_dup(msg); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data->id_msgs == NULL ? -1 : 0; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0) 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpabuf_put_buf(data->id_msgs, msg); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_add_checkcode(struct eap_aka_data *data, 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_msg *msg) 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *addr; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t len; 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen u8 hash[SHA256_MAC_LEN]; 18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen wpa_printf(MSG_DEBUG, " AT_CHECKCODE"); 18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data->id_msgs == NULL) { 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen /* 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * No EAP-AKA/Identity packets were exchanged - send empty 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * checkcode. 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */ 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott addr = wpabuf_head(data->id_msgs); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott len = wpabuf_len(data->id_msgs); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len); 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sha256_vector(1, &addr, &len, hash); 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sha1_vector(1, &addr, &len, hash); 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash, 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->eap_method == EAP_TYPE_AKA_PRIME ? 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN); 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int eap_aka_verify_checkcode(struct eap_aka_data *data, 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const u8 *checkcode, size_t checkcode_len) 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *addr; 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t len; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch u8 hash[SHA256_MAC_LEN]; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t hash_len; 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (checkcode == NULL) 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->id_msgs == NULL) { 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (checkcode_len != 0) { 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer " 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "indicates that AKA/Identity messages were " 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "used, but they were not"); 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ? 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN; 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (checkcode_len != hash_len) { 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer indicates " 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "that AKA/Identity message were not used, but they " 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "were"); 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */ 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott addr = wpabuf_head(data->id_msgs); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch len = wpabuf_len(data->id_msgs); 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sha256_vector(1, &addr, &len, hash); 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sha1_vector(1, &addr, &len, hash); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (os_memcmp(hash, checkcode, hash_len) != 0) { 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE"); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct wpabuf * eap_aka_build_identity(struct eap_sm *sm, 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, u8 id) 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct eap_sim_msg *msg; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct wpabuf *buf; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Identity"); 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_SUBTYPE_IDENTITY); 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity, 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len)) { 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0); 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * RFC 4187, Chap. 4.1.4 recommends that identity from EAP is 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * ignored and the AKA/Identity is used to request the 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * identity. 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_ANY_ID_REQ"); 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_ANY_ID_REQ, 0, NULL, 0); 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf = eap_sim_msg_finish(msg, NULL, NULL, 0); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_aka_add_id_msg(data, buf) < 0) { 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpabuf_free(buf); 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->pending_id = id; 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return buf; 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int eap_aka_build_encr(struct eap_sm *sm, struct eap_aka_data *data, 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_msg *msg, u16 counter, 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *nonce_s) 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(data->next_pseudonym); 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_pseudonym = 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch os_free(data->next_reauth_id); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->counter <= EAP_AKA_MAX_FAST_REAUTHS) { 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id = 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 1); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Max fast re-authentication " 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "count exceeded - force full authentication"); 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id = NULL; 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_pseudonym == NULL && data->next_reauth_id == NULL && 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott counter == 0 && nonce_s == NULL) 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_IV"); 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (counter > 0) { 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)", counter); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (nonce_s) { 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " *AT_NONCE_S"); 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_S, 0, nonce_s, 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_NONCE_S_LEN); 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data->next_pseudonym) { 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " *AT_NEXT_PSEUDONYM (%s)", 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_pseudonym); 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_PSEUDONYM, 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_strlen(data->next_pseudonym), 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (u8 *) data->next_pseudonym, 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch os_strlen(data->next_pseudonym)); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_reauth_id) { 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " *AT_NEXT_REAUTH_ID (%s)", 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_REAUTH_ID, 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_strlen(data->next_reauth_id), 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (u8 *) data->next_reauth_id, 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch os_strlen(data->next_reauth_id)); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "AT_ENCR_DATA"); 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct wpabuf * eap_aka_build_challenge(struct eap_sm *sm, 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 id) 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_msg *msg; 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Challenge"); 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_SUBTYPE_CHALLENGE); 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_DEBUG, " AT_RAND"); 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_RAND, 0, data->rand, EAP_AKA_RAND_LEN); 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_AUTN"); 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_AUTN, 0, data->autn, EAP_AKA_AUTN_LEN); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data->eap_method == EAP_TYPE_AKA_PRIME) { 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->kdf) { 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the selected KDF into the beginning */ 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_KDF"); 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_KDF, data->kdf, 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, 0); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_KDF"); 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_KDF, EAP_AKA_PRIME_KDF, 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, 0); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_DEBUG, " AT_KDF_INPUT"); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_sim_msg_add(msg, EAP_SIM_AT_KDF_INPUT, 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->network_name_len, 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->network_name, data->network_name_len); 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_aka_build_encr(sm, data, msg, 0, NULL)) { 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_sim_msg_free(msg); 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_add_checkcode(data, msg); 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->eap_sim_aka_result_ind) { 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA) { 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u16 flags = 0; 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int aka_prime_preferred = 0; 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i = 0; 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (sm->user && i < EAP_MAX_METHODS && 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->user->methods[i].method != EAP_TYPE_NONE)) { 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->user->methods[i].vendor == EAP_VENDOR_IETF) { 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->user->methods[i].method == 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_TYPE_AKA) 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->user->methods[i].method == 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_TYPE_AKA_PRIME) { 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott aka_prime_preferred = 1; 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i++; 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (aka_prime_preferred) 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott flags |= EAP_AKA_BIDDING_FLAG_D; 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_BIDDING, flags, NULL, 0); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* EAP_SERVER_AKA_PRIME */ 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_MAC"); 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm, 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, u8 id) 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_msg *msg; 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Re-authentication"); 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (random_get_bytes(data->nonce_s, EAP_SIM_NONCE_S_LEN)) 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S", 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->nonce_s, EAP_SIM_NONCE_S_LEN); 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) { 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_prime_derive_keys_reauth(data->k_re, data->counter, 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity, 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len, 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->nonce_s, 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->msk, data->emsk); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->msk, data->emsk); 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_derive_keys_reauth(data->counter, sm->identity, 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len, data->nonce_s, 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->mk, data->msk, data->emsk); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_SUBTYPE_REAUTHENTICATION); 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_aka_build_encr(sm, data, msg, data->counter, data->nonce_s)) { 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_free(msg); 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_add_checkcode(data, msg); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sm->eap_sim_aka_result_ind) { 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_MAC"); 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct wpabuf * eap_aka_build_notification(struct eap_sm *sm, 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 id) 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_msg *msg; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Notification"); 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method, 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_SUBTYPE_NOTIFICATION); 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_NOTIFICATION (%d)", data->notification); 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification, 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, 0); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->use_result_ind) { 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->reauth) { 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_IV"); 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_AT_ENCR_DATA); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)", 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter); 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, 0); 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_sim_msg_add_encr_end(msg, data->k_encr, 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_AT_PADDING)) { 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Failed to " 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "encrypt AT_ENCR_DATA"); 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_free(msg); 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, " AT_MAC"); 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_sim_msg_finish(msg, data->k_aut, NULL, 0); 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct wpabuf * eap_aka_buildReq(struct eap_sm *sm, void *priv, u8 id) 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->auts_reported = 0; 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (data->state) { 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case IDENTITY: 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_aka_build_identity(sm, data, id); 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case CHALLENGE: 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_aka_build_challenge(sm, data, id); 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case REAUTH: 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_aka_build_reauth(sm, data, id); 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case NOTIFICATION: 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return eap_aka_build_notification(sm, data, id); 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in " 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "buildReq", data->state); 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic Boolean eap_aka_check(struct eap_sm *sm, void *priv, 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData) 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *pos; 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t len; 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData, 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &len); 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (pos == NULL || len < 3) { 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Invalid frame"); 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE; 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FALSE; 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic Boolean eap_aka_subtype_ok(struct eap_aka_data *data, u8 subtype) 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR || 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FALSE; 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (data->state) { 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case IDENTITY: 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype != EAP_AKA_SUBTYPE_IDENTITY) { 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "subtype %d", subtype); 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE; 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case CHALLENGE: 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype != EAP_AKA_SUBTYPE_CHALLENGE && 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtype != EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) { 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "subtype %d", subtype); 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE; 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case REAUTH: 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype != EAP_AKA_SUBTYPE_REAUTHENTICATION) { 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "subtype %d", subtype); 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE; 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case NOTIFICATION: 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype != EAP_AKA_SUBTYPE_NOTIFICATION) { 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Unexpected response " 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "subtype %d", subtype); 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return TRUE; 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Unexpected state (%d) for " 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "processing a response", data->state); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FALSE; 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_determine_identity(struct eap_sm *sm, 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int before_identity, int after_reauth) 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *identity; 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t identity_len; 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int res; 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = NULL; 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = 0; 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (after_reauth && data->reauth) { 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = data->reauth->identity; 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch identity_len = data->reauth->identity_len; 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (sm->identity && sm->identity_len > 0 && 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity[0] == EAP_AKA_PERMANENT_PREFIX) { 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = sm->identity; 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = sm->identity_len; 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sm->identity, 6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sm->identity_len, 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &identity_len); 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (identity == NULL) { 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth = eap_sim_db_get_reauth_entry( 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sm->eap_sim_db_priv, sm->identity, 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sm->identity_len); 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->reauth && 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth->aka_prime != 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (data->eap_method == EAP_TYPE_AKA_PRIME)) { 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_DEBUG, "EAP-AKA: Reauth data " 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "was for different AKA version"); 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth = NULL; 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->reauth) { 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast " 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "re-authentication"); 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = data->reauth->identity; 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = data->reauth->identity_len; 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter = data->reauth->counter; 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) { 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(data->k_encr, 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth->k_encr, 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_K_ENCR_LEN); 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(data->k_aut, 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth->k_aut, 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_PRIME_K_AUT_LEN); 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(data->k_re, 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth->k_re, 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_AKA_PRIME_K_RE_LEN); 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(data->mk, data->reauth->mk, 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_MK_LEN); 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (identity == NULL || 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity, 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sm->identity_len) < 0) { 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (before_identity) { 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Permanent user name " 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "not known - send AKA-Identity request"); 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_state(data, IDENTITY); 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown whether the " 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "permanent user name is known; try to use " 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "it"); 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* eap_sim_db_get_aka_auth() will report failure, if 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * this identity is not known. */ 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity", 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity, identity_len); 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!after_reauth && data->reauth) { 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, REAUTH); 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott res = eap_sim_db_get_aka_auth(sm->eap_sim_db_priv, identity, 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, data->rand, data->autn, 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->ik, data->ck, data->res, 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &data->res_len, sm); 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (res == EAP_SIM_DB_PENDING) { 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data " 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "not yet available - pending request"); 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->method_pending = METHOD_PENDING_WAIT; 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) { 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * needed 6-octet SQN ^AK for CK',IK' derivation */ 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik, 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->autn, 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->network_name, 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->network_name_len); 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif /* EAP_SERVER_AKA_PRIME */ 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth = NULL; 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter = 0; /* reset re-auth counter since this is full auth */ 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (res != 0) { 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_INFO, "EAP-AKA: Failed to get AKA " 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "authentication data for the peer"); 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_state(data, NOTIFICATION); 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->method_pending == METHOD_PENDING_WAIT) { 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data " 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "available - abort pending wait"); 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->method_pending = METHOD_PENDING_NONE; 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = sm->identity_len; 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') { 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Workaround - drop last null " 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "character from identity"); 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len--; 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation", 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity, identity_len); 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data->eap_method == EAP_TYPE_AKA_PRIME) { 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_prime_derive_keys(identity, identity_len, data->ik, 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->ck, data->k_encr, data->k_aut, 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->k_re, data->msk, data->emsk); 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_derive_mk(sm->identity, identity_len, data->ik, 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->ck, data->mk); 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->msk, data->emsk); 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, CHALLENGE); 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_identity(struct eap_sm *sm, 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct eap_aka_data *data, 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct wpabuf *respData, 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct eap_sim_attrs *attr) 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{ 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Identity"); 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (attr->mac || attr->iv || attr->encr_data) { 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_WARNING, "EAP-AKA: Unexpected attribute " 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "received in EAP-Response/AKA-Identity"); 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (attr->identity) { 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch os_free(sm->identity); 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity = os_malloc(attr->identity_len); 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->identity) { 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(sm->identity, attr->identity, 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott attr->identity_len); 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len = attr->identity_len; 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_determine_identity(sm, data, 0, 0); 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_get_id(respData) == data->pending_id) { 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->pending_id = -1; 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_add_id_msg(data, respData); 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int eap_aka_verify_mac(struct eap_aka_data *data, 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const struct wpabuf *req, 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const u8 *mac, const u8 *extra, 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t extra_len) 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott extra_len); 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len); 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_challenge(struct eap_sm *sm, 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct wpabuf *respData, 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct eap_sim_attrs *attr) 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *identity; 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t identity_len; 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge"); 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 0 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* KDF negotiation; to be enabled only after more than one KDF is 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * supported */ 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME && 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch attr->kdf_count == 1 && attr->mac == NULL) { 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (attr->kdf[0] != EAP_AKA_PRIME_KDF) { 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA': Peer selected " 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "unknown KDF"); 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->kdf = attr->kdf[0]; 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /* Allow negotiation to continue with the selected KDF by 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * sending another Challenge message */ 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf); 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* EAP_SERVER_AKA_PRIME */ 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->checkcode && 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_verify_checkcode(data, attr->checkcode, 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott attr->checkcode_len)) { 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "message"); 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->mac == NULL || 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_verify_mac(data, respData, attr->mac, NULL, 0)) { 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "did not include valid AT_MAC"); 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * AT_RES is padded, so verify that there is enough room for RES and 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * that the RES length in bits matches with the expected RES. 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->res == NULL || attr->res_len < data->res_len || 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott attr->res_len_bits != data->res_len * 8 || 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcmp(attr->res, data->res, data->res_len) != 0) { 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not " 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "include valid AT_RES (attr len=%lu, res len=%lu " 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "bits, expected %lu bits)", 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (unsigned long) attr->res_len, 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (unsigned long) attr->res_len_bits, 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (unsigned long) data->res_len * 8); 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Challenge response includes the " 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "correct AT_MAC"); 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sm->eap_sim_aka_result_ind && attr->result_ind) { 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->use_result_ind = 1; 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data->notification = EAP_SIM_SUCCESS; 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, SUCCESS); 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity, 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len, &identity_len); 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (identity == NULL) { 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = sm->identity; 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = sm->identity_len; 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_pseudonym) { 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity, 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_pseudonym); 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_pseudonym = NULL; 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_reauth_id) { 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) { 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv, 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch identity, 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id, 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter + 1, 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->k_encr, data->k_aut, 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->k_re); 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* EAP_SERVER_AKA_PRIME */ 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity, 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch identity_len, 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id, 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter + 1, 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->mk); 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id = NULL; 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void eap_aka_process_sync_failure(struct eap_sm *sm, 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData, 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs *attr) 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Synchronization-Failure"); 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->auts == NULL) { 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_WARNING, "EAP-AKA: Synchronization-Failure " 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "message did not include valid AT_AUTS"); 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Avoid re-reporting AUTS when processing pending EAP packet by 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * maintaining a local flag stating whether this AUTS has already been 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * reported. */ 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!data->auts_reported && 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_resynchronize(sm->eap_sim_db_priv, sm->identity, 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sm->identity_len, attr->auts, 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->rand)) { 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Resynchronization failed"); 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->auts_reported = 1; 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Try again after resynchronization */ 939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_determine_identity(sm, data, 0, 0); 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_reauth(struct eap_sm *sm, 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData, 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs *attr) 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs eattr; 949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 *decrypted = NULL; 950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *identity, *id2; 951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t identity_len, id2_len; 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication"); 954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->mac == NULL || 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_verify_mac(data, respData, attr->mac, data->nonce_s, 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_SIM_NONCE_S_LEN)) { 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message " 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "did not include valid AT_MAC"); 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (attr->encr_data == NULL || attr->iv == NULL) { 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "message did not include encrypted data"); 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott attr->encr_data_len, attr->iv, &eattr, 971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0); 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (decrypted == NULL) { 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "data from reauthentication message"); 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (eattr.counter != data->counter) { 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message " 980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "used incorrect counter %u, expected %u", 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eattr.counter, data->counter); 982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch os_free(decrypted); 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott decrypted = NULL; 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response includes " 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "the correct AT_MAC"); 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eattr.counter_too_small) { 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response " 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "included AT_COUNTER_TOO_SMALL - starting full " 993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "authentication"); 994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_determine_identity(sm, data, 0, 1); 995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sm->eap_sim_aka_result_ind && attr->result_ind) { 999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->use_result_ind = 1; 1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_SUCCESS; 1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else 1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, SUCCESS); 1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->reauth) { 1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = data->reauth->identity; 1007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = data->reauth->identity_len; 1008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = sm->identity; 1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = sm->identity_len; 1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott id2 = eap_sim_db_get_permanent(sm->eap_sim_db_priv, identity, 1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, &id2_len); 1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (id2) { 1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity = id2; 1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len = id2_len; 1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_pseudonym) { 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity, 1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, data->next_pseudonym); 1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_pseudonym = NULL; 1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->next_reauth_id) { 1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->eap_method == EAP_TYPE_AKA_PRIME) { 1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv, 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity, 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id, 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter + 1, 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->k_encr, data->k_aut, 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->k_re); 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* EAP_SERVER_AKA_PRIME */ 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity, 1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott identity_len, 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id, 1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->counter + 1, 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->mk); 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->next_reauth_id = NULL; 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth); 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth = NULL; 1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottfail: 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth); 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->reauth = NULL; 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_free(decrypted); 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_client_error(struct eap_sm *sm, 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData, 1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs *attr) 1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Client reported error %d", 1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott attr->client_error_code); 1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind) 1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, SUCCESS); 1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, FAILURE); 1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_authentication_reject( 1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sm *sm, struct eap_aka_data *data, 1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData, struct eap_sim_attrs *attr) 1077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wpa_printf(MSG_DEBUG, "EAP-AKA: Client rejected authentication"); 1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_state(data, FAILURE); 1080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process_notification(struct eap_sm *sm, 1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data, 1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData, 1086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs *attr) 1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Client replied to notification"); 1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind) 1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, SUCCESS); 1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, FAILURE); 1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void eap_aka_process(struct eap_sm *sm, void *priv, 1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct wpabuf *respData) 1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const u8 *pos, *end; 1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 subtype; 1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t len; 1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_sim_attrs attr; 1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData, 1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &len); 1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (pos == NULL || len < 3) 1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott end = pos + len; 1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtype = *pos; 1112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += 3; 1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_aka_subtype_ok(data, subtype)) { 1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized or unexpected " 1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "EAP-AKA Subtype in EAP Response"); 1117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eap_aka_state(data, NOTIFICATION); 1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (eap_sim_parse_attr(pos, end, &attr, 1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1, 1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0)) { 1125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes"); 1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH; 1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_state(data, NOTIFICATION); 1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) { 1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_client_error(sm, data, respData, &attr); 1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) { 1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_authentication_reject(sm, data, respData, 1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &attr); 1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (data->state) { 1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case IDENTITY: 1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_identity(sm, data, respData, &attr); 1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case CHALLENGE: 1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) { 1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_sync_failure(sm, data, respData, 1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &attr); 1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_challenge(sm, data, respData, &attr); 1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case REAUTH: 1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_reauth(sm, data, respData, &attr); 1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case NOTIFICATION: 1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_aka_process_notification(sm, data, respData, &attr); 1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 116072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen default: 116121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in " 116221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "process", data->state); 1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 116421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 116621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic Boolean eap_aka_isDone(struct eap_sm *sm, void *priv) 1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data->state == SUCCESS || data->state == FAILURE; 117221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len) 1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 *key; 1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data->state != SUCCESS) 1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key = os_malloc(EAP_SIM_KEYING_DATA_LEN); 1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key == NULL) 1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN); 1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *len = EAP_SIM_KEYING_DATA_LEN; 1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return key; 1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 1195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u8 *key; 1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data->state != SUCCESS) 1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key = os_malloc(EAP_EMSK_LEN); 1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key == NULL) 1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os_memcpy(key, data->emsk, EAP_EMSK_LEN); 1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *len = EAP_EMSK_LEN; 1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return key; 1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic Boolean eap_aka_isSuccess(struct eap_sm *sm, void *priv) 1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_aka_data *data = priv; 1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data->state == SUCCESS; 1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint eap_server_aka_register(void) 1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_method *eap; 1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret; 1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA"); 1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (eap == NULL) 1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->init = eap_aka_init; 1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->reset = eap_aka_reset; 1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->buildReq = eap_aka_buildReq; 1229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->check = eap_aka_check; 1230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->process = eap_aka_process; 1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->isDone = eap_aka_isDone; 1232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->getKey = eap_aka_getKey; 1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->isSuccess = eap_aka_isSuccess; 1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->get_emsk = eap_aka_get_emsk; 1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret = eap_server_method_register(eap); 1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ret) 1238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_server_method_free(eap); 1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 1240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EAP_SERVER_AKA_PRIME 1244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint eap_server_aka_prime_register(void) 1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct eap_method *eap; 1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret; 1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME, 1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "AKA'"); 1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (eap == NULL) 1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->init = eap_aka_prime_init; 1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->reset = eap_aka_reset; 1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->buildReq = eap_aka_buildReq; 1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->check = eap_aka_check; 1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->process = eap_aka_process; 1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->isDone = eap_aka_isDone; 1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->getKey = eap_aka_getKey; 1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->isSuccess = eap_aka_isSuccess; 1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap->get_emsk = eap_aka_get_emsk; 1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret = eap_server_method_register(eap); 1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ret) 1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eap_server_method_free(eap); 1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ret; 1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* EAP_SERVER_AKA_PRIME */ 1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott