static int ikev2_process_sa_init_encr(struct ikev2_initiator_data *data, const struct ikev2_hdr *hdr, const u8 *encrypted, size_t encrypted_len, u8 next_payload) { u8 *decrypted; size_t decrypted_len; struct ikev2_payloads pl; int ret = 0; decrypted = ikev2_decrypt_payload(data->proposal.encr, data->proposal.integ, &data->keys, 0, hdr, encrypted, encrypted_len, &decrypted_len); if (decrypted == NULL) return -1; asd_printf(ASD_DEFAULT,MSG_DEBUG, "IKEV2: Processing decrypted payloads"); if (ikev2_parse_payloads(&pl, next_payload, decrypted, decrypted + decrypted_len) < 0) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "IKEV2: Failed to parse decrypted " "payloads"); return -1; } if (pl.idr) ret = ikev2_process_idr(data, pl.idr, pl.idr_len); os_free(decrypted); return ret; }
static int ikev2_process_sa_auth_decrypted(struct ikev2_responder_data *data, u8 next_payload, u8 *payload, size_t payload_len) { struct ikev2_payloads pl; wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads"); if (ikev2_parse_payloads(&pl, next_payload, payload, payload + payload_len) < 0) { wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted " "payloads"); return -1; } if (ikev2_process_idi(data, pl.idi, pl.idi_len) < 0 || ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 || ikev2_process_auth(data, pl.auth, pl.auth_len) < 0) { return -1; } return 0; }
static int ikev2_process_sa_auth_decrypted(struct ikev2_initiator_data *data, u8 next_payload, u8 *payload, size_t payload_len) { struct ikev2_payloads pl; asd_printf(ASD_DEFAULT,MSG_DEBUG, "IKEV2: Processing decrypted payloads"); if (ikev2_parse_payloads(&pl, next_payload, payload, payload + payload_len) < 0) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "IKEV2: Failed to parse decrypted " "payloads"); return -1; } if (ikev2_process_idr(data, pl.idr, pl.idr_len) < 0 || ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 || ikev2_process_auth(data, pl.auth, pl.auth_len) < 0) return -1; return 0; }
int ikev2_responder_process(struct ikev2_responder_data *data, const struct wpabuf *buf) { const struct ikev2_hdr *hdr; u32 length, message_id; const u8 *pos, *end; struct ikev2_payloads pl; wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)", (unsigned long) wpabuf_len(buf)); if (wpabuf_len(buf) < sizeof(*hdr)) { wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR"); return -1; } data->error_type = 0; hdr = (const struct ikev2_hdr *) wpabuf_head(buf); end = wpabuf_head_u8(buf) + wpabuf_len(buf); message_id = WPA_GET_BE32(hdr->message_id); length = WPA_GET_BE32(hdr->length); wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI", hdr->i_spi, IKEV2_SPI_LEN); wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI", hdr->r_spi, IKEV2_SPI_LEN); wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Version: 0x%x " "Exchange Type: %u", hdr->next_payload, hdr->version, hdr->exchange_type); wpa_printf(MSG_DEBUG, "IKEV2: Message ID: %u Length: %u", message_id, length); if (hdr->version != IKEV2_VERSION) { wpa_printf(MSG_INFO, "IKEV2: Unsupported HDR version 0x%x " "(expected 0x%x)", hdr->version, IKEV2_VERSION); return -1; } if (length != wpabuf_len(buf)) { wpa_printf(MSG_INFO, "IKEV2: Invalid length (HDR: %lu != " "RX: %lu)", (unsigned long) length, (unsigned long) wpabuf_len(buf)); return -1; } if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0) return -1; if ((hdr->flags & (IKEV2_HDR_INITIATOR | IKEV2_HDR_RESPONSE)) != IKEV2_HDR_INITIATOR) { wpa_printf(MSG_INFO, "IKEV2: Unexpected Flags value 0x%x", hdr->flags); return -1; } if (data->state != SA_INIT) { if (os_memcmp(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN) != 0) { wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA " "Initiator's SPI"); return -1; } if (os_memcmp(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN) != 0) { wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA " "Responder's SPI"); return -1; } } pos = (const u8 *) (hdr + 1); if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0) return -1; if (data->state == SA_INIT) { data->last_msg = LAST_MSG_SA_INIT; if (ikev2_process_sa_init(data, hdr, &pl) < 0) { if (data->state == NOTIFY) return 0; return -1; } wpabuf_free(data->i_sign_msg); data->i_sign_msg = wpabuf_dup(buf); } if (data->state == SA_AUTH) { data->last_msg = LAST_MSG_SA_AUTH; if (ikev2_process_sa_auth(data, hdr, &pl) < 0) { if (data->state == NOTIFY) return 0; return -1; } } return 0; }