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