eap_server_psk.c revision 214734
1/* 2 * hostapd / EAP-PSK (RFC 4764) server 3 * Copyright (c) 2005-2007, Jouni Malinen <j@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 * Note: EAP-PSK is an EAP authentication method and as such, completely 15 * different from WPA-PSK. This file is not needed for WPA-PSK functionality. 16 */ 17 18#include "includes.h" 19 20#include "common.h" 21#include "crypto/aes_wrap.h" 22#include "eap_common/eap_psk_common.h" 23#include "eap_server/eap_i.h" 24 25 26struct eap_psk_data { 27 enum { PSK_1, PSK_3, SUCCESS, FAILURE } state; 28 u8 rand_s[EAP_PSK_RAND_LEN]; 29 u8 rand_p[EAP_PSK_RAND_LEN]; 30 u8 *id_p, *id_s; 31 size_t id_p_len, id_s_len; 32 u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN]; 33 u8 msk[EAP_MSK_LEN]; 34 u8 emsk[EAP_EMSK_LEN]; 35}; 36 37 38static void * eap_psk_init(struct eap_sm *sm) 39{ 40 struct eap_psk_data *data; 41 42 data = os_zalloc(sizeof(*data)); 43 if (data == NULL) 44 return NULL; 45 data->state = PSK_1; 46 data->id_s = (u8 *) "hostapd"; 47 data->id_s_len = 7; 48 49 return data; 50} 51 52 53static void eap_psk_reset(struct eap_sm *sm, void *priv) 54{ 55 struct eap_psk_data *data = priv; 56 os_free(data->id_p); 57 os_free(data); 58} 59 60 61static struct wpabuf * eap_psk_build_1(struct eap_sm *sm, 62 struct eap_psk_data *data, u8 id) 63{ 64 struct wpabuf *req; 65 struct eap_psk_hdr_1 *psk; 66 67 wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)"); 68 69 if (os_get_random(data->rand_s, EAP_PSK_RAND_LEN)) { 70 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data"); 71 data->state = FAILURE; 72 return NULL; 73 } 74 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)", 75 data->rand_s, EAP_PSK_RAND_LEN); 76 77 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, 78 sizeof(*psk) + data->id_s_len, 79 EAP_CODE_REQUEST, id); 80 if (req == NULL) { 81 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " 82 "request"); 83 data->state = FAILURE; 84 return NULL; 85 } 86 87 psk = wpabuf_put(req, sizeof(*psk)); 88 psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */ 89 os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); 90 wpabuf_put_data(req, data->id_s, data->id_s_len); 91 92 return req; 93} 94 95 96static struct wpabuf * eap_psk_build_3(struct eap_sm *sm, 97 struct eap_psk_data *data, u8 id) 98{ 99 struct wpabuf *req; 100 struct eap_psk_hdr_3 *psk; 101 u8 *buf, *pchannel, nonce[16]; 102 size_t buflen; 103 104 wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)"); 105 106 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, 107 sizeof(*psk) + 4 + 16 + 1, EAP_CODE_REQUEST, id); 108 if (req == NULL) { 109 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " 110 "request"); 111 data->state = FAILURE; 112 return NULL; 113 } 114 115 psk = wpabuf_put(req, sizeof(*psk)); 116 psk->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */ 117 os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); 118 119 /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */ 120 buflen = data->id_s_len + EAP_PSK_RAND_LEN; 121 buf = os_malloc(buflen); 122 if (buf == NULL) 123 goto fail; 124 125 os_memcpy(buf, data->id_s, data->id_s_len); 126 os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN); 127 if (omac1_aes_128(data->ak, buf, buflen, psk->mac_s)) 128 goto fail; 129 os_free(buf); 130 131 if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk, 132 data->emsk)) 133 goto fail; 134 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN); 135 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN); 136 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN); 137 138 os_memset(nonce, 0, sizeof(nonce)); 139 pchannel = wpabuf_put(req, 4 + 16 + 1); 140 os_memcpy(pchannel, nonce + 12, 4); 141 os_memset(pchannel + 4, 0, 16); /* Tag */ 142 pchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6; 143 wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (plaintext)", 144 pchannel, 4 + 16 + 1); 145 if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), 146 wpabuf_head(req), 22, 147 pchannel + 4 + 16, 1, pchannel + 4)) 148 goto fail; 149 wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (encrypted)", 150 pchannel, 4 + 16 + 1); 151 152 return req; 153 154fail: 155 wpabuf_free(req); 156 data->state = FAILURE; 157 return NULL; 158} 159 160 161static struct wpabuf * eap_psk_buildReq(struct eap_sm *sm, void *priv, u8 id) 162{ 163 struct eap_psk_data *data = priv; 164 165 switch (data->state) { 166 case PSK_1: 167 return eap_psk_build_1(sm, data, id); 168 case PSK_3: 169 return eap_psk_build_3(sm, data, id); 170 default: 171 wpa_printf(MSG_DEBUG, "EAP-PSK: Unknown state %d in buildReq", 172 data->state); 173 break; 174 } 175 return NULL; 176} 177 178 179static Boolean eap_psk_check(struct eap_sm *sm, void *priv, 180 struct wpabuf *respData) 181{ 182 struct eap_psk_data *data = priv; 183 size_t len; 184 u8 t; 185 const u8 *pos; 186 187 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len); 188 if (pos == NULL || len < 1) { 189 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 190 return TRUE; 191 } 192 t = EAP_PSK_FLAGS_GET_T(*pos); 193 194 wpa_printf(MSG_DEBUG, "EAP-PSK: received frame: T=%d", t); 195 196 if (data->state == PSK_1 && t != 1) { 197 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-2 - " 198 "ignore T=%d", t); 199 return TRUE; 200 } 201 202 if (data->state == PSK_3 && t != 3) { 203 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-4 - " 204 "ignore T=%d", t); 205 return TRUE; 206 } 207 208 if ((t == 1 && len < sizeof(struct eap_psk_hdr_2)) || 209 (t == 3 && len < sizeof(struct eap_psk_hdr_4))) { 210 wpa_printf(MSG_DEBUG, "EAP-PSK: Too short frame"); 211 return TRUE; 212 } 213 214 return FALSE; 215} 216 217 218static void eap_psk_process_2(struct eap_sm *sm, 219 struct eap_psk_data *data, 220 struct wpabuf *respData) 221{ 222 const struct eap_psk_hdr_2 *resp; 223 u8 *pos, mac[EAP_PSK_MAC_LEN], *buf; 224 size_t left, buflen; 225 int i; 226 const u8 *cpos; 227 228 if (data->state != PSK_1) 229 return; 230 231 wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2"); 232 233 cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, 234 &left); 235 if (cpos == NULL || left < sizeof(*resp)) { 236 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 237 return; 238 } 239 resp = (const struct eap_psk_hdr_2 *) cpos; 240 cpos = (const u8 *) (resp + 1); 241 left -= sizeof(*resp); 242 243 os_free(data->id_p); 244 data->id_p = os_malloc(left); 245 if (data->id_p == NULL) { 246 wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for " 247 "ID_P"); 248 return; 249 } 250 os_memcpy(data->id_p, cpos, left); 251 data->id_p_len = left; 252 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P", 253 data->id_p, data->id_p_len); 254 255 if (eap_user_get(sm, data->id_p, data->id_p_len, 0) < 0) { 256 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: unknown ID_P", 257 data->id_p, data->id_p_len); 258 data->state = FAILURE; 259 return; 260 } 261 262 for (i = 0; 263 i < EAP_MAX_METHODS && 264 (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 265 sm->user->methods[i].method != EAP_TYPE_NONE); 266 i++) { 267 if (sm->user->methods[i].vendor == EAP_VENDOR_IETF && 268 sm->user->methods[i].method == EAP_TYPE_PSK) 269 break; 270 } 271 272 if (i >= EAP_MAX_METHODS || 273 sm->user->methods[i].vendor != EAP_VENDOR_IETF || 274 sm->user->methods[i].method != EAP_TYPE_PSK) { 275 wpa_hexdump_ascii(MSG_DEBUG, 276 "EAP-PSK: EAP-PSK not enabled for ID_P", 277 data->id_p, data->id_p_len); 278 data->state = FAILURE; 279 return; 280 } 281 282 if (sm->user->password == NULL || 283 sm->user->password_len != EAP_PSK_PSK_LEN) { 284 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: invalid password in " 285 "user database for ID_P", 286 data->id_p, data->id_p_len); 287 data->state = FAILURE; 288 return; 289 } 290 if (eap_psk_key_setup(sm->user->password, data->ak, data->kdk)) { 291 data->state = FAILURE; 292 return; 293 } 294 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN); 295 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN); 296 297 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)", 298 resp->rand_p, EAP_PSK_RAND_LEN); 299 os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN); 300 301 /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */ 302 buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN; 303 buf = os_malloc(buflen); 304 if (buf == NULL) { 305 data->state = FAILURE; 306 return; 307 } 308 os_memcpy(buf, data->id_p, data->id_p_len); 309 pos = buf + data->id_p_len; 310 os_memcpy(pos, data->id_s, data->id_s_len); 311 pos += data->id_s_len; 312 os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN); 313 pos += EAP_PSK_RAND_LEN; 314 os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN); 315 if (omac1_aes_128(data->ak, buf, buflen, mac)) { 316 os_free(buf); 317 data->state = FAILURE; 318 return; 319 } 320 os_free(buf); 321 wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN); 322 if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) { 323 wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P"); 324 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P", 325 mac, EAP_PSK_MAC_LEN); 326 data->state = FAILURE; 327 return; 328 } 329 330 data->state = PSK_3; 331} 332 333 334static void eap_psk_process_4(struct eap_sm *sm, 335 struct eap_psk_data *data, 336 struct wpabuf *respData) 337{ 338 const struct eap_psk_hdr_4 *resp; 339 u8 *decrypted, nonce[16]; 340 size_t left; 341 const u8 *pos, *tag; 342 343 if (data->state != PSK_3) 344 return; 345 346 wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-4"); 347 348 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &left); 349 if (pos == NULL || left < sizeof(*resp)) { 350 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 351 return; 352 } 353 resp = (const struct eap_psk_hdr_4 *) pos; 354 pos = (const u8 *) (resp + 1); 355 left -= sizeof(*resp); 356 357 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Encrypted PCHANNEL", pos, left); 358 359 if (left < 4 + 16 + 1) { 360 wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in " 361 "PSK-4 (len=%lu, expected 21)", 362 (unsigned long) left); 363 return; 364 } 365 366 if (pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0) { 367 wpa_printf(MSG_DEBUG, "EAP-PSK: Nonce did not increase"); 368 return; 369 } 370 371 os_memset(nonce, 0, 12); 372 os_memcpy(nonce + 12, pos, 4); 373 pos += 4; 374 left -= 4; 375 tag = pos; 376 pos += 16; 377 left -= 16; 378 379 decrypted = os_malloc(left); 380 if (decrypted == NULL) 381 return; 382 os_memcpy(decrypted, pos, left); 383 384 if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce), 385 wpabuf_head(respData), 22, decrypted, left, 386 tag)) { 387 wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed"); 388 os_free(decrypted); 389 data->state = FAILURE; 390 return; 391 } 392 wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message", 393 decrypted, left); 394 395 /* Verify R flag */ 396 switch (decrypted[0] >> 6) { 397 case EAP_PSK_R_FLAG_CONT: 398 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported"); 399 data->state = FAILURE; 400 break; 401 case EAP_PSK_R_FLAG_DONE_SUCCESS: 402 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS"); 403 data->state = SUCCESS; 404 break; 405 case EAP_PSK_R_FLAG_DONE_FAILURE: 406 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE"); 407 data->state = FAILURE; 408 break; 409 } 410 os_free(decrypted); 411} 412 413 414static void eap_psk_process(struct eap_sm *sm, void *priv, 415 struct wpabuf *respData) 416{ 417 struct eap_psk_data *data = priv; 418 const u8 *pos; 419 size_t len; 420 421 if (sm->user == NULL || sm->user->password == NULL) { 422 wpa_printf(MSG_INFO, "EAP-PSK: Plaintext password not " 423 "configured"); 424 data->state = FAILURE; 425 return; 426 } 427 428 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len); 429 if (pos == NULL || len < 1) 430 return; 431 432 switch (EAP_PSK_FLAGS_GET_T(*pos)) { 433 case 1: 434 eap_psk_process_2(sm, data, respData); 435 break; 436 case 3: 437 eap_psk_process_4(sm, data, respData); 438 break; 439 } 440} 441 442 443static Boolean eap_psk_isDone(struct eap_sm *sm, void *priv) 444{ 445 struct eap_psk_data *data = priv; 446 return data->state == SUCCESS || data->state == FAILURE; 447} 448 449 450static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len) 451{ 452 struct eap_psk_data *data = priv; 453 u8 *key; 454 455 if (data->state != SUCCESS) 456 return NULL; 457 458 key = os_malloc(EAP_MSK_LEN); 459 if (key == NULL) 460 return NULL; 461 os_memcpy(key, data->msk, EAP_MSK_LEN); 462 *len = EAP_MSK_LEN; 463 464 return key; 465} 466 467 468static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 469{ 470 struct eap_psk_data *data = priv; 471 u8 *key; 472 473 if (data->state != SUCCESS) 474 return NULL; 475 476 key = os_malloc(EAP_EMSK_LEN); 477 if (key == NULL) 478 return NULL; 479 os_memcpy(key, data->emsk, EAP_EMSK_LEN); 480 *len = EAP_EMSK_LEN; 481 482 return key; 483} 484 485 486static Boolean eap_psk_isSuccess(struct eap_sm *sm, void *priv) 487{ 488 struct eap_psk_data *data = priv; 489 return data->state == SUCCESS; 490} 491 492 493int eap_server_psk_register(void) 494{ 495 struct eap_method *eap; 496 int ret; 497 498 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 499 EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK"); 500 if (eap == NULL) 501 return -1; 502 503 eap->init = eap_psk_init; 504 eap->reset = eap_psk_reset; 505 eap->buildReq = eap_psk_buildReq; 506 eap->check = eap_psk_check; 507 eap->process = eap_psk_process; 508 eap->isDone = eap_psk_isDone; 509 eap->getKey = eap_psk_getKey; 510 eap->isSuccess = eap_psk_isSuccess; 511 eap->get_emsk = eap_psk_get_emsk; 512 513 ret = eap_server_method_register(eap); 514 if (ret) 515 eap_server_method_free(eap); 516 return ret; 517} 518