Home | History | Annotate | Download | only in eap_server
      1 /*
      2  * EAP-IKEv2 server (RFC 5106)
      3  * Copyright (c) 2007, Jouni Malinen <j (at) 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