1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP peer: EAP-SIM/AKA shared routines 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify 6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as 7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation. 8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD 10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license. 11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details. 13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h" 16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h" 18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_i.h" 19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "sha1.h" 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "crypto.h" 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "aes_wrap.h" 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_sim_common.h" 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_sim_prf(const u8 *key, u8 *x, size_t xlen) 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return fips186_2_prf(key, EAP_SIM_MK_LEN, x, xlen); 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sim_derive_mk(const u8 *identity, size_t identity_len, 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *nonce_mt, u16 selected_version, 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *ver_list, size_t ver_list_len, 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int num_chal, const u8 *kc, u8 *mk) 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 sel_ver[2]; 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const unsigned char *addr[5]; 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[5]; 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = identity; 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = identity_len; 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = kc; 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = num_chal * EAP_SIM_KC_LEN; 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[2] = nonce_mt; 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[2] = EAP_SIM_NONCE_MT_LEN; 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[3] = ver_list; 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[3] = ver_list_len; 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[4] = sel_ver; 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[4] = 2; 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(sel_ver, selected_version); 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */ 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha1_vector(5, addr, len, mk); 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN); 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_aka_derive_mk(const u8 *identity, size_t identity_len, 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *ik, const u8 *ck, u8 *mk) 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[3]; 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[3]; 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = identity; 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = identity_len; 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = ik; 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = EAP_AKA_IK_LEN; 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[2] = ck; 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[2] = EAP_AKA_CK_LEN; 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* MK = SHA1(Identity|IK|CK) */ 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha1_vector(3, addr, len, mk); 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: IK", ik, EAP_AKA_IK_LEN); 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: CK", ck, EAP_AKA_CK_LEN); 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: MK", mk, EAP_SIM_MK_LEN); 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk, u8 *emsk) 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 buf[EAP_SIM_K_ENCR_LEN + EAP_SIM_K_AUT_LEN + 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN], *pos; 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sim_prf(mk, buf, sizeof(buf)) < 0) { 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys"); 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = buf; 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN); 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_SIM_K_ENCR_LEN; 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(k_aut, pos, EAP_SIM_K_AUT_LEN); 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_SIM_K_AUT_LEN; 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(msk, pos, EAP_SIM_KEYING_DATA_LEN); 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_SIM_KEYING_DATA_LEN; 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(emsk, pos, EAP_EMSK_LEN); 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_encr", 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_encr, EAP_SIM_K_ENCR_LEN); 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_aut", 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_aut, EAP_SIM_K_AUT_LEN); 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: keying material (MSK)", 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msk, EAP_SIM_KEYING_DATA_LEN); 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN); 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(buf, 0, sizeof(buf)); 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_derive_keys_reauth(u16 _counter, 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *identity, size_t identity_len, 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *nonce_s, const u8 *mk, u8 *msk, 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *emsk) 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 xkey[SHA1_MAC_LEN]; 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 buf[EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN + 32]; 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 counter[2]; 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[4]; 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[4]; 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (identity_len > 0 && identity[identity_len - 1] == 0) { 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop null " 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "character from the end of identity"); 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity_len--; 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = identity; 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = identity_len; 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = counter; 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = 2; 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[2] = nonce_s; 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[2] = EAP_SIM_NONCE_S_LEN; 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[3] = mk; 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[3] = EAP_SIM_MK_LEN; 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(counter, _counter); 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: Deriving keying data from reauth"); 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity", 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project identity, identity_len); 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: counter", counter, 2); 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: NONCE_S", nonce_s, 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_SIM_NONCE_S_LEN); 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN); 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* XKEY' = SHA1(Identity|counter|NONCE_S|MK) */ 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sha1_vector(4, addr, len, xkey); 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: XKEY'", xkey, SHA1_MAC_LEN); 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sim_prf(xkey, buf, sizeof(buf)) < 0) { 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys"); 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msk) { 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(msk, buf, EAP_SIM_KEYING_DATA_LEN); 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: keying material (MSK)", 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msk, EAP_SIM_KEYING_DATA_LEN); 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (emsk) { 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(emsk, buf + EAP_SIM_KEYING_DATA_LEN, EAP_EMSK_LEN); 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN); 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(buf, 0, sizeof(buf)); 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_verify_mac(const u8 *k_aut, const u8 *req, size_t req_len, 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *mac, const u8 *extra, size_t extra_len) 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned char hmac[SHA1_MAC_LEN]; 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[2]; 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[2]; 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *tmp; 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (mac == NULL || req_len < EAP_SIM_MAC_LEN || mac < req || 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project mac > req + req_len - EAP_SIM_MAC_LEN) 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tmp = os_malloc(req_len); 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (tmp == NULL) 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = tmp; 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = req_len; 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = extra; 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = extra_len; 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* HMAC-SHA1-128 */ 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(tmp, req, req_len); 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(tmp + (mac - req), 0, EAP_SIM_MAC_LEN); 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - msg", tmp, req_len); 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - extra data", 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project extra, extra_len); 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Verify MAC - K_aut", 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_aut, EAP_SIM_K_AUT_LEN); 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac); 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC: MAC", 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac, EAP_SIM_MAC_LEN); 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(tmp); 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1; 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sim_add_mac(const u8 *k_aut, u8 *msg, size_t msg_len, u8 *mac, 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *extra, size_t extra_len) 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project unsigned char hmac[SHA1_MAC_LEN]; 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *addr[2]; 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len[2]; 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[0] = msg; 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[0] = msg_len; 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project addr[1] = extra; 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len[1] = extra_len; 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* HMAC-SHA1-128 */ 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(mac, 0, EAP_SIM_MAC_LEN); 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - msg", msg, msg_len); 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - extra data", 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project extra, extra_len); 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Add MAC - K_aut", 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project k_aut, EAP_SIM_K_AUT_LEN); 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac); 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(mac, hmac, EAP_SIM_MAC_LEN); 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC: MAC", 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project mac, EAP_SIM_MAC_LEN); 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_parse_attr(const u8 *start, const u8 *end, 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_sim_attrs *attr, int aka, int encr) 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos = start, *apos; 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t alen, plen, i, list_len; 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(attr, 0, sizeof(*attr)); 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->id_req = NO_ID_REQ; 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->notification = -1; 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->counter = -1; 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->selected_version = -1; 243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->client_error_code = -1; 244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project while (pos < end) { 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos + 2 > end) { 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow(1)"); 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_MSGDUMP, "EAP-SIM: Attribute: Type=%d Len=%d", 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos[0], pos[1] * 4); 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos + pos[1] * 4 > end) { 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow " 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(pos=%p len=%d end=%p)", 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, pos[1] * 4, end); 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos[1] == 0) { 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Attribute underflow"); 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos = pos + 2; 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen = pos[1] * 4 - 2; 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Attribute data", 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos, alen); 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (pos[0]) { 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_RAND: 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RAND"); 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos += 2; 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen -= 2; 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if ((!aka && (alen % GSM_RAND_LEN)) || 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (aka && alen != EAP_AKA_RAND_LEN)) { 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RAND" 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " (len %lu)", 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->rand = apos; 280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->num_chal = alen / GSM_RAND_LEN; 281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_AUTN: 283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTN"); 284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!aka) { 285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: " 286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "Unexpected AT_AUTN"); 287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos += 2; 290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen -= 2; 291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != EAP_AKA_AUTN_LEN) { 292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTN" 293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " (len %lu)", 294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->autn = apos; 298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_PADDING: 300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_PADDING"); 303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_PADDING"); 306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 2; i < alen; i++) { 307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (apos[i] != 0) { 308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) " 309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_PADDING used a non-zero" 310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " padding byte"); 311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-SIM: " 312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(encr) padding bytes", 313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos + 2, alen - 2); 314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_NONCE_MT: 319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NONCE_MT"); 320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2 + EAP_SIM_NONCE_MT_LEN) { 321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid " 322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NONCE_MT length"); 323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->nonce_mt = apos + 2; 326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_PERMANENT_ID_REQ: 328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_PERMANENT_ID_REQ"); 329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->id_req = PERMANENT_ID; 330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_MAC: 332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_MAC"); 333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2 + EAP_SIM_MAC_LEN) { 334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_MAC " 335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length"); 336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->mac = apos + 2; 339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_NOTIFICATION: 341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2) { 342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid " 343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NOTIFICATION length %lu", 344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->notification = apos[0] * 256 + apos[1]; 348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NOTIFICATION %d", 349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->notification); 350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_ANY_ID_REQ: 352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ANY_ID_REQ"); 353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->id_req = ANY_ID; 354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_IDENTITY: 356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IDENTITY"); 357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->identity = apos + 2; 358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->identity_len = alen - 2; 359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_VERSION_LIST: 361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (aka) { 362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-AKA: " 363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "Unexpected AT_VERSION_LIST"); 364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project list_len = apos[0] * 256 + apos[1]; 367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_VERSION_LIST"); 368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (list_len < 2 || list_len > alen - 2) { 369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-SIM: Invalid " 370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_VERSION_LIST (list_len=%lu " 371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "attr_len=%lu)", 372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) list_len, 373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->version_list = apos + 2; 377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->version_list_len = list_len; 378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_SELECTED_VERSION: 380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION"); 381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2) { 382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid " 383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_SELECTED_VERSION length %lu", 384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->selected_version = apos[0] * 256 + apos[1]; 388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION " 389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "%d", attr->selected_version); 390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_FULLAUTH_ID_REQ: 392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_FULLAUTH_ID_REQ"); 393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->id_req = FULLAUTH_ID; 394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_COUNTER: 396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_COUNTER"); 399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2) { 402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid " 403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_COUNTER (alen=%lu)", 404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->counter = apos[0] * 256 + apos[1]; 408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_COUNTER %d", 409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->counter); 410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_COUNTER_TOO_SMALL: 412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_COUNTER_TOO_SMALL"); 415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2) { 418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid " 419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_COUNTER_TOO_SMALL (alen=%lu)", 420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) " 424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_COUNTER_TOO_SMALL"); 425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->counter_too_small = 1; 426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_NONCE_S: 428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NONCE_S"); 431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) " 434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NONCE_S"); 435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2 + EAP_SIM_NONCE_S_LEN) { 436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid " 437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NONCE_S (alen=%lu)", 438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->nonce_s = apos + 2; 442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_CLIENT_ERROR_CODE: 444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2) { 445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid " 446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_CLIENT_ERROR_CODE length %lu", 447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->client_error_code = apos[0] * 256 + apos[1]; 451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_CLIENT_ERROR_CODE " 452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "%d", attr->client_error_code); 453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_IV: 455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IV"); 456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != 2 + EAP_SIM_MAC_LEN) { 457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_IV " 458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length %lu", (unsigned long) alen); 459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->iv = apos + 2; 462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 463845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_ENCR_DATA: 464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ENCR_DATA"); 465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->encr_data = apos + 2; 466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->encr_data_len = alen - 2; 467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (attr->encr_data_len % 16) { 468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid " 469845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_ENCR_DATA length %lu", 470845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) 471845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->encr_data_len); 472845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 473845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 474845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 475845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_NEXT_PSEUDONYM: 476845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 477845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 478845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NEXT_PSEUDONYM"); 479845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 480845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 481845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) " 482845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NEXT_PSEUDONYM"); 483845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project plen = apos[0] * 256 + apos[1]; 484845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen > alen - 2) { 485845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid" 486845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " AT_NEXT_PSEUDONYM (actual" 487845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " len %lu, attr len %lu)", 488845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) plen, 489845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 490845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 491845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 492845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->next_pseudonym = pos + 4; 493845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->next_pseudonym_len = plen; 494845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 495845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_NEXT_REAUTH_ID: 496845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!encr) { 497845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted " 498845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NEXT_REAUTH_ID"); 499845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 500845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 501845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) " 502845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "AT_NEXT_REAUTH_ID"); 503845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project plen = apos[0] * 256 + apos[1]; 504845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (plen > alen - 2) { 505845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid" 506845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " AT_NEXT_REAUTH_ID (actual" 507845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " len %lu, attr len %lu)", 508845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) plen, 509845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 510845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 511845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 512845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->next_reauth_id = pos + 4; 513845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->next_reauth_id_len = plen; 514845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 515845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_RES: 516845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES"); 517845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project apos += 2; 518845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen -= 2; 519845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!aka || alen < EAP_AKA_MIN_RES_LEN || 520845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen > EAP_AKA_MAX_RES_LEN) { 521845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RES " 522845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(len %lu)", 523845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 524845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 525845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 526845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->res = apos; 527845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->res_len = alen; 528845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 529845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_AT_AUTS: 530845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTS"); 531845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!aka) { 532845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: " 533845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "Unexpected AT_AUTS"); 534845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 535845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 536845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (alen != EAP_AKA_AUTS_LEN) { 537845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTS" 538845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " (len %lu)", 539845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) alen); 540845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 541845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 542845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr->auts = apos; 543845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 544845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 545845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos[0] < 128) { 546845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Unrecognized " 547845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "non-skippable attribute %d", 548845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos[0]); 549845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 550845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 551845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 552845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized skippable" 553845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " attribute %d ignored", pos[0]); 554845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 555845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 556845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 557845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += pos[1] * 4; 558845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 559845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 560845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-SIM: Attributes parsed successfully " 561845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "(aka=%d encr=%d)", aka, encr); 562845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 563845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 564845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 565845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 566845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 567845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data, 568845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t encr_data_len, const u8 *iv, 569845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_sim_attrs *attr, int aka) 570845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 571845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *decrypted; 572845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 573845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (!iv) { 574845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: Encrypted data, but no IV"); 575845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 576845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 577845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 578845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project decrypted = os_malloc(encr_data_len); 579845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (decrypted == NULL) 580845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 581845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(decrypted, encr_data, encr_data_len); 582845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 583845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project aes_128_cbc_decrypt(k_encr, iv, decrypted, encr_data_len); 584845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Decrypted AT_ENCR_DATA", 585845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project decrypted, encr_data_len); 586845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 587845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sim_parse_attr(decrypted, decrypted + encr_data_len, attr, 588845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project aka, 1)) { 589845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-SIM: (encr) Failed to parse " 590845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "decrypted AT_ENCR_DATA"); 591845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(decrypted); 592845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 593845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 594845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 595845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return decrypted; 596845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 597845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 598845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 599845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define EAP_SIM_INIT_LEN 128 600845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 601845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_sim_msg { 602845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *buf; 603845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t buf_len, used; 604845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t mac, iv, encr; /* index from buf */ 605845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 606845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 607845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 608845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype) 609845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 610845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_sim_msg *msg; 611845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *eap; 612845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 613845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 614845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg = os_zalloc(sizeof(*msg)); 615845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL) 616845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 617845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 618845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf = os_zalloc(EAP_SIM_INIT_LEN); 619845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg->buf == NULL) { 620845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(msg); 621845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 622845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 623845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf_len = EAP_SIM_INIT_LEN; 624845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap = (struct eap_hdr *) msg->buf; 625845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->code = code; 626845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->identifier = id; 627845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->used = sizeof(*eap); 628845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 629845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = (u8 *) (eap + 1); 630845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = type; 631845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = subtype; 632845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = 0; /* Reserved */ 633845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = 0; /* Reserved */ 634845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->used += 4; 635845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 636845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return msg; 637845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 638845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 639845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 640845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sim_msg_finish(struct eap_sim_msg *msg, size_t *len, const u8 *k_aut, 641845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *extra, size_t extra_len) 642845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 643845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *eap; 644845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *buf; 645845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 646845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL) 647845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 648845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 649845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap = (struct eap_hdr *) msg->buf; 650845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->length = host_to_be16(msg->used); 651845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 652845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (k_aut && msg->mac) { 653845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_sim_add_mac(k_aut, msg->buf, msg->used, 654845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf + msg->mac, extra, extra_len); 655845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 656845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 657845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = msg->used; 658845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf = msg->buf; 659845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(msg); 660845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return buf; 661845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 662845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 663845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 664845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sim_msg_free(struct eap_sim_msg *msg) 665845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 666845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg) { 667845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(msg->buf); 668845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(msg); 669845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 670845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 671845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 672845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 673845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_sim_msg_resize(struct eap_sim_msg *msg, size_t add_len) 674845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 675845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg->used + add_len > msg->buf_len) { 676845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *nbuf = os_realloc(msg->buf, msg->used + add_len); 677845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (nbuf == NULL) 678845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 679845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf = nbuf; 680845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf_len = msg->used + add_len; 681845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 682845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 683845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 684845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 685845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 686845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr, 687845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *data, size_t len) 688845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 689845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int attr_len = 2 + len; 690845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int pad_len; 691845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *start, *pos; 692845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 693845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL) 694845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 695845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 696845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pad_len = (4 - attr_len % 4) % 4; 697845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr_len += pad_len; 698845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sim_msg_resize(msg, attr_len)) 699845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 700845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project start = pos = msg->buf + msg->used; 701845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = attr; 702845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = attr_len / 4; 703845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, data, len); 704845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pad_len) { 705845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += len; 706845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(pos, 0, pad_len); 707845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 708845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->used += attr_len; 709845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return start; 710845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 711845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 712845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 713845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sim_msg_add(struct eap_sim_msg *msg, u8 attr, u16 value, 714845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *data, size_t len) 715845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 716845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int attr_len = 4 + len; 717845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int pad_len; 718845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *start, *pos; 719845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 720845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL) 721845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 722845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 723845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pad_len = (4 - attr_len % 4) % 4; 724845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project attr_len += pad_len; 725845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_sim_msg_resize(msg, attr_len)) 726845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 727845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project start = pos = msg->buf + msg->used; 728845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = attr; 729845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *pos++ = attr_len / 4; 730845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(pos, value); 731845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 2; 732845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data) 733845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, data, len); 734845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pad_len) { 735845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += len; 736845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(pos, 0, pad_len); 737845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 738845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->used += attr_len; 739845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return start; 740845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 741845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 742845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 743845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectu8 * eap_sim_msg_add_mac(struct eap_sim_msg *msg, u8 attr) 744845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 745845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos = eap_sim_msg_add(msg, attr, 0, NULL, EAP_SIM_MAC_LEN); 746845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos) 747845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->mac = (pos - msg->buf) + 4; 748845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 749845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 750845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 751845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 752845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv, 753845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 attr_encr) 754845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 755845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN); 756845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 757845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 758845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->iv = (pos - msg->buf) + 4; 759845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (hostapd_get_rand(msg->buf + msg->iv, EAP_SIM_IV_LEN)) { 760845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->iv = 0; 761845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 762845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 763845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 764845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_sim_msg_add(msg, attr_encr, 0, NULL, 0); 765845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) { 766845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->iv = 0; 767845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 768845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 769845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->encr = pos - msg->buf; 770845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 771845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 772845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 773845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 774845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 775845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr, int attr_pad) 776845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 777845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t encr_len; 778845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 779845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (msg == NULL || k_encr == NULL || msg->iv == 0 || msg->encr == 0) 780845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 781845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 782845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project encr_len = msg->used - msg->encr - 4; 783845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (encr_len % 16) { 784845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *pos; 785845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int pad_len = 16 - (encr_len % 16); 786845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pad_len < 4) { 787845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-SIM: " 788845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "eap_sim_msg_add_encr_end - invalid pad_len" 789845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project " %d", pad_len); 790845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 791845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 792845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, " *AT_PADDING"); 793845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_sim_msg_add(msg, attr_pad, 0, NULL, pad_len - 4); 794845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 795845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 796845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(pos + 4, 0, pad_len - 4); 797845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project encr_len += pad_len; 798845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 799845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, " (AT_ENCR_DATA data len %lu)", 800845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) encr_len); 801845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf[msg->encr + 1] = encr_len / 4 + 1; 802845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project aes_128_cbc_encrypt(k_encr, msg->buf + msg->iv, 803845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg->buf + msg->encr + 4, encr_len); 804845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 805845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 806845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 807845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 808845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 809845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eap_sim_report_notification(void *msg_ctx, int notification, int aka) 810845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 811845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef CONFIG_NO_STDOUT_DEBUG 812845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const char *type = aka ? "AKA" : "SIM"; 813845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_NO_STDOUT_DEBUG */ 814845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 815845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (notification) { 816845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_GENERAL_FAILURE_AFTER_AUTH: 817845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-%s: General failure " 818845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "notification (after authentication)", type); 819845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 820845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_TEMPORARILY_DENIED: 821845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: " 822845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "User has been temporarily denied access to the " 823845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "requested service", type); 824845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 825845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_NOT_SUBSCRIBED: 826845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: " 827845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "User has not subscribed to the requested service", 828845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project type); 829845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 830845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH: 831845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-%s: General failure " 832845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "notification (before authentication)", type); 833845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 834845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_SIM_SUCCESS: 835845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-%s: Successful authentication " 836845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "notification", type); 837845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 838845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 839845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (notification >= 32768) { 840845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-%s: Unrecognized " 841845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "non-failure notification %d", 842845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project type, notification); 843845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else { 844845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-%s: Unrecognized " 845845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "failure notification %d", 846845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project type, notification); 847845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 848845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 849845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 850