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