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