xref: /freebsd/contrib/wpa/src/eap_server/eap_server_ikev2.c (revision 6472ac3d8a86336899b6cfb789a4cd9897e3fab5)
1 /*
2  * EAP-IKEv2 server (RFC 5106)
3  * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "eap_i.h"
19 #include "eap_common/eap_ikev2_common.h"
20 #include "ikev2.h"
21 
22 
23 struct eap_ikev2_data {
24 	struct ikev2_initiator_data ikev2;
25 	enum { MSG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
26 	struct wpabuf *in_buf;
27 	struct wpabuf *out_buf;
28 	size_t out_used;
29 	size_t fragment_size;
30 	int keys_ready;
31 	u8 keymat[EAP_MSK_LEN + EAP_EMSK_LEN];
32 	int keymat_ok;
33 };
34 
35 
36 static const u8 * eap_ikev2_get_shared_secret(void *ctx, const u8 *IDr,
37 					      size_t IDr_len,
38 					      size_t *secret_len)
39 {
40 	struct eap_sm *sm = ctx;
41 
42 	if (IDr == NULL) {
43 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: No IDr received - default "
44 			   "to user identity from EAP-Identity");
45 		IDr = sm->identity;
46 		IDr_len = sm->identity_len;
47 	}
48 
49 	if (eap_user_get(sm, IDr, IDr_len, 0) < 0 || sm->user == NULL ||
50 	    sm->user->password == NULL) {
51 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: No user entry found");
52 		return NULL;
53 	}
54 
55 	*secret_len = sm->user->password_len;
56 	return sm->user->password;
57 }
58 
59 
60 static const char * eap_ikev2_state_txt(int state)
61 {
62 	switch (state) {
63 	case MSG:
64 		return "MSG";
65 	case FRAG_ACK:
66 		return "FRAG_ACK";
67 	case WAIT_FRAG_ACK:
68 		return "WAIT_FRAG_ACK";
69 	case DONE:
70 		return "DONE";
71 	case FAIL:
72 		return "FAIL";
73 	default:
74 		return "?";
75 	}
76 }
77 
78 
79 static void eap_ikev2_state(struct eap_ikev2_data *data, int state)
80 {
81 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: %s -> %s",
82 		   eap_ikev2_state_txt(data->state),
83 		   eap_ikev2_state_txt(state));
84 	data->state = state;
85 }
86 
87 
88 static void * eap_ikev2_init(struct eap_sm *sm)
89 {
90 	struct eap_ikev2_data *data;
91 
92 	data = os_zalloc(sizeof(*data));
93 	if (data == NULL)
94 		return NULL;
95 	data->state = MSG;
96 	data->fragment_size = IKEV2_FRAGMENT_SIZE;
97 	data->ikev2.state = SA_INIT;
98 	data->ikev2.peer_auth = PEER_AUTH_SECRET;
99 	data->ikev2.key_pad = (u8 *) os_strdup("Key Pad for EAP-IKEv2");
100 	if (data->ikev2.key_pad == NULL)
101 		goto failed;
102 	data->ikev2.key_pad_len = 21;
103 
104 	/* TODO: make proposals configurable */
105 	data->ikev2.proposal.proposal_num = 1;
106 	data->ikev2.proposal.integ = AUTH_HMAC_SHA1_96;
107 	data->ikev2.proposal.prf = PRF_HMAC_SHA1;
108 	data->ikev2.proposal.encr = ENCR_AES_CBC;
109 	data->ikev2.proposal.dh = DH_GROUP2_1024BIT_MODP;
110 
111 	data->ikev2.IDi = (u8 *) os_strdup("hostapd");
112 	data->ikev2.IDi_len = 7;
113 
114 	data->ikev2.get_shared_secret = eap_ikev2_get_shared_secret;
115 	data->ikev2.cb_ctx = sm;
116 
117 	return data;
118 
119 failed:
120 	ikev2_initiator_deinit(&data->ikev2);
121 	os_free(data);
122 	return NULL;
123 }
124 
125 
126 static void eap_ikev2_reset(struct eap_sm *sm, void *priv)
127 {
128 	struct eap_ikev2_data *data = priv;
129 	wpabuf_free(data->in_buf);
130 	wpabuf_free(data->out_buf);
131 	ikev2_initiator_deinit(&data->ikev2);
132 	os_free(data);
133 }
134 
135 
136 static struct wpabuf * eap_ikev2_build_msg(struct eap_ikev2_data *data, u8 id)
137 {
138 	struct wpabuf *req;
139 	u8 flags;
140 	size_t send_len, plen, icv_len = 0;
141 
142 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Generating Request");
143 
144 	flags = 0;
145 	send_len = wpabuf_len(data->out_buf) - data->out_used;
146 	if (1 + send_len > data->fragment_size) {
147 		send_len = data->fragment_size - 1;
148 		flags |= IKEV2_FLAGS_MORE_FRAGMENTS;
149 		if (data->out_used == 0) {
150 			flags |= IKEV2_FLAGS_LENGTH_INCLUDED;
151 			send_len -= 4;
152 		}
153 	}
154 
155 	plen = 1 + send_len;
156 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
157 		plen += 4;
158 	if (data->keys_ready) {
159 		const struct ikev2_integ_alg *integ;
160 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Add Integrity Checksum "
161 			   "Data");
162 		flags |= IKEV2_FLAGS_ICV_INCLUDED;
163 		integ = ikev2_get_integ(data->ikev2.proposal.integ);
164 		if (integ == NULL) {
165 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
166 				   "transform / cannot generate ICV");
167 			return NULL;
168 		}
169 		icv_len = integ->hash_len;
170 
171 		plen += icv_len;
172 	}
173 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, plen,
174 			    EAP_CODE_REQUEST, id);
175 	if (req == NULL)
176 		return NULL;
177 
178 	wpabuf_put_u8(req, flags); /* Flags */
179 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
180 		wpabuf_put_be32(req, wpabuf_len(data->out_buf));
181 
182 	wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used,
183 			send_len);
184 	data->out_used += send_len;
185 
186 	if (flags & IKEV2_FLAGS_ICV_INCLUDED) {
187 		const u8 *msg = wpabuf_head(req);
188 		size_t len = wpabuf_len(req);
189 		ikev2_integ_hash(data->ikev2.proposal.integ,
190 				 data->ikev2.keys.SK_ai,
191 				 data->ikev2.keys.SK_integ_len,
192 				 msg, len, wpabuf_put(req, icv_len));
193 	}
194 
195 	if (data->out_used == wpabuf_len(data->out_buf)) {
196 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes "
197 			   "(message sent completely)",
198 			   (unsigned long) send_len);
199 		wpabuf_free(data->out_buf);
200 		data->out_buf = NULL;
201 		data->out_used = 0;
202 	} else {
203 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes "
204 			   "(%lu more to send)", (unsigned long) send_len,
205 			   (unsigned long) wpabuf_len(data->out_buf) -
206 			   data->out_used);
207 		eap_ikev2_state(data, WAIT_FRAG_ACK);
208 	}
209 
210 	return req;
211 }
212 
213 
214 static struct wpabuf * eap_ikev2_buildReq(struct eap_sm *sm, void *priv, u8 id)
215 {
216 	struct eap_ikev2_data *data = priv;
217 
218 	switch (data->state) {
219 	case MSG:
220 		if (data->out_buf == NULL) {
221 			data->out_buf = ikev2_initiator_build(&data->ikev2);
222 			if (data->out_buf == NULL) {
223 				wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to "
224 					   "generate IKEv2 message");
225 				return NULL;
226 			}
227 			data->out_used = 0;
228 		}
229 		/* pass through */
230 	case WAIT_FRAG_ACK:
231 		return eap_ikev2_build_msg(data, id);
232 	case FRAG_ACK:
233 		return eap_ikev2_build_frag_ack(id, EAP_CODE_REQUEST);
234 	default:
235 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected state %d in "
236 			   "buildReq", data->state);
237 		return NULL;
238 	}
239 }
240 
241 
242 static Boolean eap_ikev2_check(struct eap_sm *sm, void *priv,
243 			       struct wpabuf *respData)
244 {
245 	const u8 *pos;
246 	size_t len;
247 
248 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData,
249 			       &len);
250 	if (pos == NULL) {
251 		wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid frame");
252 		return TRUE;
253 	}
254 
255 	return FALSE;
256 }
257 
258 
259 static int eap_ikev2_process_icv(struct eap_ikev2_data *data,
260 				 const struct wpabuf *respData,
261 				 u8 flags, const u8 *pos, const u8 **end)
262 {
263 	if (flags & IKEV2_FLAGS_ICV_INCLUDED) {
264 		int icv_len = eap_ikev2_validate_icv(
265 			data->ikev2.proposal.integ, &data->ikev2.keys, 0,
266 			respData, pos, *end);
267 		if (icv_len < 0)
268 			return -1;
269 		/* Hide Integrity Checksum Data from further processing */
270 		*end -= icv_len;
271 	} else if (data->keys_ready) {
272 		wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have "
273 			   "included integrity checksum");
274 		return -1;
275 	}
276 
277 	return 0;
278 }
279 
280 
281 static int eap_ikev2_process_cont(struct eap_ikev2_data *data,
282 				  const u8 *buf, size_t len)
283 {
284 	/* Process continuation of a pending message */
285 	if (len > wpabuf_tailroom(data->in_buf)) {
286 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment overflow");
287 		eap_ikev2_state(data, FAIL);
288 		return -1;
289 	}
290 
291 	wpabuf_put_data(data->in_buf, buf, len);
292 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes, waiting for %lu "
293 		   "bytes more", (unsigned long) len,
294 		   (unsigned long) wpabuf_tailroom(data->in_buf));
295 
296 	return 0;
297 }
298 
299 
300 static int eap_ikev2_process_fragment(struct eap_ikev2_data *data,
301 				      u8 flags, u32 message_length,
302 				      const u8 *buf, size_t len)
303 {
304 	/* Process a fragment that is not the last one of the message */
305 	if (data->in_buf == NULL && !(flags & IKEV2_FLAGS_LENGTH_INCLUDED)) {
306 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: No Message Length field in "
307 			   "a fragmented packet");
308 		return -1;
309 	}
310 
311 	if (data->in_buf == NULL) {
312 		/* First fragment of the message */
313 		data->in_buf = wpabuf_alloc(message_length);
314 		if (data->in_buf == NULL) {
315 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for "
316 				   "message");
317 			return -1;
318 		}
319 		wpabuf_put_data(data->in_buf, buf, len);
320 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first "
321 			   "fragment, waiting for %lu bytes more",
322 			   (unsigned long) len,
323 			   (unsigned long) wpabuf_tailroom(data->in_buf));
324 	}
325 
326 	return 0;
327 }
328 
329 
330 static int eap_ikev2_server_keymat(struct eap_ikev2_data *data)
331 {
332 	if (eap_ikev2_derive_keymat(
333 		    data->ikev2.proposal.prf, &data->ikev2.keys,
334 		    data->ikev2.i_nonce, data->ikev2.i_nonce_len,
335 		    data->ikev2.r_nonce, data->ikev2.r_nonce_len,
336 		    data->keymat) < 0) {
337 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to derive "
338 			   "key material");
339 		return -1;
340 	}
341 	data->keymat_ok = 1;
342 	return 0;
343 }
344 
345 
346 static void eap_ikev2_process(struct eap_sm *sm, void *priv,
347 			      struct wpabuf *respData)
348 {
349 	struct eap_ikev2_data *data = priv;
350 	const u8 *start, *pos, *end;
351 	size_t len;
352 	u8 flags;
353 	u32 message_length = 0;
354 	struct wpabuf tmpbuf;
355 
356 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData,
357 			       &len);
358 	if (pos == NULL)
359 		return; /* Should not happen; message already verified */
360 
361 	start = pos;
362 	end = start + len;
363 
364 	if (len == 0) {
365 		/* fragment ack */
366 		flags = 0;
367 	} else
368 		flags = *pos++;
369 
370 	if (eap_ikev2_process_icv(data, respData, flags, pos, &end) < 0) {
371 		eap_ikev2_state(data, FAIL);
372 		return;
373 	}
374 
375 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) {
376 		if (end - pos < 4) {
377 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow");
378 			eap_ikev2_state(data, FAIL);
379 			return;
380 		}
381 		message_length = WPA_GET_BE32(pos);
382 		pos += 4;
383 
384 		if (message_length < (u32) (end - pos)) {
385 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Invalid Message "
386 				   "Length (%d; %ld remaining in this msg)",
387 				   message_length, (long) (end - pos));
388 			eap_ikev2_state(data, FAIL);
389 			return;
390 		}
391 	}
392 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x "
393 		   "Message Length %u", flags, message_length);
394 
395 	if (data->state == WAIT_FRAG_ACK) {
396 		if (len != 0) {
397 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload "
398 				   "in WAIT_FRAG_ACK state");
399 			eap_ikev2_state(data, FAIL);
400 			return;
401 		}
402 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged");
403 		eap_ikev2_state(data, MSG);
404 		return;
405 	}
406 
407 	if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) {
408 		eap_ikev2_state(data, FAIL);
409 		return;
410 	}
411 
412 	if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) {
413 		if (eap_ikev2_process_fragment(data, flags, message_length,
414 					       pos, end - pos) < 0)
415 			eap_ikev2_state(data, FAIL);
416 		else
417 			eap_ikev2_state(data, FRAG_ACK);
418 		return;
419 	} else if (data->state == FRAG_ACK) {
420 		wpa_printf(MSG_DEBUG, "EAP-TNC: All fragments received");
421 		data->state = MSG;
422 	}
423 
424 	if (data->in_buf == NULL) {
425 		/* Wrap unfragmented messages as wpabuf without extra copy */
426 		wpabuf_set(&tmpbuf, pos, end - pos);
427 		data->in_buf = &tmpbuf;
428 	}
429 
430 	if (ikev2_initiator_process(&data->ikev2, data->in_buf) < 0) {
431 		if (data->in_buf == &tmpbuf)
432 			data->in_buf = NULL;
433 		eap_ikev2_state(data, FAIL);
434 		return;
435 	}
436 
437 	switch (data->ikev2.state) {
438 	case SA_AUTH:
439 		/* SA_INIT was sent out, so message have to be
440 		 * integrity protected from now on. */
441 		data->keys_ready = 1;
442 		break;
443 	case IKEV2_DONE:
444 		if (data->state == FAIL)
445 			break;
446 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication completed "
447 			   "successfully");
448 		if (eap_ikev2_server_keymat(data))
449 			break;
450 		eap_ikev2_state(data, DONE);
451 		break;
452 	default:
453 		break;
454 	}
455 
456 	if (data->in_buf != &tmpbuf)
457 		wpabuf_free(data->in_buf);
458 	data->in_buf = NULL;
459 }
460 
461 
462 static Boolean eap_ikev2_isDone(struct eap_sm *sm, void *priv)
463 {
464 	struct eap_ikev2_data *data = priv;
465 	return data->state == DONE || data->state == FAIL;
466 }
467 
468 
469 static Boolean eap_ikev2_isSuccess(struct eap_sm *sm, void *priv)
470 {
471 	struct eap_ikev2_data *data = priv;
472 	return data->state == DONE && data->ikev2.state == IKEV2_DONE &&
473 		data->keymat_ok;
474 }
475 
476 
477 static u8 * eap_ikev2_getKey(struct eap_sm *sm, void *priv, size_t *len)
478 {
479 	struct eap_ikev2_data *data = priv;
480 	u8 *key;
481 
482 	if (data->state != DONE || !data->keymat_ok)
483 		return NULL;
484 
485 	key = os_malloc(EAP_MSK_LEN);
486 	if (key) {
487 		os_memcpy(key, data->keymat, EAP_MSK_LEN);
488 		*len = EAP_MSK_LEN;
489 	}
490 
491 	return key;
492 }
493 
494 
495 static u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
496 {
497 	struct eap_ikev2_data *data = priv;
498 	u8 *key;
499 
500 	if (data->state != DONE || !data->keymat_ok)
501 		return NULL;
502 
503 	key = os_malloc(EAP_EMSK_LEN);
504 	if (key) {
505 		os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN);
506 		*len = EAP_EMSK_LEN;
507 	}
508 
509 	return key;
510 }
511 
512 
513 int eap_server_ikev2_register(void)
514 {
515 	struct eap_method *eap;
516 	int ret;
517 
518 	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
519 				      EAP_VENDOR_IETF, EAP_TYPE_IKEV2,
520 				      "IKEV2");
521 	if (eap == NULL)
522 		return -1;
523 
524 	eap->init = eap_ikev2_init;
525 	eap->reset = eap_ikev2_reset;
526 	eap->buildReq = eap_ikev2_buildReq;
527 	eap->check = eap_ikev2_check;
528 	eap->process = eap_ikev2_process;
529 	eap->isDone = eap_ikev2_isDone;
530 	eap->getKey = eap_ikev2_getKey;
531 	eap->isSuccess = eap_ikev2_isSuccess;
532 	eap->get_emsk = eap_ikev2_get_emsk;
533 
534 	ret = eap_server_method_register(eap);
535 	if (ret)
536 		eap_server_method_free(eap);
537 	return ret;
538 }
539