2 * EAP-IKEv2 common routines
3 * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "eap_common.h"
20 #include "ikev2_common.h"
21 #include "eap_ikev2_common.h"
24 int eap_ikev2_derive_keymat(int prf
, struct ikev2_keys
*keys
,
25 const u8
*i_nonce
, size_t i_nonce_len
,
26 const u8
*r_nonce
, size_t r_nonce_len
,
32 /* KEYMAT = prf+(SK_d, Ni | Nr) */
33 if (keys
->SK_d
== NULL
|| i_nonce
== NULL
|| r_nonce
== NULL
)
36 nlen
= i_nonce_len
+ r_nonce_len
;
37 nonces
= os_malloc(nlen
);
40 os_memcpy(nonces
, i_nonce
, i_nonce_len
);
41 os_memcpy(nonces
+ i_nonce_len
, r_nonce
, r_nonce_len
);
43 if (ikev2_prf_plus(prf
, keys
->SK_d
, keys
->SK_d_len
, nonces
, nlen
,
44 keymat
, EAP_MSK_LEN
+ EAP_EMSK_LEN
)) {
50 wpa_hexdump_key(MSG_DEBUG
, "EAP-IKEV2: KEYMAT",
51 keymat
, EAP_MSK_LEN
+ EAP_EMSK_LEN
);
57 struct wpabuf
* eap_ikev2_build_frag_ack(u8 id
, u8 code
)
62 msg
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
, 1, code
, id
);
64 wpa_printf(MSG_ERROR
, "EAP-IKEV2: Failed to allocate memory "
68 wpabuf_put_u8(msg
, 0); /* Flags */
70 msg
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
, 0, code
, id
);
72 wpa_printf(MSG_ERROR
, "EAP-IKEV2: Failed to allocate memory "
78 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Send fragment ack");
84 int eap_ikev2_validate_icv(int integ_alg
, struct ikev2_keys
*keys
,
85 int initiator
, const struct wpabuf
*msg
,
86 const u8
*pos
, const u8
*end
)
88 const struct ikev2_integ_alg
*integ
;
90 u8 icv
[IKEV2_MAX_HASH_LEN
];
91 const u8
*SK_a
= initiator
? keys
->SK_ai
: keys
->SK_ar
;
93 integ
= ikev2_get_integ(integ_alg
);
95 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Unknown INTEG "
96 "transform / cannot validate ICV");
99 icv_len
= integ
->hash_len
;
101 if (end
- pos
< (int) icv_len
) {
102 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Not enough room in the "
103 "message for Integrity Checksum Data");
108 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: No SK_a for ICV validation");
112 if (ikev2_integ_hash(integ_alg
, SK_a
, keys
->SK_integ_len
,
114 wpabuf_len(msg
) - icv_len
, icv
) < 0) {
115 wpa_printf(MSG_INFO
, "EAP-IKEV2: Could not calculate ICV");
119 if (os_memcmp(icv
, end
- icv_len
, icv_len
) != 0) {
120 wpa_printf(MSG_INFO
, "EAP-IKEV2: Invalid ICV");
121 wpa_hexdump(MSG_DEBUG
, "EAP-IKEV2: Calculated ICV",
123 wpa_hexdump(MSG_DEBUG
, "EAP-IKEV2: Received ICV",
124 end
- icv_len
, icv_len
);
128 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Valid Integrity Checksum Data in "
129 "the received message");