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