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 17struct 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 30static 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 54static 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 73static 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 82static 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 117failed: 118 ikev2_initiator_deinit(&data->ikev2); 119 os_free(data); 120 return NULL; 121} 122 123 124static 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 134static 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 212static 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 240static 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 257static 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 280static 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 299static 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 data->in_buf = wpabuf_alloc(message_length); 313 if (data->in_buf == NULL) { 314 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for " 315 "message"); 316 return -1; 317 } 318 wpabuf_put_data(data->in_buf, buf, len); 319 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first " 320 "fragment, waiting for %lu bytes more", 321 (unsigned long) len, 322 (unsigned long) wpabuf_tailroom(data->in_buf)); 323 } 324 325 return 0; 326} 327 328 329static int eap_ikev2_server_keymat(struct eap_ikev2_data *data) 330{ 331 if (eap_ikev2_derive_keymat( 332 data->ikev2.proposal.prf, &data->ikev2.keys, 333 data->ikev2.i_nonce, data->ikev2.i_nonce_len, 334 data->ikev2.r_nonce, data->ikev2.r_nonce_len, 335 data->keymat) < 0) { 336 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to derive " 337 "key material"); 338 return -1; 339 } 340 data->keymat_ok = 1; 341 return 0; 342} 343 344 345static void eap_ikev2_process(struct eap_sm *sm, void *priv, 346 struct wpabuf *respData) 347{ 348 struct eap_ikev2_data *data = priv; 349 const u8 *start, *pos, *end; 350 size_t len; 351 u8 flags; 352 u32 message_length = 0; 353 struct wpabuf tmpbuf; 354 355 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData, 356 &len); 357 if (pos == NULL) 358 return; /* Should not happen; message already verified */ 359 360 start = pos; 361 end = start + len; 362 363 if (len == 0) { 364 /* fragment ack */ 365 flags = 0; 366 } else 367 flags = *pos++; 368 369 if (eap_ikev2_process_icv(data, respData, flags, pos, &end, 370 data->state == WAIT_FRAG_ACK && len == 0) < 0) 371 { 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 463static 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 470static 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 478static 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 496static 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 514int 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