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