eap_ikev2.c revision c28170251eb54dbf64a9074a07fee377587425b2
1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com/* 2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * EAP-IKEv2 peer (RFC 5106) 3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * Copyright (c) 2007-2014, Jouni Malinen <j@w1.fi> 4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * 5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * This software may be distributed under the terms of the BSD license. 6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org * See README for more details. 7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org */ 8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "includes.h" 10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "common.h" 12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "eap_i.h" 13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "eap_common/eap_ikev2_common.h" 14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "ikev2.h" 15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstruct eap_ikev2_data { 18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct ikev2_responder_data ikev2; 19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org enum { WAIT_START, PROC_MSG, WAIT_FRAG_ACK, DONE, FAIL } state; 20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct wpabuf *in_buf; 21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct wpabuf *out_buf; 22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org size_t out_used; 23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org size_t fragment_size; 24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int keys_ready; 25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org u8 keymat[EAP_MSK_LEN + EAP_EMSK_LEN]; 26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int keymat_ok; 27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}; 28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic const char * eap_ikev2_state_txt(int state) 31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org switch (state) { 331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org case WAIT_START: 34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return "WAIT_START"; 35fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org case PROC_MSG: 36c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org return "PROC_MSG"; 377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org case WAIT_FRAG_ACK: 38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return "WAIT_FRAG_ACK"; 39ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org case DONE: 40ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org return "DONE"; 41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case FAIL: 42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return "FAIL"; 43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return "?"; 45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic void eap_ikev2_state(struct eap_ikev2_data *data, int state) 50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 51a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: %s -> %s", 52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org eap_ikev2_state_txt(data->state), 53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org eap_ikev2_state_txt(state)); 54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->state = state; 55a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 57dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org 58837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.orgstatic void * eap_ikev2_init(struct eap_sm *sm) 5933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org{ 60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct eap_ikev2_data *data; 61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const u8 *identity, *password; 62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org size_t identity_len, password_len; 63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org int fragment_size; 64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org identity = eap_get_config_identity(sm, &identity_len); 6631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (identity == NULL) { 67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_INFO, "EAP-IKEV2: No identity available"); 68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 6994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data = os_zalloc(sizeof(*data)); 72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data == NULL) 73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org data->state = WAIT_START; 75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org fragment_size = eap_get_config_fragment_size(sm); 76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (fragment_size <= 0) 77876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org data->fragment_size = IKEV2_FRAGMENT_SIZE; 784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org else 79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->fragment_size = fragment_size; 80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->ikev2.state = SA_INIT; 81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->ikev2.peer_auth = PEER_AUTH_SECRET; 82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->ikev2.key_pad = (u8 *) os_strdup("Key Pad for EAP-IKEv2"); 83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->ikev2.key_pad == NULL) 84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org goto failed; 85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->ikev2.key_pad_len = 21; 864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org data->ikev2.IDr = os_malloc(identity_len); 87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->ikev2.IDr == NULL) 88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org goto failed; 89594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org os_memcpy(data->ikev2.IDr, identity, identity_len); 90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->ikev2.IDr_len = identity_len; 91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org password = eap_get_config_password(sm, &password_len); 93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (password) { 941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org data->ikev2.shared_secret = os_malloc(password_len); 95c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (data->ikev2.shared_secret == NULL) 96c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org goto failed; 97c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org os_memcpy(data->ikev2.shared_secret, password, password_len); 984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org data->ikev2.shared_secret_len = password_len; 99e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 100c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org 1014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return data; 1024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgfailed: 104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ikev2_responder_deinit(&data->ikev2); 10583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org os_free(data); 106c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org return NULL; 1074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 10856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic void eap_ikev2_deinit(struct eap_sm *sm, void *priv) 11146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org{ 1127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org struct eap_ikev2_data *data = priv; 113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpabuf_free(data->in_buf); 114d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org wpabuf_free(data->out_buf); 115c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ikev2_responder_deinit(&data->ikev2); 116c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org bin_clear_free(data, sizeof(*data)); 117c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org} 118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 11949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic int eap_ikev2_peer_keymat(struct eap_ikev2_data *data) 121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (eap_ikev2_derive_keymat( 1234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org data->ikev2.proposal.prf, &data->ikev2.keys, 1244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org data->ikev2.i_nonce, data->ikev2.i_nonce_len, 1252bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org data->ikev2.r_nonce, data->ikev2.r_nonce_len, 126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->keymat) < 0) { 127d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to " 12871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org "derive key material"); 129160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org return -1; 1304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org data->keymat_ok = 1; 132e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return 0; 1330ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry} 1344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic struct wpabuf * eap_ikev2_build_msg(struct eap_ikev2_data *data, 137c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org struct eap_method_ret *ret, u8 id) 1384d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org{ 139c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org struct wpabuf *resp; 140378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org u8 flags; 141c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_t send_len, plen, icv_len = 0; 142c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 143e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ret->ignore = FALSE; 144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Generating Response"); 145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->allowNotifications = TRUE; 146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 147355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org flags = 0; 148efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org send_len = wpabuf_len(data->out_buf) - data->out_used; 149471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (1 + send_len > data->fragment_size) { 150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org send_len = data->fragment_size - 1; 151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org flags |= IKEV2_FLAGS_MORE_FRAGMENTS; 152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->out_used == 0) { 15383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org flags |= IKEV2_FLAGS_LENGTH_INCLUDED; 154a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org send_len -= 4; 1555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 157f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org plen = 1 + send_len; 159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) 160e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org plen += 4; 161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->keys_ready) { 16232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org const struct ikev2_integ_alg *integ; 163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Add Integrity Checksum " 164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "Data"); 165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org flags |= IKEV2_FLAGS_ICV_INCLUDED; 166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org integ = ikev2_get_integ(data->ikev2.proposal.integ); 16783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org if (integ == NULL) { 16874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG " 16974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org "transform / cannot generate ICV"); 170e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return NULL; 171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org icv_len = integ->hash_len; 173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 174160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org plen += icv_len; 1750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org } 176b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, plen, 177471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org EAP_CODE_RESPONSE, id); 178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (resp == NULL) 179d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return NULL; 180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 181ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org wpabuf_put_u8(resp, flags); /* Flags */ 182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) 18394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org wpabuf_put_be32(resp, wpabuf_len(data->out_buf)); 184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org wpabuf_put_data(resp, wpabuf_head_u8(data->out_buf) + data->out_used, 186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org send_len); 187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->out_used += send_len; 188d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 189be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (flags & IKEV2_FLAGS_ICV_INCLUDED) { 190154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org const u8 *msg = wpabuf_head(resp); 191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org size_t len = wpabuf_len(resp); 19228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org ikev2_integ_hash(data->ikev2.proposal.integ, 193003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org data->ikev2.keys.SK_ar, 19428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org data->ikev2.keys.SK_integ_len, 19528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org msg, len, wpabuf_put(resp, icv_len)); 19628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 197c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 198c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org ret->methodState = METHOD_MAY_CONT; 199d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org ret->decision = DECISION_FAIL; 200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 201c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (data->out_used == wpabuf_len(data->out_buf)) { 202c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes " 203c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org "(message sent completely)", 20457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org (unsigned long) send_len); 205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org wpabuf_free(data->out_buf); 20678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org data->out_buf = NULL; 207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->out_used = 0; 208c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org switch (data->ikev2.state) { 209c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org case SA_AUTH: 210d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org /* SA_INIT was sent out, so message have to be 211c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org * integrity protected from now on. */ 212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->keys_ready = 1; 213dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org break; 214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case IKEV2_DONE: 215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->methodState = METHOD_DONE; 216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->state == FAIL) 217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 218dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org ret->decision = DECISION_COND_SUCC; 219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication " 220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "completed successfully"); 221dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org if (eap_ikev2_peer_keymat(data)) 222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 223dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org eap_ikev2_state(data, DONE); 224dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org break; 225dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org case IKEV2_FAILED: 226dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication " 227dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org "failed"); 228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->methodState = METHOD_DONE; 229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->decision = DECISION_FAIL; 230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org break; 231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org default: 2328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org break; 2338f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 2348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } else { 2358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes " 2368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org "(%lu more to send)", (unsigned long) send_len, 237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org (unsigned long) wpabuf_len(data->out_buf) - 238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->out_used); 2398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org eap_ikev2_state(data, WAIT_FRAG_ACK); 2408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 2418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org return resp; 243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic int eap_ikev2_process_icv(struct eap_ikev2_data *data, 247812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org const struct wpabuf *reqData, 248812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org u8 flags, const u8 *pos, const u8 **end, 249812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org int frag_ack) 250812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org{ 251812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (flags & IKEV2_FLAGS_ICV_INCLUDED) { 252812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org int icv_len = eap_ikev2_validate_icv( 253812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org data->ikev2.proposal.integ, &data->ikev2.keys, 1, 254812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org reqData, pos, *end); 255ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org if (icv_len < 0) 256ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org return -1; 257ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org /* Hide Integrity Checksum Data from further processing */ 258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org *end -= icv_len; 259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else if (data->keys_ready && !frag_ack) { 260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have " 261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "included integrity checksum"); 262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return -1; 263b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org } 2648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 265ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org return 0; 266ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org} 267ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org 2688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 2698f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgstatic int eap_ikev2_process_cont(struct eap_ikev2_data *data, 270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org const u8 *buf, size_t len) 2711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org{ 2721fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org /* Process continuation of a pending message */ 2731fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org if (len > wpabuf_tailroom(data->in_buf)) { 2741fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment overflow"); 2758f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org eap_ikev2_state(data, FAIL); 276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return -1; 2778f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 2795f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org wpabuf_put_data(data->in_buf, buf, len); 280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes, waiting " 281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "for %lu bytes more", (unsigned long) len, 282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org (unsigned long) wpabuf_tailroom(data->in_buf)); 283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return 0; 2858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 2868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 287471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 288471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgstatic struct wpabuf * eap_ikev2_process_fragment(struct eap_ikev2_data *data, 289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct eap_method_ret *ret, 2908f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org u8 id, u8 flags, 2918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org u32 message_length, 2928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org const u8 *buf, size_t len) 293fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org{ 294fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org /* Process a fragment that is not the last one of the message */ 295fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (data->in_buf == NULL && !(flags & IKEV2_FLAGS_LENGTH_INCLUDED)) { 296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: No Message Length field in " 297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "a fragmented packet"); 298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->ignore = TRUE; 299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->in_buf == NULL) { 303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org /* First fragment of the message */ 304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->in_buf = wpabuf_alloc(message_length); 305e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (data->in_buf == NULL) { 306e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for " 307e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "message"); 308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ret->ignore = TRUE; 309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return NULL; 310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 311e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org wpabuf_put_data(data->in_buf, buf, len); 312e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first " 313e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "fragment, waiting for %lu bytes more", 314e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (unsigned long) len, 315e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (unsigned long) wpabuf_tailroom(data->in_buf)); 316e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 317e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 318e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return eap_ikev2_build_frag_ack(id, EAP_CODE_RESPONSE); 319e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 320e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 321e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 322e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic struct wpabuf * eap_ikev2_process(struct eap_sm *sm, void *priv, 323e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct eap_method_ret *ret, 324e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const struct wpabuf *reqData) 325e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org{ 326e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct eap_ikev2_data *data = priv; 327e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const u8 *start, *pos, *end; 328e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org size_t len; 329e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org u8 flags, id; 330e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org u32 message_length = 0; 331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct wpabuf tmpbuf; 332e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 333e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, reqData, &len); 334e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (pos == NULL) { 335e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ret->ignore = TRUE; 336e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return NULL; 337e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 338e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 339e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org id = eap_get_id(reqData); 340e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 341e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org start = pos; 342e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org end = start + len; 343e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 344e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (len == 0) 345e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org flags = 0; /* fragment ack */ 346e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org else 347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org flags = *pos++; 348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 349d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (eap_ikev2_process_icv(data, reqData, flags, pos, &end, 350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->state == WAIT_FRAG_ACK && len == 0) < 0) 351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { 352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->ignore = TRUE; 353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) { 357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (end - pos < 4) { 358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow"); 359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->ignore = TRUE; 360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org message_length = WPA_GET_BE32(pos); 363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org pos += 4; 364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (message_length < (u32) (end - pos)) { 3662bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Invalid Message " 367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "Length (%d; %ld remaining in this msg)", 368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org message_length, (long) (end - pos)); 369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->ignore = TRUE; 370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x " 375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "Message Length %u", flags, message_length); 376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->state == WAIT_FRAG_ACK) { 3782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (len != 0) { 379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload " 380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org "in WAIT_FRAG_ACK state"); 381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ret->ignore = TRUE; 3822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return NULL; 383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged"); 385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org eap_ikev2_state(data, PROC_MSG); 3862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return eap_ikev2_build_msg(data, ret, id); 387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) { 3902bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ret->ignore = TRUE; 391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) { 395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return eap_ikev2_process_fragment(data, ret, id, flags, 396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org message_length, pos, 397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org end - pos); 398c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org } 399c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org 400c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (data->in_buf == NULL) { 401c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org /* Wrap unfragmented messages as wpabuf without extra copy */ 402c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org wpabuf_set(&tmpbuf, pos, end - pos); 4032bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org data->in_buf = &tmpbuf; 404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (ikev2_responder_process(&data->ikev2, data->in_buf) < 0) { 4072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (data->in_buf == &tmpbuf) 408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->in_buf = NULL; 409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org eap_ikev2_state(data, FAIL); 410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 4112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } 412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->in_buf != &tmpbuf) 414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org wpabuf_free(data->in_buf); 4152bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org data->in_buf = NULL; 416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->out_buf == NULL) { 418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org data->out_buf = ikev2_responder_build(&data->ikev2); 419c22f2d813ad21e25e8df5d4a371fd63f582e4262danno@chromium.org if (data->out_buf == NULL) { 420c22f2d813ad21e25e8df5d4a371fd63f582e4262danno@chromium.org wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to generate " 421935781b3604caa053bf75ce6b1079d79a225e63fdanno@chromium.org "IKEv2 message"); 422935781b3604caa053bf75ce6b1079d79a225e63fdanno@chromium.org return NULL; 423d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 424d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org data->out_used = 0; 425d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 426d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 427d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org eap_ikev2_state(data, PROC_MSG); 428d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return eap_ikev2_build_msg(data, ret, id); 429d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 430d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 431d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 432d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgstatic Boolean eap_ikev2_isKeyAvailable(struct eap_sm *sm, void *priv) 433d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org{ 434d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org struct eap_ikev2_data *data = priv; 435d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return data->state == DONE && data->keymat_ok; 436d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 437d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 438d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 439d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgstatic u8 * eap_ikev2_getKey(struct eap_sm *sm, void *priv, size_t *len) 440d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org{ 4412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org struct eap_ikev2_data *data = priv; 442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org u8 *key; 443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (data->state != DONE || !data->keymat_ok) 445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 447d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org key = os_malloc(EAP_MSK_LEN); 448a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (key) { 449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org os_memcpy(key, data->keymat, EAP_MSK_LEN); 450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org *len = EAP_MSK_LEN; 451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return key; 454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 457d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgstatic u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org{ 459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org struct eap_ikev2_data *data = priv; 460a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org u8 *key; 461d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 462a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org if (data->state != DONE || !data->keymat_ok) 463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return NULL; 464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 465a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org key = os_malloc(EAP_EMSK_LEN); 466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (key) { 467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN); 468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org *len = EAP_EMSK_LEN; 4693847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com } 4703847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 4713847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com return key; 4723847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com} 4733847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 4743847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 475ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.orgstatic u8 * eap_ikev2_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 4763847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com{ 4773847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com struct eap_ikev2_data *data = priv; 4783847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com u8 *sid; 4793847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com size_t sid_len; 4803847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com size_t offset; 4813847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 4823847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com if (data->state != DONE || !data->keymat_ok) 4833847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com return NULL; 4843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 4853847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com sid_len = 1 + data->ikev2.i_nonce_len + data->ikev2.r_nonce_len; 4863847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com sid = os_malloc(sid_len); 4873847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com if (sid) { 4883847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com offset = 0; 4893847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com sid[offset] = EAP_TYPE_IKEV2; 4903847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com offset++; 4913847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com os_memcpy(sid + offset, data->ikev2.i_nonce, 4923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com data->ikev2.i_nonce_len); 4933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com offset += data->ikev2.i_nonce_len; 4943847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com os_memcpy(sid + offset, data->ikev2.r_nonce, 4953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com data->ikev2.r_nonce_len); 4963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com *len = sid_len; 4973847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Derived Session-Id", 4983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com sid, sid_len); 4993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com } 5003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com return sid; 5023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com} 5033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5053847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.comint eap_peer_ikev2_register(void) 5063847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com{ 5073847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com struct eap_method *eap; 5083847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com int ret; 5093847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5103847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 5113847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 5123847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com "IKEV2"); 5133847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com if (eap == NULL) 5143847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com return -1; 5153847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5163847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->init = eap_ikev2_init; 5173847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->deinit = eap_ikev2_deinit; 5183847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->process = eap_ikev2_process; 5193847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->isKeyAvailable = eap_ikev2_isKeyAvailable; 5203847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->getKey = eap_ikev2_getKey; 5213847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->get_emsk = eap_ikev2_get_emsk; 5223847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com eap->getSessionId = eap_ikev2_get_session_id; 5233847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 5243847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com ret = eap_peer_method_register(eap); 52505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org if (ret) 52605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org eap_peer_method_free(eap); 52728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org return ret; 52805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org} 52905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org