$search
00001 /* 00002 * hostapd / EAP-PSK (RFC 4764) server 00003 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 * 00014 * Note: EAP-PSK is an EAP authentication method and as such, completely 00015 * different from WPA-PSK. This file is not needed for WPA-PSK functionality. 00016 */ 00017 00018 #include "includes.h" 00019 00020 #include "common.h" 00021 #include "crypto/aes_wrap.h" 00022 #include "eap_common/eap_psk_common.h" 00023 #include "eap_server/eap_i.h" 00024 00025 00026 struct eap_psk_data { 00027 enum { PSK_1, PSK_3, SUCCESS, FAILURE } state; 00028 u8 rand_s[EAP_PSK_RAND_LEN]; 00029 u8 rand_p[EAP_PSK_RAND_LEN]; 00030 u8 *id_p, *id_s; 00031 size_t id_p_len, id_s_len; 00032 u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN]; 00033 u8 msk[EAP_MSK_LEN]; 00034 u8 emsk[EAP_EMSK_LEN]; 00035 }; 00036 00037 00038 static void * eap_psk_init(struct eap_sm *sm) 00039 { 00040 struct eap_psk_data *data; 00041 00042 data = os_zalloc(sizeof(*data)); 00043 if (data == NULL) 00044 return NULL; 00045 data->state = PSK_1; 00046 data->id_s = (u8 *) "hostapd"; 00047 data->id_s_len = 7; 00048 00049 return data; 00050 } 00051 00052 00053 static void eap_psk_reset(struct eap_sm *sm, void *priv) 00054 { 00055 struct eap_psk_data *data = priv; 00056 os_free(data->id_p); 00057 os_free(data); 00058 } 00059 00060 00061 static struct wpabuf * eap_psk_build_1(struct eap_sm *sm, 00062 struct eap_psk_data *data, u8 id) 00063 { 00064 struct wpabuf *req; 00065 struct eap_psk_hdr_1 *psk; 00066 00067 wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)"); 00068 00069 if (os_get_random(data->rand_s, EAP_PSK_RAND_LEN)) { 00070 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data"); 00071 data->state = FAILURE; 00072 return NULL; 00073 } 00074 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)", 00075 data->rand_s, EAP_PSK_RAND_LEN); 00076 00077 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, 00078 sizeof(*psk) + data->id_s_len, 00079 EAP_CODE_REQUEST, id); 00080 if (req == NULL) { 00081 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " 00082 "request"); 00083 data->state = FAILURE; 00084 return NULL; 00085 } 00086 00087 psk = wpabuf_put(req, sizeof(*psk)); 00088 psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */ 00089 os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); 00090 wpabuf_put_data(req, data->id_s, data->id_s_len); 00091 00092 return req; 00093 } 00094 00095 00096 static struct wpabuf * eap_psk_build_3(struct eap_sm *sm, 00097 struct eap_psk_data *data, u8 id) 00098 { 00099 struct wpabuf *req; 00100 struct eap_psk_hdr_3 *psk; 00101 u8 *buf, *pchannel, nonce[16]; 00102 size_t buflen; 00103 00104 wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)"); 00105 00106 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, 00107 sizeof(*psk) + 4 + 16 + 1, EAP_CODE_REQUEST, id); 00108 if (req == NULL) { 00109 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " 00110 "request"); 00111 data->state = FAILURE; 00112 return NULL; 00113 } 00114 00115 psk = wpabuf_put(req, sizeof(*psk)); 00116 psk->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */ 00117 os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); 00118 00119 /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */ 00120 buflen = data->id_s_len + EAP_PSK_RAND_LEN; 00121 buf = os_malloc(buflen); 00122 if (buf == NULL) 00123 goto fail; 00124 00125 os_memcpy(buf, data->id_s, data->id_s_len); 00126 os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN); 00127 if (omac1_aes_128(data->ak, buf, buflen, psk->mac_s)) 00128 goto fail; 00129 os_free(buf); 00130 00131 if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk, 00132 data->emsk)) 00133 goto fail; 00134 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN); 00135 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN); 00136 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN); 00137 00138 os_memset(nonce, 0, sizeof(nonce)); 00139 pchannel = wpabuf_put(req, 4 + 16 + 1); 00140 os_memcpy(pchannel, nonce + 12, 4); 00141 os_memset(pchannel + 4, 0, 16); /* Tag */ 00142 pchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6; 00143 wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (plaintext)", 00144 pchannel, 4 + 16 + 1); 00145 if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), 00146 wpabuf_head(req), 22, 00147 pchannel + 4 + 16, 1, pchannel + 4)) 00148 goto fail; 00149 wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (encrypted)", 00150 pchannel, 4 + 16 + 1); 00151 00152 return req; 00153 00154 fail: 00155 wpabuf_free(req); 00156 data->state = FAILURE; 00157 return NULL; 00158 } 00159 00160 00161 static struct wpabuf * eap_psk_buildReq(struct eap_sm *sm, void *priv, u8 id) 00162 { 00163 struct eap_psk_data *data = priv; 00164 00165 switch (data->state) { 00166 case PSK_1: 00167 return eap_psk_build_1(sm, data, id); 00168 case PSK_3: 00169 return eap_psk_build_3(sm, data, id); 00170 default: 00171 wpa_printf(MSG_DEBUG, "EAP-PSK: Unknown state %d in buildReq", 00172 data->state); 00173 break; 00174 } 00175 return NULL; 00176 } 00177 00178 00179 static Boolean eap_psk_check(struct eap_sm *sm, void *priv, 00180 struct wpabuf *respData) 00181 { 00182 struct eap_psk_data *data = priv; 00183 size_t len; 00184 u8 t; 00185 const u8 *pos; 00186 00187 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len); 00188 if (pos == NULL || len < 1) { 00189 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 00190 return TRUE; 00191 } 00192 t = EAP_PSK_FLAGS_GET_T(*pos); 00193 00194 wpa_printf(MSG_DEBUG, "EAP-PSK: received frame: T=%d", t); 00195 00196 if (data->state == PSK_1 && t != 1) { 00197 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-2 - " 00198 "ignore T=%d", t); 00199 return TRUE; 00200 } 00201 00202 if (data->state == PSK_3 && t != 3) { 00203 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-4 - " 00204 "ignore T=%d", t); 00205 return TRUE; 00206 } 00207 00208 if ((t == 1 && len < sizeof(struct eap_psk_hdr_2)) || 00209 (t == 3 && len < sizeof(struct eap_psk_hdr_4))) { 00210 wpa_printf(MSG_DEBUG, "EAP-PSK: Too short frame"); 00211 return TRUE; 00212 } 00213 00214 return FALSE; 00215 } 00216 00217 00218 static void eap_psk_process_2(struct eap_sm *sm, 00219 struct eap_psk_data *data, 00220 struct wpabuf *respData) 00221 { 00222 const struct eap_psk_hdr_2 *resp; 00223 u8 *pos, mac[EAP_PSK_MAC_LEN], *buf; 00224 size_t left, buflen; 00225 int i; 00226 const u8 *cpos; 00227 00228 if (data->state != PSK_1) 00229 return; 00230 00231 wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2"); 00232 00233 cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, 00234 &left); 00235 if (cpos == NULL || left < sizeof(*resp)) { 00236 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 00237 return; 00238 } 00239 resp = (const struct eap_psk_hdr_2 *) cpos; 00240 cpos = (const u8 *) (resp + 1); 00241 left -= sizeof(*resp); 00242 00243 os_free(data->id_p); 00244 data->id_p = os_malloc(left); 00245 if (data->id_p == NULL) { 00246 wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for " 00247 "ID_P"); 00248 return; 00249 } 00250 os_memcpy(data->id_p, cpos, left); 00251 data->id_p_len = left; 00252 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P", 00253 data->id_p, data->id_p_len); 00254 00255 if (eap_user_get(sm, data->id_p, data->id_p_len, 0) < 0) { 00256 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: unknown ID_P", 00257 data->id_p, data->id_p_len); 00258 data->state = FAILURE; 00259 return; 00260 } 00261 00262 for (i = 0; 00263 i < EAP_MAX_METHODS && 00264 (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 00265 sm->user->methods[i].method != EAP_TYPE_NONE); 00266 i++) { 00267 if (sm->user->methods[i].vendor == EAP_VENDOR_IETF && 00268 sm->user->methods[i].method == EAP_TYPE_PSK) 00269 break; 00270 } 00271 00272 if (i >= EAP_MAX_METHODS || 00273 sm->user->methods[i].vendor != EAP_VENDOR_IETF || 00274 sm->user->methods[i].method != EAP_TYPE_PSK) { 00275 wpa_hexdump_ascii(MSG_DEBUG, 00276 "EAP-PSK: EAP-PSK not enabled for ID_P", 00277 data->id_p, data->id_p_len); 00278 data->state = FAILURE; 00279 return; 00280 } 00281 00282 if (sm->user->password == NULL || 00283 sm->user->password_len != EAP_PSK_PSK_LEN) { 00284 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: invalid password in " 00285 "user database for ID_P", 00286 data->id_p, data->id_p_len); 00287 data->state = FAILURE; 00288 return; 00289 } 00290 if (eap_psk_key_setup(sm->user->password, data->ak, data->kdk)) { 00291 data->state = FAILURE; 00292 return; 00293 } 00294 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN); 00295 wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN); 00296 00297 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)", 00298 resp->rand_p, EAP_PSK_RAND_LEN); 00299 os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN); 00300 00301 /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */ 00302 buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN; 00303 buf = os_malloc(buflen); 00304 if (buf == NULL) { 00305 data->state = FAILURE; 00306 return; 00307 } 00308 os_memcpy(buf, data->id_p, data->id_p_len); 00309 pos = buf + data->id_p_len; 00310 os_memcpy(pos, data->id_s, data->id_s_len); 00311 pos += data->id_s_len; 00312 os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN); 00313 pos += EAP_PSK_RAND_LEN; 00314 os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN); 00315 if (omac1_aes_128(data->ak, buf, buflen, mac)) { 00316 os_free(buf); 00317 data->state = FAILURE; 00318 return; 00319 } 00320 os_free(buf); 00321 wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN); 00322 if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) { 00323 wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P"); 00324 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P", 00325 mac, EAP_PSK_MAC_LEN); 00326 data->state = FAILURE; 00327 return; 00328 } 00329 00330 data->state = PSK_3; 00331 } 00332 00333 00334 static void eap_psk_process_4(struct eap_sm *sm, 00335 struct eap_psk_data *data, 00336 struct wpabuf *respData) 00337 { 00338 const struct eap_psk_hdr_4 *resp; 00339 u8 *decrypted, nonce[16]; 00340 size_t left; 00341 const u8 *pos, *tag; 00342 00343 if (data->state != PSK_3) 00344 return; 00345 00346 wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-4"); 00347 00348 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &left); 00349 if (pos == NULL || left < sizeof(*resp)) { 00350 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); 00351 return; 00352 } 00353 resp = (const struct eap_psk_hdr_4 *) pos; 00354 pos = (const u8 *) (resp + 1); 00355 left -= sizeof(*resp); 00356 00357 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Encrypted PCHANNEL", pos, left); 00358 00359 if (left < 4 + 16 + 1) { 00360 wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in " 00361 "PSK-4 (len=%lu, expected 21)", 00362 (unsigned long) left); 00363 return; 00364 } 00365 00366 if (pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0) { 00367 wpa_printf(MSG_DEBUG, "EAP-PSK: Nonce did not increase"); 00368 return; 00369 } 00370 00371 os_memset(nonce, 0, 12); 00372 os_memcpy(nonce + 12, pos, 4); 00373 pos += 4; 00374 left -= 4; 00375 tag = pos; 00376 pos += 16; 00377 left -= 16; 00378 00379 decrypted = os_malloc(left); 00380 if (decrypted == NULL) 00381 return; 00382 os_memcpy(decrypted, pos, left); 00383 00384 if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce), 00385 wpabuf_head(respData), 22, decrypted, left, 00386 tag)) { 00387 wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed"); 00388 os_free(decrypted); 00389 data->state = FAILURE; 00390 return; 00391 } 00392 wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message", 00393 decrypted, left); 00394 00395 /* Verify R flag */ 00396 switch (decrypted[0] >> 6) { 00397 case EAP_PSK_R_FLAG_CONT: 00398 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported"); 00399 data->state = FAILURE; 00400 break; 00401 case EAP_PSK_R_FLAG_DONE_SUCCESS: 00402 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS"); 00403 data->state = SUCCESS; 00404 break; 00405 case EAP_PSK_R_FLAG_DONE_FAILURE: 00406 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE"); 00407 data->state = FAILURE; 00408 break; 00409 } 00410 os_free(decrypted); 00411 } 00412 00413 00414 static void eap_psk_process(struct eap_sm *sm, void *priv, 00415 struct wpabuf *respData) 00416 { 00417 struct eap_psk_data *data = priv; 00418 const u8 *pos; 00419 size_t len; 00420 00421 if (sm->user == NULL || sm->user->password == NULL) { 00422 wpa_printf(MSG_INFO, "EAP-PSK: Plaintext password not " 00423 "configured"); 00424 data->state = FAILURE; 00425 return; 00426 } 00427 00428 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len); 00429 if (pos == NULL || len < 1) 00430 return; 00431 00432 switch (EAP_PSK_FLAGS_GET_T(*pos)) { 00433 case 1: 00434 eap_psk_process_2(sm, data, respData); 00435 break; 00436 case 3: 00437 eap_psk_process_4(sm, data, respData); 00438 break; 00439 } 00440 } 00441 00442 00443 static Boolean eap_psk_isDone(struct eap_sm *sm, void *priv) 00444 { 00445 struct eap_psk_data *data = priv; 00446 return data->state == SUCCESS || data->state == FAILURE; 00447 } 00448 00449 00450 static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len) 00451 { 00452 struct eap_psk_data *data = priv; 00453 u8 *key; 00454 00455 if (data->state != SUCCESS) 00456 return NULL; 00457 00458 key = os_malloc(EAP_MSK_LEN); 00459 if (key == NULL) 00460 return NULL; 00461 os_memcpy(key, data->msk, EAP_MSK_LEN); 00462 *len = EAP_MSK_LEN; 00463 00464 return key; 00465 } 00466 00467 00468 static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 00469 { 00470 struct eap_psk_data *data = priv; 00471 u8 *key; 00472 00473 if (data->state != SUCCESS) 00474 return NULL; 00475 00476 key = os_malloc(EAP_EMSK_LEN); 00477 if (key == NULL) 00478 return NULL; 00479 os_memcpy(key, data->emsk, EAP_EMSK_LEN); 00480 *len = EAP_EMSK_LEN; 00481 00482 return key; 00483 } 00484 00485 00486 static Boolean eap_psk_isSuccess(struct eap_sm *sm, void *priv) 00487 { 00488 struct eap_psk_data *data = priv; 00489 return data->state == SUCCESS; 00490 } 00491 00492 00493 int eap_server_psk_register(void) 00494 { 00495 struct eap_method *eap; 00496 int ret; 00497 00498 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 00499 EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK"); 00500 if (eap == NULL) 00501 return -1; 00502 00503 eap->init = eap_psk_init; 00504 eap->reset = eap_psk_reset; 00505 eap->buildReq = eap_psk_buildReq; 00506 eap->check = eap_psk_check; 00507 eap->process = eap_psk_process; 00508 eap->isDone = eap_psk_isDone; 00509 eap->getKey = eap_psk_getKey; 00510 eap->isSuccess = eap_psk_isSuccess; 00511 eap->get_emsk = eap_psk_get_emsk; 00512 00513 ret = eap_server_method_register(eap); 00514 if (ret) 00515 eap_server_method_free(eap); 00516 return ret; 00517 }