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 os_free(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{ 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) { 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 279static 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 298static 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 data->in_buf = wpabuf_alloc(message_length); 312 if (data->in_buf == NULL) { 313 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for " 314 "message"); 315 return -1; 316 } 317 wpabuf_put_data(data->in_buf, buf, len); 318 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first " 319 "fragment, waiting for %lu bytes more", 320 (unsigned long) len, 321 (unsigned long) wpabuf_tailroom(data->in_buf)); 322 } 323 324 return 0; 325} 326 327 328static int eap_ikev2_server_keymat(struct eap_ikev2_data *data) 329{ 330 if (eap_ikev2_derive_keymat( 331 data->ikev2.proposal.prf, &data->ikev2.keys, 332 data->ikev2.i_nonce, data->ikev2.i_nonce_len, 333 data->ikev2.r_nonce, data->ikev2.r_nonce_len, 334 data->keymat) < 0) { 335 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to derive " 336 "key material"); 337 return -1; 338 } 339 data->keymat_ok = 1; 340 return 0; 341} 342 343 344static void eap_ikev2_process(struct eap_sm *sm, void *priv, 345 struct wpabuf *respData) 346{ 347 struct eap_ikev2_data *data = priv; 348 const u8 *start, *pos, *end; 349 size_t len; 350 u8 flags; 351 u32 message_length = 0; 352 struct wpabuf tmpbuf; 353 354 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, respData, 355 &len); 356 if (pos == NULL) 357 return; /* Should not happen; message already verified */ 358 359 start = pos; 360 end = start + len; 361 362 if (len == 0) { 363 /* fragment ack */ 364 flags = 0; 365 } else 366 flags = *pos++; 367 368 if (eap_ikev2_process_icv(data, respData, flags, pos, &end) < 0) { 369 eap_ikev2_state(data, FAIL); 370 return; 371 } 372 373 if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) { 374 if (end - pos < 4) { 375 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow"); 376 eap_ikev2_state(data, FAIL); 377 return; 378 } 379 message_length = WPA_GET_BE32(pos); 380 pos += 4; 381 382 if (message_length < (u32) (end - pos)) { 383 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Invalid Message " 384 "Length (%d; %ld remaining in this msg)", 385 message_length, (long) (end - pos)); 386 eap_ikev2_state(data, FAIL); 387 return; 388 } 389 } 390 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x " 391 "Message Length %u", flags, message_length); 392 393 if (data->state == WAIT_FRAG_ACK) { 394 if (len != 0) { 395 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload " 396 "in WAIT_FRAG_ACK state"); 397 eap_ikev2_state(data, FAIL); 398 return; 399 } 400 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged"); 401 eap_ikev2_state(data, MSG); 402 return; 403 } 404 405 if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) { 406 eap_ikev2_state(data, FAIL); 407 return; 408 } 409 410 if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) { 411 if (eap_ikev2_process_fragment(data, flags, message_length, 412 pos, end - pos) < 0) 413 eap_ikev2_state(data, FAIL); 414 else 415 eap_ikev2_state(data, FRAG_ACK); 416 return; 417 } else if (data->state == FRAG_ACK) { 418 wpa_printf(MSG_DEBUG, "EAP-TNC: All fragments received"); 419 data->state = MSG; 420 } 421 422 if (data->in_buf == NULL) { 423 /* Wrap unfragmented messages as wpabuf without extra copy */ 424 wpabuf_set(&tmpbuf, pos, end - pos); 425 data->in_buf = &tmpbuf; 426 } 427 428 if (ikev2_initiator_process(&data->ikev2, data->in_buf) < 0) { 429 if (data->in_buf == &tmpbuf) 430 data->in_buf = NULL; 431 eap_ikev2_state(data, FAIL); 432 return; 433 } 434 435 switch (data->ikev2.state) { 436 case SA_AUTH: 437 /* SA_INIT was sent out, so message have to be 438 * integrity protected from now on. */ 439 data->keys_ready = 1; 440 break; 441 case IKEV2_DONE: 442 if (data->state == FAIL) 443 break; 444 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication completed " 445 "successfully"); 446 if (eap_ikev2_server_keymat(data)) 447 break; 448 eap_ikev2_state(data, DONE); 449 break; 450 default: 451 break; 452 } 453 454 if (data->in_buf != &tmpbuf) 455 wpabuf_free(data->in_buf); 456 data->in_buf = NULL; 457} 458 459 460static Boolean eap_ikev2_isDone(struct eap_sm *sm, void *priv) 461{ 462 struct eap_ikev2_data *data = priv; 463 return data->state == DONE || data->state == FAIL; 464} 465 466 467static Boolean eap_ikev2_isSuccess(struct eap_sm *sm, void *priv) 468{ 469 struct eap_ikev2_data *data = priv; 470 return data->state == DONE && data->ikev2.state == IKEV2_DONE && 471 data->keymat_ok; 472} 473 474 475static u8 * eap_ikev2_getKey(struct eap_sm *sm, void *priv, size_t *len) 476{ 477 struct eap_ikev2_data *data = priv; 478 u8 *key; 479 480 if (data->state != DONE || !data->keymat_ok) 481 return NULL; 482 483 key = os_malloc(EAP_MSK_LEN); 484 if (key) { 485 os_memcpy(key, data->keymat, EAP_MSK_LEN); 486 *len = EAP_MSK_LEN; 487 } 488 489 return key; 490} 491 492 493static u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 494{ 495 struct eap_ikev2_data *data = priv; 496 u8 *key; 497 498 if (data->state != DONE || !data->keymat_ok) 499 return NULL; 500 501 key = os_malloc(EAP_EMSK_LEN); 502 if (key) { 503 os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN); 504 *len = EAP_EMSK_LEN; 505 } 506 507 return key; 508} 509 510 511int eap_server_ikev2_register(void) 512{ 513 struct eap_method *eap; 514 int ret; 515 516 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 517 EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 518 "IKEV2"); 519 if (eap == NULL) 520 return -1; 521 522 eap->init = eap_ikev2_init; 523 eap->reset = eap_ikev2_reset; 524 eap->buildReq = eap_ikev2_buildReq; 525 eap->check = eap_ikev2_check; 526 eap->process = eap_ikev2_process; 527 eap->isDone = eap_ikev2_isDone; 528 eap->getKey = eap_ikev2_getKey; 529 eap->isSuccess = eap_ikev2_isSuccess; 530 eap->get_emsk = eap_ikev2_get_emsk; 531 532 ret = eap_server_method_register(eap); 533 if (ret) 534 eap_server_method_free(eap); 535 return ret; 536} 537