2 * EAP-IKEv2 server (RFC 5106)
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/eap_ikev2_common.h"
17 struct eap_ikev2_data
{
18 struct ikev2_initiator_data ikev2
;
19 enum { MSG
, FRAG_ACK
, WAIT_FRAG_ACK
, DONE
, FAIL
} state
;
20 struct wpabuf
*in_buf
;
21 struct wpabuf
*out_buf
;
25 u8 keymat
[EAP_MSK_LEN
+ EAP_EMSK_LEN
];
30 static const u8
* eap_ikev2_get_shared_secret(void *ctx
, const u8
*IDr
,
34 struct eap_sm
*sm
= ctx
;
37 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: No IDr received - default "
38 "to user identity from EAP-Identity");
40 IDr_len
= sm
->identity_len
;
43 if (eap_user_get(sm
, IDr
, IDr_len
, 0) < 0 || sm
->user
== NULL
||
44 sm
->user
->password
== NULL
) {
45 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: No user entry found");
49 *secret_len
= sm
->user
->password_len
;
50 return sm
->user
->password
;
54 static const char * eap_ikev2_state_txt(int state
)
62 return "WAIT_FRAG_ACK";
73 static void eap_ikev2_state(struct eap_ikev2_data
*data
, int state
)
75 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: %s -> %s",
76 eap_ikev2_state_txt(data
->state
),
77 eap_ikev2_state_txt(state
));
82 static void * eap_ikev2_init(struct eap_sm
*sm
)
84 struct eap_ikev2_data
*data
;
86 data
= os_zalloc(sizeof(*data
));
90 data
->fragment_size
= sm
->fragment_size
> 0 ? sm
->fragment_size
:
92 data
->ikev2
.state
= SA_INIT
;
93 data
->ikev2
.peer_auth
= PEER_AUTH_SECRET
;
94 data
->ikev2
.key_pad
= (u8
*) os_strdup("Key Pad for EAP-IKEv2");
95 if (data
->ikev2
.key_pad
== NULL
)
97 data
->ikev2
.key_pad_len
= 21;
99 /* TODO: make proposals configurable */
100 data
->ikev2
.proposal
.proposal_num
= 1;
101 data
->ikev2
.proposal
.integ
= AUTH_HMAC_SHA1_96
;
102 data
->ikev2
.proposal
.prf
= PRF_HMAC_SHA1
;
103 data
->ikev2
.proposal
.encr
= ENCR_AES_CBC
;
104 data
->ikev2
.proposal
.dh
= DH_GROUP2_1024BIT_MODP
;
106 data
->ikev2
.IDi
= (u8
*) os_strdup("hostapd");
107 data
->ikev2
.IDi_len
= 7;
109 data
->ikev2
.get_shared_secret
= eap_ikev2_get_shared_secret
;
110 data
->ikev2
.cb_ctx
= sm
;
115 ikev2_initiator_deinit(&data
->ikev2
);
121 static void eap_ikev2_reset(struct eap_sm
*sm
, void *priv
)
123 struct eap_ikev2_data
*data
= priv
;
124 wpabuf_free(data
->in_buf
);
125 wpabuf_free(data
->out_buf
);
126 ikev2_initiator_deinit(&data
->ikev2
);
131 static struct wpabuf
* eap_ikev2_build_msg(struct eap_ikev2_data
*data
, u8 id
)
135 size_t send_len
, plen
, icv_len
= 0;
137 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Generating Request");
140 send_len
= wpabuf_len(data
->out_buf
) - data
->out_used
;
141 if (1 + send_len
> data
->fragment_size
) {
142 send_len
= data
->fragment_size
- 1;
143 flags
|= IKEV2_FLAGS_MORE_FRAGMENTS
;
144 if (data
->out_used
== 0) {
145 flags
|= IKEV2_FLAGS_LENGTH_INCLUDED
;
151 if (flags
& IKEV2_FLAGS_LENGTH_INCLUDED
)
153 if (data
->keys_ready
) {
154 const struct ikev2_integ_alg
*integ
;
155 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Add Integrity Checksum "
157 flags
|= IKEV2_FLAGS_ICV_INCLUDED
;
158 integ
= ikev2_get_integ(data
->ikev2
.proposal
.integ
);
160 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Unknown INTEG "
161 "transform / cannot generate ICV");
164 icv_len
= integ
->hash_len
;
168 req
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
, plen
,
169 EAP_CODE_REQUEST
, id
);
173 wpabuf_put_u8(req
, flags
); /* Flags */
174 if (flags
& IKEV2_FLAGS_LENGTH_INCLUDED
)
175 wpabuf_put_be32(req
, wpabuf_len(data
->out_buf
));
177 wpabuf_put_data(req
, wpabuf_head_u8(data
->out_buf
) + data
->out_used
,
179 data
->out_used
+= send_len
;
181 if (flags
& IKEV2_FLAGS_ICV_INCLUDED
) {
182 const u8
*msg
= wpabuf_head(req
);
183 size_t len
= wpabuf_len(req
);
184 ikev2_integ_hash(data
->ikev2
.proposal
.integ
,
185 data
->ikev2
.keys
.SK_ai
,
186 data
->ikev2
.keys
.SK_integ_len
,
187 msg
, len
, wpabuf_put(req
, icv_len
));
190 if (data
->out_used
== wpabuf_len(data
->out_buf
)) {
191 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Sending out %lu bytes "
192 "(message sent completely)",
193 (unsigned long) send_len
);
194 wpabuf_free(data
->out_buf
);
195 data
->out_buf
= NULL
;
198 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Sending out %lu bytes "
199 "(%lu more to send)", (unsigned long) send_len
,
200 (unsigned long) wpabuf_len(data
->out_buf
) -
202 eap_ikev2_state(data
, WAIT_FRAG_ACK
);
209 static struct wpabuf
* eap_ikev2_buildReq(struct eap_sm
*sm
, void *priv
, u8 id
)
211 struct eap_ikev2_data
*data
= priv
;
213 switch (data
->state
) {
215 if (data
->out_buf
== NULL
) {
216 data
->out_buf
= ikev2_initiator_build(&data
->ikev2
);
217 if (data
->out_buf
== NULL
) {
218 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Failed to "
219 "generate IKEv2 message");
226 return eap_ikev2_build_msg(data
, id
);
228 return eap_ikev2_build_frag_ack(id
, EAP_CODE_REQUEST
);
230 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Unexpected state %d in "
231 "buildReq", data
->state
);
237 static Boolean
eap_ikev2_check(struct eap_sm
*sm
, void *priv
,
238 struct wpabuf
*respData
)
243 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
, respData
,
246 wpa_printf(MSG_INFO
, "EAP-IKEV2: Invalid frame");
254 static int eap_ikev2_process_icv(struct eap_ikev2_data
*data
,
255 const struct wpabuf
*respData
,
256 u8 flags
, const u8
*pos
, const u8
**end
)
258 if (flags
& IKEV2_FLAGS_ICV_INCLUDED
) {
259 int icv_len
= eap_ikev2_validate_icv(
260 data
->ikev2
.proposal
.integ
, &data
->ikev2
.keys
, 0,
261 respData
, pos
, *end
);
264 /* Hide Integrity Checksum Data from further processing */
266 } else if (data
->keys_ready
) {
267 wpa_printf(MSG_INFO
, "EAP-IKEV2: The message should have "
268 "included integrity checksum");
276 static int eap_ikev2_process_cont(struct eap_ikev2_data
*data
,
277 const u8
*buf
, size_t len
)
279 /* Process continuation of a pending message */
280 if (len
> wpabuf_tailroom(data
->in_buf
)) {
281 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Fragment overflow");
282 eap_ikev2_state(data
, FAIL
);
286 wpabuf_put_data(data
->in_buf
, buf
, len
);
287 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Received %lu bytes, waiting for %lu "
288 "bytes more", (unsigned long) len
,
289 (unsigned long) wpabuf_tailroom(data
->in_buf
));
295 static int eap_ikev2_process_fragment(struct eap_ikev2_data
*data
,
296 u8 flags
, u32 message_length
,
297 const u8
*buf
, size_t len
)
299 /* Process a fragment that is not the last one of the message */
300 if (data
->in_buf
== NULL
&& !(flags
& IKEV2_FLAGS_LENGTH_INCLUDED
)) {
301 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: No Message Length field in "
302 "a fragmented packet");
306 if (data
->in_buf
== NULL
) {
307 /* First fragment of the message */
308 data
->in_buf
= wpabuf_alloc(message_length
);
309 if (data
->in_buf
== NULL
) {
310 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: No memory for "
314 wpabuf_put_data(data
->in_buf
, buf
, len
);
315 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Received %lu bytes in first "
316 "fragment, waiting for %lu bytes more",
318 (unsigned long) wpabuf_tailroom(data
->in_buf
));
325 static int eap_ikev2_server_keymat(struct eap_ikev2_data
*data
)
327 if (eap_ikev2_derive_keymat(
328 data
->ikev2
.proposal
.prf
, &data
->ikev2
.keys
,
329 data
->ikev2
.i_nonce
, data
->ikev2
.i_nonce_len
,
330 data
->ikev2
.r_nonce
, data
->ikev2
.r_nonce_len
,
332 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Failed to derive "
341 static void eap_ikev2_process(struct eap_sm
*sm
, void *priv
,
342 struct wpabuf
*respData
)
344 struct eap_ikev2_data
*data
= priv
;
345 const u8
*start
, *pos
, *end
;
348 u32 message_length
= 0;
349 struct wpabuf tmpbuf
;
351 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
, respData
,
354 return; /* Should not happen; message already verified */
365 if (eap_ikev2_process_icv(data
, respData
, flags
, pos
, &end
) < 0) {
366 eap_ikev2_state(data
, FAIL
);
370 if (flags
& IKEV2_FLAGS_LENGTH_INCLUDED
) {
372 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Message underflow");
373 eap_ikev2_state(data
, FAIL
);
376 message_length
= WPA_GET_BE32(pos
);
379 if (message_length
< (u32
) (end
- pos
)) {
380 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Invalid Message "
381 "Length (%d; %ld remaining in this msg)",
382 message_length
, (long) (end
- pos
));
383 eap_ikev2_state(data
, FAIL
);
387 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Received packet: Flags 0x%x "
388 "Message Length %u", flags
, message_length
);
390 if (data
->state
== WAIT_FRAG_ACK
) {
392 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Unexpected payload "
393 "in WAIT_FRAG_ACK state");
394 eap_ikev2_state(data
, FAIL
);
397 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Fragment acknowledged");
398 eap_ikev2_state(data
, MSG
);
402 if (data
->in_buf
&& eap_ikev2_process_cont(data
, pos
, end
- pos
) < 0) {
403 eap_ikev2_state(data
, FAIL
);
407 if (flags
& IKEV2_FLAGS_MORE_FRAGMENTS
) {
408 if (eap_ikev2_process_fragment(data
, flags
, message_length
,
410 eap_ikev2_state(data
, FAIL
);
412 eap_ikev2_state(data
, FRAG_ACK
);
414 } else if (data
->state
== FRAG_ACK
) {
415 wpa_printf(MSG_DEBUG
, "EAP-TNC: All fragments received");
419 if (data
->in_buf
== NULL
) {
420 /* Wrap unfragmented messages as wpabuf without extra copy */
421 wpabuf_set(&tmpbuf
, pos
, end
- pos
);
422 data
->in_buf
= &tmpbuf
;
425 if (ikev2_initiator_process(&data
->ikev2
, data
->in_buf
) < 0) {
426 if (data
->in_buf
== &tmpbuf
)
428 eap_ikev2_state(data
, FAIL
);
432 switch (data
->ikev2
.state
) {
434 /* SA_INIT was sent out, so message have to be
435 * integrity protected from now on. */
436 data
->keys_ready
= 1;
439 if (data
->state
== FAIL
)
441 wpa_printf(MSG_DEBUG
, "EAP-IKEV2: Authentication completed "
443 if (eap_ikev2_server_keymat(data
))
445 eap_ikev2_state(data
, DONE
);
451 if (data
->in_buf
!= &tmpbuf
)
452 wpabuf_free(data
->in_buf
);
457 static Boolean
eap_ikev2_isDone(struct eap_sm
*sm
, void *priv
)
459 struct eap_ikev2_data
*data
= priv
;
460 return data
->state
== DONE
|| data
->state
== FAIL
;
464 static Boolean
eap_ikev2_isSuccess(struct eap_sm
*sm
, void *priv
)
466 struct eap_ikev2_data
*data
= priv
;
467 return data
->state
== DONE
&& data
->ikev2
.state
== IKEV2_DONE
&&
472 static u8
* eap_ikev2_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
474 struct eap_ikev2_data
*data
= priv
;
477 if (data
->state
!= DONE
|| !data
->keymat_ok
)
480 key
= os_malloc(EAP_MSK_LEN
);
482 os_memcpy(key
, data
->keymat
, EAP_MSK_LEN
);
490 static u8
* eap_ikev2_get_emsk(struct eap_sm
*sm
, void *priv
, size_t *len
)
492 struct eap_ikev2_data
*data
= priv
;
495 if (data
->state
!= DONE
|| !data
->keymat_ok
)
498 key
= os_malloc(EAP_EMSK_LEN
);
500 os_memcpy(key
, data
->keymat
+ EAP_MSK_LEN
, EAP_EMSK_LEN
);
508 int eap_server_ikev2_register(void)
510 struct eap_method
*eap
;
513 eap
= eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION
,
514 EAP_VENDOR_IETF
, EAP_TYPE_IKEV2
,
519 eap
->init
= eap_ikev2_init
;
520 eap
->reset
= eap_ikev2_reset
;
521 eap
->buildReq
= eap_ikev2_buildReq
;
522 eap
->check
= eap_ikev2_check
;
523 eap
->process
= eap_ikev2_process
;
524 eap
->isDone
= eap_ikev2_isDone
;
525 eap
->getKey
= eap_ikev2_getKey
;
526 eap
->isSuccess
= eap_ikev2_isSuccess
;
527 eap
->get_emsk
= eap_ikev2_get_emsk
;
529 ret
= eap_server_method_register(eap
);
531 eap_server_method_free(eap
);