1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* 2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt) 3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2006-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 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 "config_ssid.h" 20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eap_gpsk_common.h" 21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eap_gpsk_data { 23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project enum { GPSK_1, GPSK_3, SUCCESS, FAILURE } state; 24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 rand_server[EAP_GPSK_RAND_LEN]; 25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 rand_peer[EAP_GPSK_RAND_LEN]; 26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 msk[EAP_MSK_LEN]; 27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 emsk[EAP_EMSK_LEN]; 28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 sk[EAP_GPSK_MAX_SK_LEN]; 29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t sk_len; 30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 pk[EAP_GPSK_MAX_PK_LEN]; 31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t pk_len; 32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 session_id; 33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int session_id_set; 34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *id_peer; 35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t id_peer_len; 36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *id_server; 37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t id_server_len; 38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int vendor; /* CSuite/Specifier */ 39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int specifier; /* CSuite/Specifier */ 40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *psk; 41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t psk_len; 42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}; 43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier, 46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *csuite_list, size_t csuite_list_len, 47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen); 48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier, 49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen); 50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef CONFIG_NO_STDOUT_DEBUG 53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const char * eap_gpsk_state_txt(int state) 54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (state) { 56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case GPSK_1: 57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "GPSK-1"; 58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case GPSK_3: 59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "GPSK-3"; 60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case SUCCESS: 61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "SUCCESS"; 62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case FAILURE: 63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "FAILURE"; 64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return "?"; 66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* CONFIG_NO_STDOUT_DEBUG */ 69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_gpsk_state(struct eap_gpsk_data *data, int state) 72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: %s -> %s", 74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state_txt(data->state), 75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state_txt(state)); 76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->state = state; 77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_gpsk_deinit(struct eap_sm *sm, void *priv); 81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void * eap_gpsk_init(struct eap_sm *sm) 84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct wpa_ssid *config = eap_get_config(sm); 86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data; 87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config == NULL) { 89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-GPSK: No configuration found"); 90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->eappsk == NULL) { 94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-GPSK: No key (eappsk) configured"); 95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data = os_zalloc(sizeof(*data)); 99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data == NULL) 100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->state = GPSK_1; 102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (config->nai) { 104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_peer = os_malloc(config->nai_len); 105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_peer == NULL) { 106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_deinit(sm, data); 107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->id_peer, config->nai, config->nai_len); 110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_peer_len = config->nai_len; 111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->psk = os_malloc(config->eappsk_len); 114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->psk == NULL) { 115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_deinit(sm, data); 116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->psk, config->eappsk, config->eappsk_len); 119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->psk_len = config->eappsk_len; 120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return data; 122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eap_gpsk_deinit(struct eap_sm *sm, void *priv) 126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data = priv; 128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_server); 129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_peer); 130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->psk); 131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data); 132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_process_id_server(struct eap_gpsk_data *data, 136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u16 alen; 139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < 2) { 141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet"); 142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen = WPA_GET_BE16(pos); 145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 2; 146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < alen) { 147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: ID_Server overflow"); 148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(data->id_server); 151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_server = os_malloc(alen); 152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_server == NULL) { 153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: No memory for ID_Server"); 154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->id_server, pos, alen); 157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_server_len = alen; 158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server", 159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_server, data->id_server_len); 160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += alen; 161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_process_rand_server(struct eap_gpsk_data *data, 167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < EAP_GPSK_RAND_LEN) { 173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server overflow"); 174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(data->rand_server, pos, EAP_GPSK_RAND_LEN); 177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server", 178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->rand_server, EAP_GPSK_RAND_LEN); 179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_GPSK_RAND_LEN; 180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eap_gpsk_select_csuite(struct eap_sm *sm, 186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data, 187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *csuite_list, 188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t csuite_list_len) 189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_csuite *csuite; 191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int i, count; 192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project count = csuite_list_len / sizeof(struct eap_gpsk_csuite); 194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->vendor = EAP_GPSK_VENDOR_IETF; 195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier = EAP_GPSK_CIPHER_RESERVED; 196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project csuite = (struct eap_gpsk_csuite *) csuite_list; 197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project for (i = 0; i < count; i++) { 198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int vendor, specifier; 199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project vendor = WPA_GET_BE32(csuite->vendor); 200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project specifier = WPA_GET_BE16(csuite->specifier); 201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite[%d]: %d:%d", 202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project i, vendor, specifier); 203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->vendor == EAP_GPSK_VENDOR_IETF && 204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier == EAP_GPSK_CIPHER_RESERVED && 205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_supported_ciphersuite(vendor, specifier)) { 206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->vendor = vendor; 207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier = specifier; 208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project csuite++; 210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->vendor == EAP_GPSK_VENDOR_IETF && 212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier == EAP_GPSK_CIPHER_RESERVED) { 213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_msg(sm->msg_ctx, MSG_INFO, "EAP-GPSK: No supported " 214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "ciphersuite found"); 215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Selected ciphersuite %d:%d", 218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->vendor, data->specifier); 219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return 0; 221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm, 225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data, 226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 **list, size_t *list_len, 227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < 2) { 233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet"); 234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *list_len = WPA_GET_BE16(pos); 237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 2; 238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < (int) *list_len) { 239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List overflow"); 240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (*list_len == 0 || (*list_len % sizeof(struct eap_gpsk_csuite))) { 243dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %lu", 244dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt (unsigned long) *list_len); 245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *list = pos; 248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += *list_len; 249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_gpsk_select_csuite(sm, data, *list, *list_len) < 0) 251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm, 258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data, 259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *payload, size_t payload_len, 262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t csuite_list_len; 265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *csuite_list, *pos, *end; 266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *req; 267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp; 268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != GPSK_1) { 270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-1"); 275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project end = payload + payload_len; 277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_process_id_server(data, payload, end); 279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_process_rand_server(data, pos, end); 280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_process_csuite_list(sm, data, &csuite_list, 281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project &csuite_list_len, pos, end); 282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) { 283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project req = (const struct eap_hdr *) reqData; 288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_gpsk_send_gpsk_2(data, req->identifier, 289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project csuite_list, csuite_list_len, 290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project respDataLen); 291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, GPSK_3); 295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier, 301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *csuite_list, size_t csuite_list_len, 302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len, miclen; 306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *rpos, *start; 307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_csuite *csuite; 308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-2"); 310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project miclen = eap_gpsk_mic_len(data->vendor, data->specifier); 312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = 1 + 2 + data->id_peer_len + 2 + data->id_server_len + 313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 2 * EAP_GPSK_RAND_LEN + 2 + csuite_list_len + 314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project sizeof(struct eap_gpsk_csuite) + 2 + miclen; 315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len, 317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_CODE_RESPONSE, identifier, &rpos); 318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *rpos++ = EAP_GPSK_OPCODE_GPSK_2; 322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project start = rpos; 323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer", 325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_peer, data->id_peer_len); 326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(rpos, data->id_peer_len); 327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += 2; 328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_peer) 329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpos, data->id_peer, data->id_peer_len); 330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += data->id_peer_len; 331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(rpos, data->id_server_len); 333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += 2; 334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->id_server) 335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpos, data->id_server, data->id_server_len); 336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += data->id_server_len; 337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (os_get_random(data->rand_peer, EAP_GPSK_RAND_LEN)) { 339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to get random data " 340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "for RAND_Peer"); 341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(resp); 343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer", 346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->rand_peer, EAP_GPSK_RAND_LEN); 347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpos, data->rand_peer, EAP_GPSK_RAND_LEN); 348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += EAP_GPSK_RAND_LEN; 349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpos, data->rand_server, EAP_GPSK_RAND_LEN); 351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += EAP_GPSK_RAND_LEN; 352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(rpos, csuite_list_len); 354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += 2; 355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(rpos, csuite_list, csuite_list_len); 356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += csuite_list_len; 357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project csuite = (struct eap_gpsk_csuite *) rpos; 359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE32(csuite->vendor, data->vendor); 360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(csuite->specifier, data->specifier); 361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos = (u8 *) (csuite + 1); 362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_gpsk_derive_keys(data->psk, data->psk_len, 364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->vendor, data->specifier, 365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->rand_peer, data->rand_server, 366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_peer, data->id_peer_len, 367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_server, data->id_server_len, 368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->msk, data->emsk, 369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->sk, &data->sk_len, 370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->pk, &data->pk_len) < 0) { 371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys"); 372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(resp); 374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* No PD_Payload_1 */ 378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(rpos, 0); 379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += 2; 380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, 382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier, start, rpos - start, rpos) < 383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0) { 384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(resp); 386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_validate_rand(struct eap_gpsk_data *data, const u8 *pos, 394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *end) 395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < EAP_GPSK_RAND_LEN) { 397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "RAND_Peer"); 399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (os_memcmp(pos, data->rand_peer, EAP_GPSK_RAND_LEN) != 0) { 402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2 and " 403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "GPSK-3 did not match"); 404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2", 405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->rand_peer, EAP_GPSK_RAND_LEN); 406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-3", 407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, EAP_GPSK_RAND_LEN); 408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_GPSK_RAND_LEN; 411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < EAP_GPSK_RAND_LEN) { 413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "RAND_Server"); 415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (os_memcmp(pos, data->rand_server, EAP_GPSK_RAND_LEN) != 0) { 418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and " 419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "GPSK-3 did not match"); 420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1", 421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->rand_server, EAP_GPSK_RAND_LEN); 422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-3", 423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, EAP_GPSK_RAND_LEN); 424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += EAP_GPSK_RAND_LEN; 427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data, 433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len; 436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < (int) 2) { 441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "length(ID_Server)"); 443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = WPA_GET_BE16(pos); 447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 2; 448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < (int) len) { 450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "ID_Server"); 452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (len != data->id_server_len || 456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcmp(pos, data->id_server, len) != 0) { 457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-GPSK: ID_Server did not match with " 458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "the one used in GPSK-1"); 459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1", 460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->id_server, data->id_server_len); 461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3", 462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos, len); 463dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt return NULL; 464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += len; 467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 469845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 470845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 471845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 472845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data, const u8 *pos, 473845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *end) 474845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 475845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int vendor, specifier; 476845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_gpsk_csuite *csuite; 477845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 478845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 479845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 480845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 481845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < (int) sizeof(*csuite)) { 482845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 483845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "CSuite_Sel"); 484845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 485845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 486845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project csuite = (const struct eap_gpsk_csuite *) pos; 487845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project vendor = WPA_GET_BE32(csuite->vendor); 488845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project specifier = WPA_GET_BE16(csuite->specifier); 489845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += sizeof(*csuite); 490845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (vendor != data->vendor || specifier != data->specifier) { 491845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel (%d:%d) does not " 492845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "match with the one sent in GPSK-2 (%d:%d)", 493845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project vendor, specifier, data->vendor, data->specifier); 494845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 495845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 496845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 497845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 498845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 499845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 500845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 501845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_validate_pd_payload_2(struct eap_gpsk_data *data, 502845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 503845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 504845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u16 alen; 505845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 506845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 507845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 508845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 509845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < 2) { 510845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 511845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "PD_Payload_2 length"); 512845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 513845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 514845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project alen = WPA_GET_BE16(pos); 515845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += 2; 516845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < alen) { 517845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " 518845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "%d-octet PD_Payload_2", alen); 519845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 520845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 521845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_2", pos, alen); 522845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += alen; 523845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 524845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 525845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 526845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 527845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 528845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectconst u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data, 529845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *payload, 530845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, const u8 *end) 531845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 532845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t miclen; 533845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 mic[EAP_GPSK_MAX_MIC_LEN]; 534845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 535845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) 536845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 537845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 538845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project miclen = eap_gpsk_mic_len(data->vendor, data->specifier); 539845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (end - pos < (int) miclen) { 540845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC " 541dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt "(left=%lu miclen=%lu)", 542dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt (unsigned long) (end - pos), 543dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt (unsigned long) miclen); 544845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 545845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 546845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, 547845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier, payload, pos - payload, mic) 548845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project < 0) { 549845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC"); 550845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 551845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 552845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (os_memcmp(mic, pos, miclen) != 0) { 553845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-3"); 554845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen); 555845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen); 556845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 557845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 558845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos += miclen; 559845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 560845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return pos; 561845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 562845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 563845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 564845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm, 565845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data, 566845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 567845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 568845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *payload, size_t payload_len, 569845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 570845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 571845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp; 572845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const struct eap_hdr *req; 573845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos, *end; 574845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 575845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != GPSK_3) { 576845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 577845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 578845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 579845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 580845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-3"); 581845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 582845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project end = payload + payload_len; 583845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 584845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_validate_rand(data, payload, end); 585845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_validate_id_server(data, pos, end); 586845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_validate_csuite(data, pos, end); 587845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_validate_pd_payload_2(data, pos, end); 588845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_gpsk_validate_gpsk_3_mic(data, payload, pos, end); 589845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 590845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL) { 591845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 592845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 593845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 594845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos != end) { 595dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra " 596dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt "data in the end of GPSK-2", 597dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt (unsigned long) (end - pos)); 598845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 599845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 600845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project req = (const struct eap_hdr *) reqData; 601845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_gpsk_send_gpsk_4(data, req->identifier, respDataLen); 602845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 603845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 604845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 605845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, SUCCESS); 606845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_DONE; 607845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_UNCOND_SUCC; 608845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 609845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 610845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 611845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 612845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 613845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier, 614845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 615845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 616845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_hdr *resp; 617845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *rpos, *start; 618845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len; 619845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 620845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4"); 621845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 622845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project len = 1 + 2 + eap_gpsk_mic_len(data->vendor, data->specifier); 623845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 624845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len, 625845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_CODE_RESPONSE, identifier, &rpos); 626845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (resp == NULL) 627845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 628845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 629845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *rpos++ = EAP_GPSK_OPCODE_GPSK_4; 630845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project start = rpos; 631845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 632845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project /* No PD_Payload_3 */ 633845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project WPA_PUT_BE16(rpos, 0); 634845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project rpos += 2; 635845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 636845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, 637845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project data->specifier, start, rpos - start, rpos) < 638845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 0) { 639845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_gpsk_state(data, FAILURE); 640845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_free(resp); 641845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 642845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 643845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 644845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return (u8 *) resp; 645845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 646845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 647845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 648845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_process(struct eap_sm *sm, void *priv, 649845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method_ret *ret, 650845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *reqData, size_t reqDataLen, 651845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t *respDataLen) 652845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 653845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data = priv; 654845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *resp; 655845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project const u8 *pos; 656845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project size_t len; 657845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 658845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, 659845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqData, reqDataLen, &len); 660845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (pos == NULL || len < 1) { 661845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 662845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 663845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 664845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 665845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", *pos); 666845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 667845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = FALSE; 668845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->methodState = METHOD_MAY_CONT; 669845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->decision = DECISION_FAIL; 670845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->allowNotifications = FALSE; 671845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 672845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project switch (*pos) { 673845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_GPSK_OPCODE_GPSK_1: 674845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_gpsk_process_gpsk_1(sm, data, ret, reqData, 675845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqDataLen, pos + 1, len - 1, 676845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project respDataLen); 677845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 678845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project case EAP_GPSK_OPCODE_GPSK_3: 679845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project resp = eap_gpsk_process_gpsk_3(sm, data, ret, reqData, 680845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project reqDataLen, pos + 1, len - 1, 681845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project respDataLen); 682845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project break; 683845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project default: 684845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignoring message with " 685845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project "unknown opcode %d", *pos); 686845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret->ignore = TRUE; 687845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 688845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project } 689845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 690845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return resp; 691845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 692845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 693845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 694845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic Boolean eap_gpsk_isKeyAvailable(struct eap_sm *sm, void *priv) 695845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 696845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data = priv; 697845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return data->state == SUCCESS; 698845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 699845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 700845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 701845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_getKey(struct eap_sm *sm, void *priv, size_t *len) 702845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 703845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data = priv; 704845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *key; 705845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 706845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != SUCCESS) 707845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 708845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 709845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key = os_malloc(EAP_MSK_LEN); 710845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (key == NULL) 711845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 712845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(key, data->msk, EAP_MSK_LEN); 713845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = EAP_MSK_LEN; 714845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 715845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return key; 716845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 717845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 718845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 719845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 * eap_gpsk_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 720845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 721845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_gpsk_data *data = priv; 722845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project u8 *key; 723845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 724845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (data->state != SUCCESS) 725845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 726845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 727845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project key = os_malloc(EAP_EMSK_LEN); 728845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (key == NULL) 729845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return NULL; 730845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project os_memcpy(key, data->emsk, EAP_EMSK_LEN); 731845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *len = EAP_EMSK_LEN; 732845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 733845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return key; 734845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 735845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 736845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 737845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eap_peer_gpsk_register(void) 738845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{ 739845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project struct eap_method *eap; 740845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project int ret; 741845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 742845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 743845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project EAP_VENDOR_IETF, EAP_TYPE_GPSK, "GPSK"); 744845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (eap == NULL) 745845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return -1; 746845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 747845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->init = eap_gpsk_init; 748845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->deinit = eap_gpsk_deinit; 749845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->process = eap_gpsk_process; 750845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->isKeyAvailable = eap_gpsk_isKeyAvailable; 751845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->getKey = eap_gpsk_getKey; 752845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap->get_emsk = eap_gpsk_get_emsk; 753845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project 754845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project ret = eap_peer_method_register(eap); 755845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project if (ret) 756845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project eap_peer_method_free(eap); 757845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project return ret; 758845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} 759