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 23struct 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 36static 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 60static 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 79static 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 88static 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 119failed: 120 ikev2_initiator_deinit(&data->ikev2); 121 os_free(data); 122 return NULL; 123} 124 125 126static 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 136static 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 214static 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 242static 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 259static 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 281static 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 300static 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 330static 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 346static 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 462static 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 469static 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 477static 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 495static 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 513int 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