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