static struct wpabuf * eap_sake_build_identity(struct eap_sm *sm, struct eap_sake_data *data, u8 id) { struct wpabuf *msg; size_t plen; asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: Request/Identity"); plen = 4; if (data->serverid) plen += 2 + data->serverid_len; msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_IDENTITY); if (msg == NULL) { data->state = FAILURE; return NULL; } asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: * AT_PERM_ID_REQ"); eap_sake_add_attr(msg, EAP_SAKE_AT_PERM_ID_REQ, NULL, 2); if (data->serverid) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: * AT_SERVERID"); eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID, data->serverid, data->serverid_len); } return msg; }
static struct wpabuf * eap_sake_build_challenge(struct eap_sm *sm, struct eap_sake_data *data, u8 id) { struct wpabuf *msg; size_t plen; asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: Request/Challenge"); if (os_get_random(data->rand_s, EAP_SAKE_RAND_LEN)) { asd_printf(ASD_DEFAULT,MSG_ERROR, "EAP-SAKE: Failed to get random data"); data->state = FAILURE; return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", data->rand_s, EAP_SAKE_RAND_LEN); plen = 2 + EAP_SAKE_RAND_LEN; if (data->serverid) plen += 2 + data->serverid_len; msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_CHALLENGE); if (msg == NULL) { data->state = FAILURE; return NULL; } asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: * AT_RAND_S"); eap_sake_add_attr(msg, EAP_SAKE_AT_RAND_S, data->rand_s, EAP_SAKE_RAND_LEN); if (data->serverid) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "EAP-SAKE: * AT_SERVERID"); eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID, data->serverid, data->serverid_len); } return msg; }
static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct eap_sake_parse_attr attr; struct wpabuf *resp; if (data->state != IDENTITY) { ret->ignore = TRUE; return NULL; } wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Identity"); if (eap_sake_parse_attributes(payload, payload_len, &attr)) return NULL; if (!attr.perm_id_req && !attr.any_id_req) { wpa_printf(MSG_INFO, "EAP-SAKE: No AT_PERM_ID_REQ or " "AT_ANY_ID_REQ in Request/Identity"); return NULL; } wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity"); resp = eap_sake_build_msg(data, eap_get_id(reqData), 2 + data->peerid_len, EAP_SAKE_SUBTYPE_IDENTITY); if (resp == NULL) return NULL; wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, data->peerid, data->peerid_len); eap_sake_state(data, CHALLENGE); return resp; }
static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, u8 id, const u8 *payload, size_t payload_len) { struct eap_sake_parse_attr attr; struct wpabuf *resp; u8 *rpos; size_t rlen; if (data->state != IDENTITY && data->state != CHALLENGE) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received " "in unexpected state (%d)", data->state); ret->ignore = TRUE; return NULL; } if (data->state == IDENTITY) eap_sake_state(data, CHALLENGE); wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Challenge"); if (eap_sake_parse_attributes(payload, payload_len, &attr)) return NULL; if (!attr.rand_s) { wpa_printf(MSG_INFO, "EAP-SAKE: Request/Challenge did not " "include AT_RAND_S"); return NULL; } os_memcpy(data->rand_s, attr.rand_s, EAP_SAKE_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", data->rand_s, EAP_SAKE_RAND_LEN); if (random_get_bytes(data->rand_p, EAP_SAKE_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_P (peer rand)", data->rand_p, EAP_SAKE_RAND_LEN); os_free(data->serverid); data->serverid = NULL; data->serverid_len = 0; if (attr.serverid) { wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-SAKE: SERVERID", attr.serverid, attr.serverid_len); data->serverid = os_malloc(attr.serverid_len); if (data->serverid == NULL) return NULL; os_memcpy(data->serverid, attr.serverid, attr.serverid_len); data->serverid_len = attr.serverid_len; } eap_sake_derive_keys(data->root_secret_a, data->root_secret_b, data->rand_s, data->rand_p, (u8 *) &data->tek, data->msk, data->emsk); wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge"); rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN; if (data->peerid) rlen += 2 + data->peerid_len; resp = eap_sake_build_msg(data, id, rlen, EAP_SAKE_SUBTYPE_CHALLENGE); if (resp == NULL) return NULL; wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P"); eap_sake_add_attr(resp, EAP_SAKE_AT_RAND_P, data->rand_p, EAP_SAKE_RAND_LEN); if (data->peerid) { wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID, data->peerid, data->peerid_len); } wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P); wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN); rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN); if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, data->serverid, data->serverid_len, data->peerid, data->peerid_len, 1, wpabuf_head(resp), wpabuf_len(resp), rpos, rpos)) { wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); wpabuf_free(resp); return NULL; } eap_sake_state(data, CONFIRM); return resp; }