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 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