xref: /freebsd/contrib/wpa/src/eap_server/eap_server_ikev2.c (revision 2f1217877e155a8a7de97e74eb7e82096a5ef316)
1 /*
2  * EAP-IKEv2 server (RFC 5106)
3  * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "eap_i.h"
13 #include "eap_common/eap_ikev2_common.h"
14 #include "ikev2.h"
15 
16 
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;
22 	size_t out_used;
23 	size_t fragment_size;
24 	int keys_ready;
25 	u8 keymat[EAP_MSK_LEN + EAP_EMSK_LEN];
26 	int keymat_ok;
27 };
28 
29 
30 static const u8 * eap_ikev2_get_shared_secret(void *ctx, const u8 *IDr,
31 					      size_t IDr_len,
32 					      size_t *secret_len)
33 {
34 	struct eap_sm *sm = ctx;
35 
36 	if (IDr == NULL) {
37 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: No IDr received - default "
38 			   "to user identity from EAP-Identity");
39 		IDr = sm->identity;
40 		IDr_len = sm->identity_len;
41 	}
42 
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");
46 		return NULL;
47 	}
48 
49 	*secret_len = sm->user->password_len;
50 	return sm->user->password;
51 }
52 
53 
54 static const char * eap_ikev2_state_txt(int state)
55 {
56 	switch (state) {
57 	case MSG:
58 		return "MSG";
59 	case FRAG_ACK:
60 		return "FRAG_ACK";
61 	case WAIT_FRAG_ACK:
62 		return "WAIT_FRAG_ACK";
63 	case DONE:
64 		return "DONE";
65 	case FAIL:
66 		return "FAIL";
67 	default:
68 		return "?";
69 	}
70 }
71 
72 
73 static void eap_ikev2_state(struct eap_ikev2_data *data, int state)
74 {
75 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: %s -> %s",
76 		   eap_ikev2_state_txt(data->state),
77 		   eap_ikev2_state_txt(state));
78 	data->state = state;
79 }
80 
81 
82 static void * eap_ikev2_init(struct eap_sm *sm)
83 {
84 	struct eap_ikev2_data *data;
85 
86 	data = os_zalloc(sizeof(*data));
87 	if (data == NULL)
88 		return NULL;
89 	data->state = MSG;
90 	data->fragment_size = sm->fragment_size > 0 ? sm->fragment_size :
91 		IKEV2_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)
96 		goto failed;
97 	data->ikev2.key_pad_len = 21;
98 
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;
105 
106 	data->ikev2.IDi = (u8 *) os_strdup("hostapd");
107 	data->ikev2.IDi_len = 7;
108 
109 	data->ikev2.get_shared_secret = eap_ikev2_get_shared_secret;
110 	data->ikev2.cb_ctx = sm;
111 
112 	return data;
113 
114 failed:
115 	ikev2_initiator_deinit(&data->ikev2);
116 	os_free(data);
117 	return NULL;
118 }
119 
120 
121 static void eap_ikev2_reset(struct eap_sm *sm, void *priv)
122 {
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);
127 	os_free(data);
128 }
129 
130 
131 static struct wpabuf * eap_ikev2_build_msg(struct eap_ikev2_data *data, u8 id)
132 {
133 	struct wpabuf *req;
134 	u8 flags;
135 	size_t send_len, plen, icv_len = 0;
136 
137 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Generating Request");
138 
139 	flags = 0;
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;
146 			send_len -= 4;
147 		}
148 	}
149 
150 	plen = 1 + send_len;
151 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
152 		plen += 4;
153 	if (data->keys_ready) {
154 		const struct ikev2_integ_alg *integ;
155 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Add Integrity Checksum "
156 			   "Data");
157 		flags |= IKEV2_FLAGS_ICV_INCLUDED;
158 		integ = ikev2_get_integ(data->ikev2.proposal.integ);
159 		if (integ == NULL) {
160 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
161 				   "transform / cannot generate ICV");
162 			return NULL;
163 		}
164 		icv_len = integ->hash_len;
165 
166 		plen += icv_len;
167 	}
168 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, plen,
169 			    EAP_CODE_REQUEST, id);
170 	if (req == NULL)
171 		return NULL;
172 
173 	wpabuf_put_u8(req, flags); /* Flags */
174 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
175 		wpabuf_put_be32(req, wpabuf_len(data->out_buf));
176 
177 	wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used,
178 			send_len);
179 	data->out_used += send_len;
180 
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));
188 	}
189 
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;
196 		data->out_used = 0;
197 	} else {
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) -
201 			   data->out_used);
202 		eap_ikev2_state(data, WAIT_FRAG_ACK);
203 	}
204 
205 	return req;
206 }
207 
208 
209 static struct wpabuf * eap_ikev2_buildReq(struct eap_sm *sm, void *priv, u8 id)
210 {
211 	struct eap_ikev2_data *data = priv;
212 
213 	switch (data->state) {
214 	case MSG:
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");
220 				return NULL;
221 			}
222 			data->out_used = 0;
223 		}
224 		/* pass through */
225 	case WAIT_FRAG_ACK:
226 		return eap_ikev2_build_msg(data, id);
227 	case FRAG_ACK:
228 		return eap_ikev2_build_frag_ack(id, EAP_CODE_REQUEST);
229 	default:
230 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected state %d in "
231 			   "buildReq", data->state);
232 		return NULL;
233 	}
234 }
235 
236 
237 static Boolean eap_ikev2_check(struct eap_sm *sm, void *priv,
238 			       struct wpabuf *respData)
239 {
240 	const u8 *pos;
241 	size_t len;
242 
243 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData,
244 			       &len);
245 	if (pos == NULL) {
246 		wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid frame");
247 		return TRUE;
248 	}
249 
250 	return FALSE;
251 }
252 
253 
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)
257 {
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);
262 		if (icv_len < 0)
263 			return -1;
264 		/* Hide Integrity Checksum Data from further processing */
265 		*end -= icv_len;
266 	} else if (data->keys_ready) {
267 		wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have "
268 			   "included integrity checksum");
269 		return -1;
270 	}
271 
272 	return 0;
273 }
274 
275 
276 static int eap_ikev2_process_cont(struct eap_ikev2_data *data,
277 				  const u8 *buf, size_t len)
278 {
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);
283 		return -1;
284 	}
285 
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));
290 
291 	return 0;
292 }
293 
294 
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)
298 {
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");
303 		return -1;
304 	}
305 
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 "
311 				   "message");
312 			return -1;
313 		}
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",
317 			   (unsigned long) len,
318 			   (unsigned long) wpabuf_tailroom(data->in_buf));
319 	}
320 
321 	return 0;
322 }
323 
324 
325 static int eap_ikev2_server_keymat(struct eap_ikev2_data *data)
326 {
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,
331 		    data->keymat) < 0) {
332 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to derive "
333 			   "key material");
334 		return -1;
335 	}
336 	data->keymat_ok = 1;
337 	return 0;
338 }
339 
340 
341 static void eap_ikev2_process(struct eap_sm *sm, void *priv,
342 			      struct wpabuf *respData)
343 {
344 	struct eap_ikev2_data *data = priv;
345 	const u8 *start, *pos, *end;
346 	size_t len;
347 	u8 flags;
348 	u32 message_length = 0;
349 	struct wpabuf tmpbuf;
350 
351 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData,
352 			       &len);
353 	if (pos == NULL)
354 		return; /* Should not happen; message already verified */
355 
356 	start = pos;
357 	end = start + len;
358 
359 	if (len == 0) {
360 		/* fragment ack */
361 		flags = 0;
362 	} else
363 		flags = *pos++;
364 
365 	if (eap_ikev2_process_icv(data, respData, flags, pos, &end) < 0) {
366 		eap_ikev2_state(data, FAIL);
367 		return;
368 	}
369 
370 	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) {
371 		if (end - pos < 4) {
372 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow");
373 			eap_ikev2_state(data, FAIL);
374 			return;
375 		}
376 		message_length = WPA_GET_BE32(pos);
377 		pos += 4;
378 
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);
384 			return;
385 		}
386 	}
387 	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x "
388 		   "Message Length %u", flags, message_length);
389 
390 	if (data->state == WAIT_FRAG_ACK) {
391 		if (len != 0) {
392 			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload "
393 				   "in WAIT_FRAG_ACK state");
394 			eap_ikev2_state(data, FAIL);
395 			return;
396 		}
397 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged");
398 		eap_ikev2_state(data, MSG);
399 		return;
400 	}
401 
402 	if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) {
403 		eap_ikev2_state(data, FAIL);
404 		return;
405 	}
406 
407 	if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) {
408 		if (eap_ikev2_process_fragment(data, flags, message_length,
409 					       pos, end - pos) < 0)
410 			eap_ikev2_state(data, FAIL);
411 		else
412 			eap_ikev2_state(data, FRAG_ACK);
413 		return;
414 	} else if (data->state == FRAG_ACK) {
415 		wpa_printf(MSG_DEBUG, "EAP-TNC: All fragments received");
416 		data->state = MSG;
417 	}
418 
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;
423 	}
424 
425 	if (ikev2_initiator_process(&data->ikev2, data->in_buf) < 0) {
426 		if (data->in_buf == &tmpbuf)
427 			data->in_buf = NULL;
428 		eap_ikev2_state(data, FAIL);
429 		return;
430 	}
431 
432 	switch (data->ikev2.state) {
433 	case SA_AUTH:
434 		/* SA_INIT was sent out, so message have to be
435 		 * integrity protected from now on. */
436 		data->keys_ready = 1;
437 		break;
438 	case IKEV2_DONE:
439 		if (data->state == FAIL)
440 			break;
441 		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication completed "
442 			   "successfully");
443 		if (eap_ikev2_server_keymat(data))
444 			break;
445 		eap_ikev2_state(data, DONE);
446 		break;
447 	default:
448 		break;
449 	}
450 
451 	if (data->in_buf != &tmpbuf)
452 		wpabuf_free(data->in_buf);
453 	data->in_buf = NULL;
454 }
455 
456 
457 static Boolean eap_ikev2_isDone(struct eap_sm *sm, void *priv)
458 {
459 	struct eap_ikev2_data *data = priv;
460 	return data->state == DONE || data->state == FAIL;
461 }
462 
463 
464 static Boolean eap_ikev2_isSuccess(struct eap_sm *sm, void *priv)
465 {
466 	struct eap_ikev2_data *data = priv;
467 	return data->state == DONE && data->ikev2.state == IKEV2_DONE &&
468 		data->keymat_ok;
469 }
470 
471 
472 static u8 * eap_ikev2_getKey(struct eap_sm *sm, void *priv, size_t *len)
473 {
474 	struct eap_ikev2_data *data = priv;
475 	u8 *key;
476 
477 	if (data->state != DONE || !data->keymat_ok)
478 		return NULL;
479 
480 	key = os_malloc(EAP_MSK_LEN);
481 	if (key) {
482 		os_memcpy(key, data->keymat, EAP_MSK_LEN);
483 		*len = EAP_MSK_LEN;
484 	}
485 
486 	return key;
487 }
488 
489 
490 static u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
491 {
492 	struct eap_ikev2_data *data = priv;
493 	u8 *key;
494 
495 	if (data->state != DONE || !data->keymat_ok)
496 		return NULL;
497 
498 	key = os_malloc(EAP_EMSK_LEN);
499 	if (key) {
500 		os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN);
501 		*len = EAP_EMSK_LEN;
502 	}
503 
504 	return key;
505 }
506 
507 
508 int eap_server_ikev2_register(void)
509 {
510 	struct eap_method *eap;
511 	int ret;
512 
513 	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
514 				      EAP_VENDOR_IETF, EAP_TYPE_IKEV2,
515 				      "IKEV2");
516 	if (eap == NULL)
517 		return -1;
518 
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;
528 
529 	ret = eap_server_method_register(eap);
530 	if (ret)
531 		eap_server_method_free(eap);
532 	return ret;
533 }
534