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); 111c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(data, sizeof(*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, 144cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt u8 id, 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 169cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_build_msg(data, id, 2 + data->peerid_len, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_IDENTITY); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CHALLENGE); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 187cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt u8 id, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *payload, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t payload_len) 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_parse_attr attr; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rpos; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != IDENTITY && data->state != CHALLENGE) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received " 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in unexpected state (%d)", data->state); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == IDENTITY) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CHALLENGE); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Challenge"); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_parse_attributes(payload, payload_len, &attr)) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!attr.rand_s) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Request/Challenge did not " 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "include AT_RAND_S"); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->rand_s, attr.rand_s, EAP_SAKE_RAND_LEN); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_s, EAP_SAKE_RAND_LEN); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(data->rand_p, EAP_SAKE_RAND_LEN)) { 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_P (peer rand)", 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_p, EAP_SAKE_RAND_LEN); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->serverid); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid = NULL; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid_len = 0; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.serverid) { 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-SAKE: SERVERID", 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.serverid, attr.serverid_len); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid = os_malloc(attr.serverid_len); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->serverid == NULL) 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->serverid, attr.serverid, attr.serverid_len); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid_len = attr.serverid_len; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_derive_keys(data->root_secret_a, data->root_secret_b, 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_s, data->rand_p, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &data->tek, data->msk, data->emsk); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge"); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peerid) 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen += 2 + data->peerid_len; 249cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_build_msg(data, id, rlen, EAP_SAKE_SUBTYPE_CHALLENGE); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P"); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_RAND_P, 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->rand_p, EAP_SAKE_RAND_LEN); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->peerid) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid, data->serverid_len, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len, 1, 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), rpos, 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos)) { 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, CONFIRM); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm, 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data, 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 286cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt u8 id, 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData, 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *payload, 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t payload_len) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_parse_attr attr; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mic_s[EAP_SAKE_MIC_LEN]; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rpos; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != CONFIRM) { 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Confirm"); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_parse_attributes(payload, payload_len, &attr)) 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!attr.mic_s) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Request/Confirm did not " 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "include AT_MIC_S"); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 312849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 313849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt data->serverid, data->serverid_len, 314849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt data->peerid, data->peerid_len, 0, 315849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_head(reqData), wpabuf_len(reqData), 316849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt attr.mic_s, mic_s)) { 317849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); 318849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt eap_sake_state(data, FAILURE); 319849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ret->methodState = METHOD_DONE; 320849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ret->decision = DECISION_FAIL; 321849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ret->allowNotifications = FALSE; 322849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Auth-Reject"); 323849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return eap_sake_build_msg(data, id, 0, 324849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt EAP_SAKE_SUBTYPE_AUTH_REJECT); 325849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 326c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S"); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, FAILURE); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending " 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Response/Auth-Reject"); 334cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt return eap_sake_build_msg(data, id, 0, 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_AUTH_REJECT); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm"); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 340cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_build_msg(data, id, 2 + EAP_SAKE_MIC_LEN, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SAKE_SUBTYPE_CONFIRM); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->serverid, data->serverid_len, 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->peerid, data->peerid_len, 1, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), rpos, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos)) { 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sake_state(data, SUCCESS); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_UNCOND_SUCC; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData) 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_sake_hdr *req; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 377cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt u8 subtype, session_id, id; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || len < sizeof(struct eap_sake_hdr)) { 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = (const struct eap_sake_hdr *) pos; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 387cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt id = eap_get_id(reqData); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt subtype = req->subtype; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session_id = req->session_id; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (req + 1); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Received frame: subtype %d " 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session_id %d", subtype, session_id); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Received attributes", 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->session_id_set && data->session_id != session_id) { 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SAKE: Session ID mismatch (%d,%d)", 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session_id, data->session_id); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->session_id = session_id; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->session_id_set = 1; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = FALSE; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_MAY_CONT; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = TRUE; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (subtype) { 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_IDENTITY: 413cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_process_identity(sm, data, ret, id, 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_CHALLENGE: 417cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_process_challenge(sm, data, ret, id, 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SAKE_SUBTYPE_CONFIRM: 421cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt resp = eap_sake_process_confirm(sm, data, ret, id, reqData, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SAKE: Ignoring message with " 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown subtype %d", subtype); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret->methodState == METHOD_DONE) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sake_isKeyAvailable(struct eap_sm *sm, void *priv) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state == SUCCESS; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_sake_getKey(struct eap_sm *sm, void *priv, size_t *len) 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != SUCCESS) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_MSK_LEN); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->msk, EAP_MSK_LEN); 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_MSK_LEN; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 463f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic u8 * eap_sake_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 464f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{ 465f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct eap_sake_data *data = priv; 466f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u8 *id; 467f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 468f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (data->state != SUCCESS) 469f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return NULL; 470f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 471f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt *len = 1 + 2 * EAP_SAKE_RAND_LEN; 472f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt id = os_malloc(*len); 473f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (id == NULL) 474f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return NULL; 475f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 476f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt id[0] = EAP_TYPE_SAKE; 477f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(id + 1, data->rand_s, EAP_SAKE_RAND_LEN); 478f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(id + 1 + EAP_SAKE_RAND_LEN, data->rand_s, EAP_SAKE_RAND_LEN); 479f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Derived Session-Id", id, *len); 480f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 481f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return id; 482f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt} 483f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 484f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_sake_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sake_data *data = priv; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != SUCCESS) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_EMSK_LEN); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->emsk, EAP_EMSK_LEN); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_EMSK_LEN; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_sake_register(void) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_SAKE, "SAKE"); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_sake_init; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->deinit = eap_sake_deinit; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_sake_process; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isKeyAvailable = eap_sake_isKeyAvailable; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->getKey = eap_sake_getKey; 517f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap->getSessionId = eap_sake_get_session_id; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->get_emsk = eap_sake_get_emsk; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5201d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt return eap_peer_method_register(eap); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 522