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