2 * EAP-IKEv2 common routines
3 * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #include "eap_common.h"
14 #include "ikev2_common.h"
15 #include "eap_ikev2_common.h"
18 int eap_ikev2_derive_keymat(int prf, struct ikev2_keys *keys,
19 const u8 *i_nonce, size_t i_nonce_len,
20 const u8 *r_nonce, size_t r_nonce_len,
26 /* KEYMAT = prf+(SK_d, Ni | Nr) */
27 if (keys->SK_d == NULL || i_nonce == NULL || r_nonce == NULL)
30 nlen = i_nonce_len + r_nonce_len;
31 nonces = os_malloc(nlen);
34 os_memcpy(nonces, i_nonce, i_nonce_len);
35 os_memcpy(nonces + i_nonce_len, r_nonce, r_nonce_len);
37 if (ikev2_prf_plus(prf, keys->SK_d, keys->SK_d_len, nonces, nlen,
38 keymat, EAP_MSK_LEN + EAP_EMSK_LEN)) {
44 wpa_hexdump_key(MSG_DEBUG, "EAP-IKEV2: KEYMAT",
45 keymat, EAP_MSK_LEN + EAP_EMSK_LEN);
51 struct wpabuf * eap_ikev2_build_frag_ack(u8 id, u8 code)
55 msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 0, code, id);
57 wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
62 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Send fragment ack");
68 int eap_ikev2_validate_icv(int integ_alg, struct ikev2_keys *keys,
69 int initiator, const struct wpabuf *msg,
70 const u8 *pos, const u8 *end)
72 const struct ikev2_integ_alg *integ;
74 u8 icv[IKEV2_MAX_HASH_LEN];
75 const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
77 integ = ikev2_get_integ(integ_alg);
79 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
80 "transform / cannot validate ICV");
83 icv_len = integ->hash_len;
85 if (end - pos < (int) icv_len) {
86 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Not enough room in the "
87 "message for Integrity Checksum Data");
92 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No SK_a for ICV validation");
96 if (ikev2_integ_hash(integ_alg, SK_a, keys->SK_integ_len,
98 wpabuf_len(msg) - icv_len, icv) < 0) {
99 wpa_printf(MSG_INFO, "EAP-IKEV2: Could not calculate ICV");
103 if (os_memcmp_const(icv, end - icv_len, icv_len) != 0) {
104 wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV");
105 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV",
107 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Received ICV",
108 end - icv_len, icv_len);
112 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Valid Integrity Checksum Data in "
113 "the received message");