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->cfg->fragment_size > 0 ? 91 sm->cfg->fragment_size : 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 = os_memdup(sm->cfg->server_id, sm->cfg->server_id_len); 107 if (data->ikev2.IDi == NULL) 108 goto failed; 109 data->ikev2.IDi_len = sm->cfg->server_id_len; 110 111 data->ikev2.get_shared_secret = eap_ikev2_get_shared_secret; 112 data->ikev2.cb_ctx = sm; 113 114 return data; 115 116 failed: 117 ikev2_initiator_deinit(&data->ikev2); 118 os_free(data); 119 return NULL; 120 } 121 122 123 static void eap_ikev2_reset(struct eap_sm *sm, void *priv) 124 { 125 struct eap_ikev2_data *data = priv; 126 wpabuf_free(data->in_buf); 127 wpabuf_free(data->out_buf); 128 ikev2_initiator_deinit(&data->ikev2); 129 bin_clear_free(data, sizeof(*data)); 130 } 131 132 133 static struct wpabuf * eap_ikev2_build_msg(struct eap_ikev2_data *data, u8 id) 134 { 135 struct wpabuf *req; 136 u8 flags; 137 size_t send_len, plen, icv_len = 0; 138 139 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Generating Request"); 140 141 flags = 0; 142 send_len = wpabuf_len(data->out_buf) - data->out_used; 143 if (1 + send_len > data->fragment_size) { 144 send_len = data->fragment_size - 1; 145 flags |= IKEV2_FLAGS_MORE_FRAGMENTS; 146 if (data->out_used == 0) { 147 flags |= IKEV2_FLAGS_LENGTH_INCLUDED; 148 send_len -= 4; 149 } 150 } 151 152 plen = 1 + send_len; 153 if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) 154 plen += 4; 155 if (data->keys_ready) { 156 const struct ikev2_integ_alg *integ; 157 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Add Integrity Checksum " 158 "Data"); 159 flags |= IKEV2_FLAGS_ICV_INCLUDED; 160 integ = ikev2_get_integ(data->ikev2.proposal.integ); 161 if (integ == NULL) { 162 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG " 163 "transform / cannot generate ICV"); 164 return NULL; 165 } 166 icv_len = integ->hash_len; 167 168 plen += icv_len; 169 } 170 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, plen, 171 EAP_CODE_REQUEST, id); 172 if (req == NULL) 173 return NULL; 174 175 wpabuf_put_u8(req, flags); /* Flags */ 176 if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) 177 wpabuf_put_be32(req, wpabuf_len(data->out_buf)); 178 179 wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used, 180 send_len); 181 data->out_used += send_len; 182 183 if (flags & IKEV2_FLAGS_ICV_INCLUDED) { 184 const u8 *msg = wpabuf_head(req); 185 size_t len = wpabuf_len(req); 186 ikev2_integ_hash(data->ikev2.proposal.integ, 187 data->ikev2.keys.SK_ai, 188 data->ikev2.keys.SK_integ_len, 189 msg, len, wpabuf_put(req, icv_len)); 190 } 191 192 if (data->out_used == wpabuf_len(data->out_buf)) { 193 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes " 194 "(message sent completely)", 195 (unsigned long) send_len); 196 wpabuf_free(data->out_buf); 197 data->out_buf = NULL; 198 data->out_used = 0; 199 } else { 200 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes " 201 "(%lu more to send)", (unsigned long) send_len, 202 (unsigned long) wpabuf_len(data->out_buf) - 203 data->out_used); 204 eap_ikev2_state(data, WAIT_FRAG_ACK); 205 } 206 207 return req; 208 } 209 210 211 static struct wpabuf * eap_ikev2_buildReq(struct eap_sm *sm, void *priv, u8 id) 212 { 213 struct eap_ikev2_data *data = priv; 214 215 switch (data->state) { 216 case MSG: 217 if (data->out_buf == NULL) { 218 data->out_buf = ikev2_initiator_build(&data->ikev2); 219 if (data->out_buf == NULL) { 220 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to " 221 "generate IKEv2 message"); 222 return NULL; 223 } 224 data->out_used = 0; 225 } 226 /* fall through */ 227 case WAIT_FRAG_ACK: 228 return eap_ikev2_build_msg(data, id); 229 case FRAG_ACK: 230 return eap_ikev2_build_frag_ack(id, EAP_CODE_REQUEST); 231 default: 232 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected state %d in " 233 "buildReq", data->state); 234 return NULL; 235 } 236 } 237 238 239 static bool eap_ikev2_check(struct eap_sm *sm, void *priv, 240 struct wpabuf *respData) 241 { 242 const u8 *pos; 243 size_t len; 244 245 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData, 246 &len); 247 if (pos == NULL) { 248 wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid frame"); 249 return true; 250 } 251 252 return false; 253 } 254 255 256 static int eap_ikev2_process_icv(struct eap_ikev2_data *data, 257 const struct wpabuf *respData, 258 u8 flags, const u8 *pos, const u8 **end, 259 int frag_ack) 260 { 261 if (flags & IKEV2_FLAGS_ICV_INCLUDED) { 262 int icv_len = eap_ikev2_validate_icv( 263 data->ikev2.proposal.integ, &data->ikev2.keys, 0, 264 respData, pos, *end); 265 if (icv_len < 0) 266 return -1; 267 /* Hide Integrity Checksum Data from further processing */ 268 *end -= icv_len; 269 } else if (data->keys_ready && !frag_ack) { 270 wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have " 271 "included integrity checksum"); 272 return -1; 273 } 274 275 return 0; 276 } 277 278 279 static int eap_ikev2_process_cont(struct eap_ikev2_data *data, 280 const u8 *buf, size_t len) 281 { 282 /* Process continuation of a pending message */ 283 if (len > wpabuf_tailroom(data->in_buf)) { 284 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment overflow"); 285 eap_ikev2_state(data, FAIL); 286 return -1; 287 } 288 289 wpabuf_put_data(data->in_buf, buf, len); 290 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes, waiting for %lu " 291 "bytes more", (unsigned long) len, 292 (unsigned long) wpabuf_tailroom(data->in_buf)); 293 294 return 0; 295 } 296 297 298 static int eap_ikev2_process_fragment(struct eap_ikev2_data *data, 299 u8 flags, u32 message_length, 300 const u8 *buf, size_t len) 301 { 302 /* Process a fragment that is not the last one of the message */ 303 if (data->in_buf == NULL && !(flags & IKEV2_FLAGS_LENGTH_INCLUDED)) { 304 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No Message Length field in " 305 "a fragmented packet"); 306 return -1; 307 } 308 309 if (data->in_buf == NULL) { 310 /* First fragment of the message */ 311 if (message_length > 50000) { 312 /* Limit maximum memory allocation */ 313 wpa_printf(MSG_DEBUG, 314 "EAP-IKEV2: Ignore too long message"); 315 return -1; 316 } 317 data->in_buf = wpabuf_alloc(message_length); 318 if (data->in_buf == NULL) { 319 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for " 320 "message"); 321 return -1; 322 } 323 wpabuf_put_data(data->in_buf, buf, len); 324 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first " 325 "fragment, waiting for %lu bytes more", 326 (unsigned long) len, 327 (unsigned long) wpabuf_tailroom(data->in_buf)); 328 } 329 330 return 0; 331 } 332 333 334 static int eap_ikev2_server_keymat(struct eap_ikev2_data *data) 335 { 336 if (eap_ikev2_derive_keymat( 337 data->ikev2.proposal.prf, &data->ikev2.keys, 338 data->ikev2.i_nonce, data->ikev2.i_nonce_len, 339 data->ikev2.r_nonce, data->ikev2.r_nonce_len, 340 data->keymat) < 0) { 341 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to derive " 342 "key material"); 343 return -1; 344 } 345 data->keymat_ok = 1; 346 return 0; 347 } 348 349 350 static void eap_ikev2_process(struct eap_sm *sm, void *priv, 351 struct wpabuf *respData) 352 { 353 struct eap_ikev2_data *data = priv; 354 const u8 *start, *pos, *end; 355 size_t len; 356 u8 flags; 357 u32 message_length = 0; 358 struct wpabuf tmpbuf; 359 360 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData, 361 &len); 362 if (pos == NULL) 363 return; /* Should not happen; message already verified */ 364 365 start = pos; 366 end = start + len; 367 368 if (len == 0) { 369 /* fragment ack */ 370 flags = 0; 371 } else 372 flags = *pos++; 373 374 if (eap_ikev2_process_icv(data, respData, flags, pos, &end, 375 data->state == WAIT_FRAG_ACK && len == 0) < 0) 376 { 377 eap_ikev2_state(data, FAIL); 378 return; 379 } 380 381 if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) { 382 if (end - pos < 4) { 383 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow"); 384 eap_ikev2_state(data, FAIL); 385 return; 386 } 387 message_length = WPA_GET_BE32(pos); 388 pos += 4; 389 390 if (message_length < (u32) (end - pos)) { 391 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Invalid Message " 392 "Length (%d; %ld remaining in this msg)", 393 message_length, (long) (end - pos)); 394 eap_ikev2_state(data, FAIL); 395 return; 396 } 397 } 398 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x " 399 "Message Length %u", flags, message_length); 400 401 if (data->state == WAIT_FRAG_ACK) { 402 if (len != 0) { 403 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload " 404 "in WAIT_FRAG_ACK state"); 405 eap_ikev2_state(data, FAIL); 406 return; 407 } 408 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged"); 409 eap_ikev2_state(data, MSG); 410 return; 411 } 412 413 if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) { 414 eap_ikev2_state(data, FAIL); 415 return; 416 } 417 418 if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) { 419 if (eap_ikev2_process_fragment(data, flags, message_length, 420 pos, end - pos) < 0) 421 eap_ikev2_state(data, FAIL); 422 else 423 eap_ikev2_state(data, FRAG_ACK); 424 return; 425 } else if (data->state == FRAG_ACK) { 426 wpa_printf(MSG_DEBUG, "EAP-TNC: All fragments received"); 427 data->state = MSG; 428 } 429 430 if (data->in_buf == NULL) { 431 /* Wrap unfragmented messages as wpabuf without extra copy */ 432 wpabuf_set(&tmpbuf, pos, end - pos); 433 data->in_buf = &tmpbuf; 434 } 435 436 if (ikev2_initiator_process(&data->ikev2, data->in_buf) < 0) { 437 if (data->in_buf == &tmpbuf) 438 data->in_buf = NULL; 439 eap_ikev2_state(data, FAIL); 440 return; 441 } 442 443 switch (data->ikev2.state) { 444 case SA_AUTH: 445 /* SA_INIT was sent out, so message have to be 446 * integrity protected from now on. */ 447 data->keys_ready = 1; 448 break; 449 case IKEV2_DONE: 450 if (data->state == FAIL) 451 break; 452 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication completed " 453 "successfully"); 454 if (eap_ikev2_server_keymat(data)) 455 break; 456 eap_ikev2_state(data, DONE); 457 break; 458 default: 459 break; 460 } 461 462 if (data->in_buf != &tmpbuf) 463 wpabuf_free(data->in_buf); 464 data->in_buf = NULL; 465 } 466 467 468 static bool eap_ikev2_isDone(struct eap_sm *sm, void *priv) 469 { 470 struct eap_ikev2_data *data = priv; 471 return data->state == DONE || data->state == FAIL; 472 } 473 474 475 static bool eap_ikev2_isSuccess(struct eap_sm *sm, void *priv) 476 { 477 struct eap_ikev2_data *data = priv; 478 return data->state == DONE && data->ikev2.state == IKEV2_DONE && 479 data->keymat_ok; 480 } 481 482 483 static u8 * eap_ikev2_getKey(struct eap_sm *sm, void *priv, size_t *len) 484 { 485 struct eap_ikev2_data *data = priv; 486 u8 *key; 487 488 if (data->state != DONE || !data->keymat_ok) 489 return NULL; 490 491 key = os_malloc(EAP_MSK_LEN); 492 if (key) { 493 os_memcpy(key, data->keymat, EAP_MSK_LEN); 494 *len = EAP_MSK_LEN; 495 } 496 497 return key; 498 } 499 500 501 static u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 502 { 503 struct eap_ikev2_data *data = priv; 504 u8 *key; 505 506 if (data->state != DONE || !data->keymat_ok) 507 return NULL; 508 509 key = os_malloc(EAP_EMSK_LEN); 510 if (key) { 511 os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN); 512 *len = EAP_EMSK_LEN; 513 } 514 515 return key; 516 } 517 518 519 static u8 * eap_ikev2_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 520 { 521 struct eap_ikev2_data *data = priv; 522 u8 *sid; 523 size_t sid_len; 524 size_t offset; 525 526 if (data->state != DONE || !data->keymat_ok) 527 return NULL; 528 529 sid_len = 1 + data->ikev2.i_nonce_len + data->ikev2.r_nonce_len; 530 sid = os_malloc(sid_len); 531 if (sid) { 532 offset = 0; 533 sid[offset] = EAP_TYPE_IKEV2; 534 offset++; 535 os_memcpy(sid + offset, data->ikev2.i_nonce, 536 data->ikev2.i_nonce_len); 537 offset += data->ikev2.i_nonce_len; 538 os_memcpy(sid + offset, data->ikev2.r_nonce, 539 data->ikev2.r_nonce_len); 540 *len = sid_len; 541 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Derived Session-Id", 542 sid, sid_len); 543 } 544 545 return sid; 546 } 547 548 549 int eap_server_ikev2_register(void) 550 { 551 struct eap_method *eap; 552 553 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 554 EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 555 "IKEV2"); 556 if (eap == NULL) 557 return -1; 558 559 eap->init = eap_ikev2_init; 560 eap->reset = eap_ikev2_reset; 561 eap->buildReq = eap_ikev2_buildReq; 562 eap->check = eap_ikev2_check; 563 eap->process = eap_ikev2_process; 564 eap->isDone = eap_ikev2_isDone; 565 eap->getKey = eap_ikev2_getKey; 566 eap->isSuccess = eap_ikev2_isSuccess; 567 eap->get_emsk = eap_ikev2_get_emsk; 568 eap->getSessionId = eap_ikev2_get_session_id; 569 570 return eap_server_method_register(eap); 571 } 572