18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer method: EAP-SAKE (RFC 4763) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap_i.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_sake_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sake_data { 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { IDENTITY, CHALLENGE, CONFIRM, SUCCESS, FAILURE } state; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 root_secret_a[EAP_SAKE_ROOT_SECRET_LEN]; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 root_secret_b[EAP_SAKE_ROOT_SECRET_LEN]; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand_s[EAP_SAKE_RAND_LEN]; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand_p[EAP_SAKE_RAND_LEN]; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 auth[EAP_SAKE_TEK_AUTH_LEN]; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 cipher[EAP_SAKE_TEK_CIPHER_LEN]; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } tek; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 msk[EAP_MSK_LEN]; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 emsk[EAP_EMSK_LEN]; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 session_id; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int session_id_set; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *peerid; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t peerid_len; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *serverid; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t serverid_len; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_sake_state_txt(int state) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IDENTITY: 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDENTITY"; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CHALLENGE: 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CHALLENGE"; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CONFIRM: 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONFIRM"; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUCCESS: 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case FAILURE: 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAILURE"; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sake_state(struct eap_sake_data *data, int state) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: %s -> %s", 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state_txt(data->state), 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state_txt(state)); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = state; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sake_deinit(struct eap_sm *sm, void *priv); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_sake_init(struct eap_sm *sm) 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *identity, *password; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len, password_len; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password = eap_get_config_password(sm, &password_len); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!password || password_len != 2 * EAP_SAKE_ROOT_SECRET_LEN) { 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: No key of correct length " 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configured"); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = IDENTITY; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = eap_get_config_identity(sm, &identity_len); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity) { 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid = os_malloc(identity_len); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peerid == NULL) { 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_deinit(sm, data); 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->peerid, identity, identity_len); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid_len = identity_len; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->root_secret_a, password, EAP_SAKE_ROOT_SECRET_LEN); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->root_secret_b, 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password + EAP_SAKE_ROOT_SECRET_LEN, 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_ROOT_SECRET_LEN); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sake_deinit(struct eap_sm *sm, void *priv) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->serverid); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->peerid); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data, 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id, size_t length, u8 subtype) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_hdr *sake; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *msg; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = length + sizeof(struct eap_sake_hdr); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_SAKE, plen, 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to allocate memory " 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request"); 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sake = wpabuf_put(msg, sizeof(*sake)); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sake->version = EAP_SAKE_VERSION; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sake->session_id = data->session_id; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sake->subtype = subtype; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process_identity(struct eap_sm *sm, 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data, 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *payload, 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t payload_len) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_parse_attr attr; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != IDENTITY) { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Identity"); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_parse_attributes(payload, payload_len, &attr)) 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!attr.perm_id_req && !attr.any_id_req) { 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: No AT_PERM_ID_REQ or " 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AT_ANY_ID_REQ in Request/Identity"); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity"); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_build_msg(data, eap_get_id(reqData), 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + data->peerid_len, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_IDENTITY); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CHALLENGE); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *payload, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t payload_len) 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_parse_attr attr; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rpos; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != IDENTITY && data->state != CHALLENGE) { 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received " 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in unexpected state (%d)", data->state); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == IDENTITY) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CHALLENGE); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Challenge"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_parse_attributes(payload, payload_len, &attr)) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!attr.rand_s) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Request/Challenge did not " 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "include AT_RAND_S"); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->rand_s, attr.rand_s, EAP_SAKE_RAND_LEN); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_s, EAP_SAKE_RAND_LEN); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(data->rand_p, EAP_SAKE_RAND_LEN)) { 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_P (peer rand)", 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_p, EAP_SAKE_RAND_LEN); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->serverid); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid = NULL; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid_len = 0; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.serverid) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-SAKE: SERVERID", 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.serverid, attr.serverid_len); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid = os_malloc(attr.serverid_len); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->serverid == NULL) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->serverid, attr.serverid, attr.serverid_len); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid_len = attr.serverid_len; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_derive_keys(data->root_secret_a, data->root_secret_b, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_s, data->rand_p, 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &data->tek, data->msk, data->emsk); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge"); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peerid) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen += 2 + data->peerid_len; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_build_msg(data, eap_get_id(reqData), rlen, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_CHALLENGE); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P"); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_RAND_P, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_p, EAP_SAKE_RAND_LEN); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peerid) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid, data->serverid_len, 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len, 1, 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), rpos, 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos)) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CONFIRM); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm, 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data, 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData, 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *payload, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t payload_len) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_parse_attr attr; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mic_s[EAP_SAKE_MIC_LEN]; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rpos; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != CONFIRM) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Confirm"); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_parse_attributes(payload, payload_len, &attr)) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!attr.mic_s) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Request/Confirm did not " 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "include AT_MIC_S"); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid, data->serverid_len, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len, 0, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(reqData), wpabuf_len(reqData), 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.mic_s, mic_s); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) { 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S"); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, FAILURE); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending " 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Response/Auth-Reject"); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sake_build_msg(data, eap_get_id(reqData), 0, 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_AUTH_REJECT); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm"); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_build_msg(data, eap_get_id(reqData), 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + EAP_SAKE_MIC_LEN, 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_CONFIRM); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid, data->serverid_len, 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len, 1, 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), rpos, 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos)) { 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, SUCCESS); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_UNCOND_SUCC; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv, 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData) 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_sake_hdr *req; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 subtype, session_id; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || len < sizeof(struct eap_sake_hdr)) { 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = (const struct eap_sake_hdr *) pos; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt subtype = req->subtype; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session_id = req->session_id; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (req + 1); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received frame: subtype %d " 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session_id %d", subtype, session_id); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Received attributes", 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->session_id_set && data->session_id != session_id) { 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Session ID mismatch (%d,%d)", 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session_id, data->session_id); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->session_id = session_id; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->session_id_set = 1; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = FALSE; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_MAY_CONT; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = TRUE; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (subtype) { 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_IDENTITY: 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_process_identity(sm, data, ret, reqData, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_CHALLENGE: 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_process_challenge(sm, data, ret, reqData, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_CONFIRM: 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_sake_process_confirm(sm, data, ret, reqData, 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Ignoring message with " 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown subtype %d", subtype); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret->methodState == METHOD_DONE) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sake_isKeyAvailable(struct eap_sm *sm, void *priv) 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state == SUCCESS; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_sake_getKey(struct eap_sm *sm, void *priv, size_t *len) 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != SUCCESS) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_MSK_LEN); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->msk, EAP_MSK_LEN); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_MSK_LEN; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_sake_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != SUCCESS) 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_EMSK_LEN); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->emsk, EAP_EMSK_LEN); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_EMSK_LEN; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_sake_register(void) 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_SAKE, "SAKE"); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_sake_init; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->deinit = eap_sake_deinit; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_sake_process; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isKeyAvailable = eap_sake_isKeyAvailable; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->getKey = eap_sake_getKey; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->get_emsk = eap_sake_get_emsk; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_peer_method_register(eap); 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_method_free(eap); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 495