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