1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP peer method: EAP-PSK (RFC 4764) 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2004-2007, 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 * Note: EAP-PSK is an EAP authentication method and as such, completely 15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * different from WPA-PSK. This file is not needed for WPA-PSK functionality. 16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */ 17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h" 19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h" 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_i.h" 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "config_ssid.h" 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "md5.h" 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "aes_wrap.h" 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_psk_common.h" 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_psk_data { 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project enum { PSK_INIT, PSK_MAC_SENT, PSK_DONE } state; 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 rand_p[EAP_PSK_RAND_LEN]; 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN]; 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *id_s, *id_p; 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t id_s_len, id_p_len; 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 msk[EAP_MSK_LEN]; 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 emsk[EAP_EMSK_LEN]; 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void * eap_psk_init(struct eap_sm *sm) 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data; 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL || !config->eappsk) { 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: pre-shared key not configured"); 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data = os_zalloc(sizeof(*data)); 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data == NULL) 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_psk_key_setup(config->eappsk, data->ak, data->kdk); 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN); 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN); 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->state = PSK_INIT; 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->nai) { 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_p = os_malloc(config->nai_len); 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_p) 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->id_p, config->nai, config->nai_len); 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_p_len = config->nai_len; 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_p == NULL) { 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: could not get own identity"); 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data); 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return data; 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_psk_deinit(struct eap_sm *sm, void *priv) 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data = priv; 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_s); 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_p); 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data); 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_psk_process_1(struct eap_psk_data *data, 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_psk_hdr_1 *hdr1; 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_hdr_2 *hdr2; 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp, *buf, *pos; 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t buflen; 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: in INIT state"); 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr1 = (const struct eap_psk_hdr_1 *) reqData; 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (reqDataLen < sizeof(*hdr1) || 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project be_to_host16(hdr1->length) < sizeof(*hdr1) || 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project be_to_host16(hdr1->length) > reqDataLen) { 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Invalid first message " 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length (%lu %d; expected %lu or more)", 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) reqDataLen, 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project be_to_host16(hdr1->length), 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) sizeof(*hdr1)); 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr1->flags); 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (EAP_PSK_FLAGS_GET_T(hdr1->flags) != 0) { 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 0)", 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_FLAGS_GET_T(hdr1->flags)); 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s, 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_RAND_LEN); 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_s); 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_s_len = be_to_host16(hdr1->length) - sizeof(*hdr1); 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_s = os_malloc(data->id_s_len); 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_s == NULL) { 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory for " 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "ID_S (len=%lu)", (unsigned long) data->id_s_len); 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->id_s, (u8 *) (hdr1 + 1), data->id_s_len); 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S", 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_s, data->id_s_len); 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (hostapd_get_rand(data->rand_p, EAP_PSK_RAND_LEN)) { 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data"); 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *respDataLen = sizeof(*hdr2) + data->id_p_len; 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*respDataLen); 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2 = (struct eap_psk_hdr_2 *) resp; 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2->code = EAP_CODE_RESPONSE; 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2->identifier = hdr1->identifier; 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2->length = host_to_be16(*respDataLen); 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2->type = EAP_TYPE_PSK; 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr2->flags = EAP_PSK_FLAGS_SET_T(1); /* T=1 */ 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(hdr2->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN); 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(hdr2->rand_p, data->rand_p, EAP_PSK_RAND_LEN); 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy((u8 *) (hdr2 + 1), data->id_p, data->id_p_len); 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */ 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN; 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf = os_malloc(buflen); 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (buf == NULL) { 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(resp); 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(buf, data->id_p, data->id_p_len); 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = buf + data->id_p_len; 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, data->id_s, data->id_s_len); 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += data->id_s_len; 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, hdr1->rand_s, EAP_PSK_RAND_LEN); 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_PSK_RAND_LEN; 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN); 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project omac1_aes_128(data->ak, buf, buflen, hdr2->mac_p); 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(buf); 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_P", hdr2->rand_p, 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_RAND_LEN); 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", hdr2->mac_p, EAP_PSK_MAC_LEN); 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_P", 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (u8 *) (hdr2 + 1), data->id_p_len); 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->state = PSK_MAC_SENT; 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return resp; 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_psk_process_3(struct eap_psk_data *data, 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_psk_hdr_3 *hdr3; 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_hdr_4 *hdr4; 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp, *buf, *rpchannel, nonce[16], *decrypted; 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pchannel, *tag, *msg; 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 mac[EAP_PSK_MAC_LEN]; 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t buflen, left, data_len; 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int failed = 0; 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: in MAC_SENT state"); 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr3 = (const struct eap_psk_hdr_3 *) reqData; 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project left = be_to_host16(hdr3->length); 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (left < sizeof(*hdr3) || reqDataLen < left) { 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Invalid third message " 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length (%lu %d; expected %lu)", 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) reqDataLen, 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project be_to_host16(hdr3->length), 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) sizeof(*hdr3)); 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project left -= sizeof(*hdr3); 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pchannel = (const u8 *) (hdr3 + 1); 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr3->flags); 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (EAP_PSK_FLAGS_GET_T(hdr3->flags) != 2) { 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 2)", 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_FLAGS_GET_T(hdr3->flags)); 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr3->rand_s, 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_RAND_LEN); 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_S", hdr3->mac_s, EAP_PSK_MAC_LEN); 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL", pchannel, left); 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (left < 4 + 16 + 1) { 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in " 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "third message (len=%lu, expected 21)", 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (unsigned long) left); 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */ 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buflen = data->id_s_len + EAP_PSK_RAND_LEN; 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project buf = os_malloc(buflen); 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (buf == NULL) 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(buf, data->id_s, data->id_s_len); 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN); 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project omac1_aes_128(data->ak, buf, buflen, mac); 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(buf); 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) { 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third " 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "message"); 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: MAC_S verified successfully"); 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, 244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->msk, data->emsk); 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN); 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN); 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN); 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memset(nonce, 0, 12); 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(nonce + 12, pchannel, 4); 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pchannel += 4; 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project left -= 4; 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project tag = pchannel; 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pchannel += 16; 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project left -= 16; 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project msg = pchannel; 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - nonce", 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project nonce, sizeof(nonce)); 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr", reqData, 5); 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - cipher msg", msg, left); 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project decrypted = os_malloc(left); 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (decrypted == NULL) { 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(decrypted, msg, left); 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce), 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqData, 22, decrypted, left, tag)) { 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed"); 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(decrypted); 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message", 280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project decrypted, left); 281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* Verify R flag */ 283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (decrypted[0] >> 6) { 284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_PSK_R_FLAG_CONT: 285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported"); 286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project failed = 1; 287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_PSK_R_FLAG_DONE_SUCCESS: 289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS"); 290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_PSK_R_FLAG_DONE_FAILURE: 292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE"); 293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-PSK: Authentication server rejected " 294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "authentication"); 295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project failed = 1; 296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *respDataLen = sizeof(*hdr4) + 4 + 16 + 1; 300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = os_malloc(*respDataLen + 1); 301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) { 302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(decrypted); 303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4 = (struct eap_psk_hdr_4 *) resp; 306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->code = EAP_CODE_RESPONSE; 307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->identifier = hdr3->identifier; 308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->length = host_to_be16(*respDataLen); 309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->type = EAP_TYPE_PSK; 310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->flags = EAP_PSK_FLAGS_SET_T(3); /* T=3 */ 311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(hdr4->rand_s, hdr3->rand_s, EAP_PSK_RAND_LEN); 312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel = (u8 *) (hdr4 + 1); 313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* nonce++ */ 315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project inc_byte_array(nonce, sizeof(nonce)); 316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpchannel, nonce + 12, 4); 317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data_len = 1; 319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (decrypted[0] & EAP_PSK_E_FLAG) { 320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: Unsupported E (Ext) flag"); 321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project failed = 1; 322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel[4 + 16] = (EAP_PSK_R_FLAG_DONE_FAILURE << 6) | 323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_PSK_E_FLAG; 324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (left > 1) { 325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* Add empty EXT_Payload with same EXT_Type */ 326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project (*respDataLen)++; 327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project hdr4->length = host_to_be16(*respDataLen); 328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel[4 + 16 + 1] = decrypted[1]; 329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data_len++; 330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } else if (failed) 332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_FAILURE << 6; 333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project else 334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6; 335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (plaintext)", 337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel + 4 + 16, data_len); 338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), resp, 22, 339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel + 4 + 16, data_len, rpchannel + 4); 340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (PCHANNEL)", 341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpchannel, 4 + 16 + data_len); 342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: Completed %ssuccessfully", 344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project failed ? "un" : ""); 345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->state = PSK_DONE; 346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = failed ? DECISION_FAIL : DECISION_UNCOND_SUCC; 348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(decrypted); 350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return resp; 352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_psk_process(struct eap_sm *sm, void *priv, 356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data = priv; 361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos; 362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp = NULL; 363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len; 364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, 366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqData, reqDataLen, &len); 367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) { 368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len += sizeof(struct eap_hdr) + 1; 372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = FALSE; 374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_MAY_CONT; 375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->allowNotifications = TRUE; 377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (data->state) { 379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case PSK_INIT: 380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_psk_process_1(data, ret, reqData, len, 381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project respDataLen); 382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case PSK_MAC_SENT: 384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_psk_process_3(data, ret, reqData, len, 385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project respDataLen); 386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case PSK_DONE: 388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-PSK: in DONE state - ignore " 389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "unexpected message"); 390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ret->methodState == METHOD_DONE) { 395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->allowNotifications = FALSE; 396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return resp; 399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic Boolean eap_psk_isKeyAvailable(struct eap_sm *sm, void *priv) 403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data = priv; 405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return data->state == PSK_DONE; 406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len) 410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data = priv; 412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *key; 413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != PSK_DONE) 415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key = os_malloc(EAP_MSK_LEN); 418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (key == NULL) 419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = EAP_MSK_LEN; 422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(key, data->msk, EAP_MSK_LEN); 423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return key; 425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_psk_data *data = priv; 431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *key; 432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != PSK_DONE) 434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key = os_malloc(EAP_EMSK_LEN); 437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (key == NULL) 438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = EAP_EMSK_LEN; 441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(key, data->emsk, EAP_EMSK_LEN); 442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return key; 444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_peer_psk_register(void) 448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method *eap; 450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int ret; 451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK"); 454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap == NULL) 455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->init = eap_psk_init; 458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->deinit = eap_psk_deinit; 459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->process = eap_psk_process; 460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->isKeyAvailable = eap_psk_isKeyAvailable; 461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->getKey = eap_psk_getKey; 462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->get_emsk = eap_psk_get_emsk; 463845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret = eap_peer_method_register(eap); 465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ret) 466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_peer_method_free(eap); 467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return ret; 468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 469