2 * hostapd / EAP-PSK (RFC 4764) server
3 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
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.
21 #include "crypto/aes_wrap.h"
22 #include "eap_common/eap_psk_common.h"
23 #include "eap_server/eap_i.h"
27 enum { PSK_1
, PSK_3
, SUCCESS
, FAILURE
} state
;
28 u8 rand_s
[EAP_PSK_RAND_LEN
];
29 u8 rand_p
[EAP_PSK_RAND_LEN
];
31 size_t id_p_len
, id_s_len
;
32 u8 ak
[EAP_PSK_AK_LEN
], kdk
[EAP_PSK_KDK_LEN
], tek
[EAP_PSK_TEK_LEN
];
34 u8 emsk
[EAP_EMSK_LEN
];
38 static void * eap_psk_init(struct eap_sm
*sm
)
40 struct eap_psk_data
*data
;
42 data
= os_zalloc(sizeof(*data
));
46 data
->id_s
= (u8
*) "hostapd";
53 static void eap_psk_reset(struct eap_sm
*sm
, void *priv
)
55 struct eap_psk_data
*data
= priv
;
61 static struct wpabuf
* eap_psk_build_1(struct eap_sm
*sm
,
62 struct eap_psk_data
*data
, u8 id
)
65 struct eap_psk_hdr_1
*psk
;
67 wpa_printf(MSG_DEBUG
, "EAP-PSK: PSK-1 (sending)");
69 if (os_get_random(data
->rand_s
, EAP_PSK_RAND_LEN
)) {
70 wpa_printf(MSG_ERROR
, "EAP-PSK: Failed to get random data");
71 data
->state
= FAILURE
;
74 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: RAND_S (server rand)",
75 data
->rand_s
, EAP_PSK_RAND_LEN
);
77 req
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_PSK
,
78 sizeof(*psk
) + data
->id_s_len
,
79 EAP_CODE_REQUEST
, id
);
81 wpa_printf(MSG_ERROR
, "EAP-PSK: Failed to allocate memory "
83 data
->state
= FAILURE
;
87 psk
= wpabuf_put(req
, sizeof(*psk
));
88 psk
->flags
= EAP_PSK_FLAGS_SET_T(0); /* T=0 */
89 os_memcpy(psk
->rand_s
, data
->rand_s
, EAP_PSK_RAND_LEN
);
90 wpabuf_put_data(req
, data
->id_s
, data
->id_s_len
);
96 static struct wpabuf
* eap_psk_build_3(struct eap_sm
*sm
,
97 struct eap_psk_data
*data
, u8 id
)
100 struct eap_psk_hdr_3
*psk
;
101 u8
*buf
, *pchannel
, nonce
[16];
104 wpa_printf(MSG_DEBUG
, "EAP-PSK: PSK-3 (sending)");
106 req
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_PSK
,
107 sizeof(*psk
) + 4 + 16 + 1, EAP_CODE_REQUEST
, id
);
109 wpa_printf(MSG_ERROR
, "EAP-PSK: Failed to allocate memory "
111 data
->state
= FAILURE
;
115 psk
= wpabuf_put(req
, sizeof(*psk
));
116 psk
->flags
= EAP_PSK_FLAGS_SET_T(2); /* T=2 */
117 os_memcpy(psk
->rand_s
, data
->rand_s
, EAP_PSK_RAND_LEN
);
119 /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
120 buflen
= data
->id_s_len
+ EAP_PSK_RAND_LEN
;
121 buf
= os_malloc(buflen
);
125 os_memcpy(buf
, data
->id_s
, data
->id_s_len
);
126 os_memcpy(buf
+ data
->id_s_len
, data
->rand_p
, EAP_PSK_RAND_LEN
);
127 if (omac1_aes_128(data
->ak
, buf
, buflen
, psk
->mac_s
))
131 if (eap_psk_derive_keys(data
->kdk
, data
->rand_p
, data
->tek
, data
->msk
,
134 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: TEK", data
->tek
, EAP_PSK_TEK_LEN
);
135 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: MSK", data
->msk
, EAP_MSK_LEN
);
136 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: EMSK", data
->emsk
, EAP_EMSK_LEN
);
138 os_memset(nonce
, 0, sizeof(nonce
));
139 pchannel
= wpabuf_put(req
, 4 + 16 + 1);
140 os_memcpy(pchannel
, nonce
+ 12, 4);
141 os_memset(pchannel
+ 4, 0, 16); /* Tag */
142 pchannel
[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS
<< 6;
143 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: PCHANNEL (plaintext)",
144 pchannel
, 4 + 16 + 1);
145 if (aes_128_eax_encrypt(data
->tek
, nonce
, sizeof(nonce
),
146 wpabuf_head(req
), 22,
147 pchannel
+ 4 + 16, 1, pchannel
+ 4))
149 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: PCHANNEL (encrypted)",
150 pchannel
, 4 + 16 + 1);
156 data
->state
= FAILURE
;
161 static struct wpabuf
* eap_psk_buildReq(struct eap_sm
*sm
, void *priv
, u8 id
)
163 struct eap_psk_data
*data
= priv
;
165 switch (data
->state
) {
167 return eap_psk_build_1(sm
, data
, id
);
169 return eap_psk_build_3(sm
, data
, id
);
171 wpa_printf(MSG_DEBUG
, "EAP-PSK: Unknown state %d in buildReq",
179 static Boolean
eap_psk_check(struct eap_sm
*sm
, void *priv
,
180 struct wpabuf
*respData
)
182 struct eap_psk_data
*data
= priv
;
187 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_PSK
, respData
, &len
);
188 if (pos
== NULL
|| len
< 1) {
189 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid frame");
192 t
= EAP_PSK_FLAGS_GET_T(*pos
);
194 wpa_printf(MSG_DEBUG
, "EAP-PSK: received frame: T=%d", t
);
196 if (data
->state
== PSK_1
&& t
!= 1) {
197 wpa_printf(MSG_DEBUG
, "EAP-PSK: Expected PSK-2 - "
202 if (data
->state
== PSK_3
&& t
!= 3) {
203 wpa_printf(MSG_DEBUG
, "EAP-PSK: Expected PSK-4 - "
208 if ((t
== 1 && len
< sizeof(struct eap_psk_hdr_2
)) ||
209 (t
== 3 && len
< sizeof(struct eap_psk_hdr_4
))) {
210 wpa_printf(MSG_DEBUG
, "EAP-PSK: Too short frame");
218 static void eap_psk_process_2(struct eap_sm
*sm
,
219 struct eap_psk_data
*data
,
220 struct wpabuf
*respData
)
222 const struct eap_psk_hdr_2
*resp
;
223 u8
*pos
, mac
[EAP_PSK_MAC_LEN
], *buf
;
228 if (data
->state
!= PSK_1
)
231 wpa_printf(MSG_DEBUG
, "EAP-PSK: Received PSK-2");
233 cpos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_PSK
, respData
,
235 if (cpos
== NULL
|| left
< sizeof(*resp
)) {
236 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid frame");
239 resp
= (const struct eap_psk_hdr_2
*) cpos
;
240 cpos
= (const u8
*) (resp
+ 1);
241 left
-= sizeof(*resp
);
244 data
->id_p
= os_malloc(left
);
245 if (data
->id_p
== NULL
) {
246 wpa_printf(MSG_INFO
, "EAP-PSK: Failed to allocate memory for "
250 os_memcpy(data
->id_p
, cpos
, left
);
251 data
->id_p_len
= left
;
252 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-PSK: ID_P",
253 data
->id_p
, data
->id_p_len
);
255 if (eap_user_get(sm
, data
->id_p
, data
->id_p_len
, 0) < 0) {
256 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-PSK: unknown ID_P",
257 data
->id_p
, data
->id_p_len
);
258 data
->state
= FAILURE
;
263 i
< EAP_MAX_METHODS
&&
264 (sm
->user
->methods
[i
].vendor
!= EAP_VENDOR_IETF
||
265 sm
->user
->methods
[i
].method
!= EAP_TYPE_NONE
);
267 if (sm
->user
->methods
[i
].vendor
== EAP_VENDOR_IETF
&&
268 sm
->user
->methods
[i
].method
== EAP_TYPE_PSK
)
272 if (i
>= EAP_MAX_METHODS
||
273 sm
->user
->methods
[i
].vendor
!= EAP_VENDOR_IETF
||
274 sm
->user
->methods
[i
].method
!= EAP_TYPE_PSK
) {
275 wpa_hexdump_ascii(MSG_DEBUG
,
276 "EAP-PSK: EAP-PSK not enabled for ID_P",
277 data
->id_p
, data
->id_p_len
);
278 data
->state
= FAILURE
;
282 if (sm
->user
->password
== NULL
||
283 sm
->user
->password_len
!= EAP_PSK_PSK_LEN
) {
284 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-PSK: invalid password in "
285 "user database for ID_P",
286 data
->id_p
, data
->id_p_len
);
287 data
->state
= FAILURE
;
290 if (eap_psk_key_setup(sm
->user
->password
, data
->ak
, data
->kdk
)) {
291 data
->state
= FAILURE
;
294 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: AK", data
->ak
, EAP_PSK_AK_LEN
);
295 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: KDK", data
->kdk
, EAP_PSK_KDK_LEN
);
297 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: RAND_P (client rand)",
298 resp
->rand_p
, EAP_PSK_RAND_LEN
);
299 os_memcpy(data
->rand_p
, resp
->rand_p
, EAP_PSK_RAND_LEN
);
301 /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
302 buflen
= data
->id_p_len
+ data
->id_s_len
+ 2 * EAP_PSK_RAND_LEN
;
303 buf
= os_malloc(buflen
);
305 data
->state
= FAILURE
;
308 os_memcpy(buf
, data
->id_p
, data
->id_p_len
);
309 pos
= buf
+ data
->id_p_len
;
310 os_memcpy(pos
, data
->id_s
, data
->id_s_len
);
311 pos
+= data
->id_s_len
;
312 os_memcpy(pos
, data
->rand_s
, EAP_PSK_RAND_LEN
);
313 pos
+= EAP_PSK_RAND_LEN
;
314 os_memcpy(pos
, data
->rand_p
, EAP_PSK_RAND_LEN
);
315 if (omac1_aes_128(data
->ak
, buf
, buflen
, mac
)) {
317 data
->state
= FAILURE
;
321 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: MAC_P", resp
->mac_p
, EAP_PSK_MAC_LEN
);
322 if (os_memcmp(mac
, resp
->mac_p
, EAP_PSK_MAC_LEN
) != 0) {
323 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid MAC_P");
324 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: Expected MAC_P",
325 mac
, EAP_PSK_MAC_LEN
);
326 data
->state
= FAILURE
;
334 static void eap_psk_process_4(struct eap_sm
*sm
,
335 struct eap_psk_data
*data
,
336 struct wpabuf
*respData
)
338 const struct eap_psk_hdr_4
*resp
;
339 u8
*decrypted
, nonce
[16];
343 if (data
->state
!= PSK_3
)
346 wpa_printf(MSG_DEBUG
, "EAP-PSK: Received PSK-4");
348 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_PSK
, respData
, &left
);
349 if (pos
== NULL
|| left
< sizeof(*resp
)) {
350 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid frame");
353 resp
= (const struct eap_psk_hdr_4
*) pos
;
354 pos
= (const u8
*) (resp
+ 1);
355 left
-= sizeof(*resp
);
357 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: Encrypted PCHANNEL", pos
, left
);
359 if (left
< 4 + 16 + 1) {
360 wpa_printf(MSG_INFO
, "EAP-PSK: Too short PCHANNEL data in "
361 "PSK-4 (len=%lu, expected 21)",
362 (unsigned long) left
);
366 if (pos
[0] == 0 && pos
[1] == 0 && pos
[2] == 0 && pos
[3] == 0) {
367 wpa_printf(MSG_DEBUG
, "EAP-PSK: Nonce did not increase");
371 os_memset(nonce
, 0, 12);
372 os_memcpy(nonce
+ 12, pos
, 4);
379 decrypted
= os_malloc(left
);
380 if (decrypted
== NULL
)
382 os_memcpy(decrypted
, pos
, left
);
384 if (aes_128_eax_decrypt(data
->tek
, nonce
, sizeof(nonce
),
385 wpabuf_head(respData
), 22, decrypted
, left
,
387 wpa_printf(MSG_WARNING
, "EAP-PSK: PCHANNEL decryption failed");
389 data
->state
= FAILURE
;
392 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: Decrypted PCHANNEL message",
396 switch (decrypted
[0] >> 6) {
397 case EAP_PSK_R_FLAG_CONT
:
398 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - CONT - unsupported");
399 data
->state
= FAILURE
;
401 case EAP_PSK_R_FLAG_DONE_SUCCESS
:
402 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - DONE_SUCCESS");
403 data
->state
= SUCCESS
;
405 case EAP_PSK_R_FLAG_DONE_FAILURE
:
406 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - DONE_FAILURE");
407 data
->state
= FAILURE
;
414 static void eap_psk_process(struct eap_sm
*sm
, void *priv
,
415 struct wpabuf
*respData
)
417 struct eap_psk_data
*data
= priv
;
421 if (sm
->user
== NULL
|| sm
->user
->password
== NULL
) {
422 wpa_printf(MSG_INFO
, "EAP-PSK: Plaintext password not "
424 data
->state
= FAILURE
;
428 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_PSK
, respData
, &len
);
429 if (pos
== NULL
|| len
< 1)
432 switch (EAP_PSK_FLAGS_GET_T(*pos
)) {
434 eap_psk_process_2(sm
, data
, respData
);
437 eap_psk_process_4(sm
, data
, respData
);
443 static Boolean
eap_psk_isDone(struct eap_sm
*sm
, void *priv
)
445 struct eap_psk_data
*data
= priv
;
446 return data
->state
== SUCCESS
|| data
->state
== FAILURE
;
450 static u8
* eap_psk_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
452 struct eap_psk_data
*data
= priv
;
455 if (data
->state
!= SUCCESS
)
458 key
= os_malloc(EAP_MSK_LEN
);
461 os_memcpy(key
, data
->msk
, EAP_MSK_LEN
);
468 static u8
* eap_psk_get_emsk(struct eap_sm
*sm
, void *priv
, size_t *len
)
470 struct eap_psk_data
*data
= priv
;
473 if (data
->state
!= SUCCESS
)
476 key
= os_malloc(EAP_EMSK_LEN
);
479 os_memcpy(key
, data
->emsk
, EAP_EMSK_LEN
);
486 static Boolean
eap_psk_isSuccess(struct eap_sm
*sm
, void *priv
)
488 struct eap_psk_data
*data
= priv
;
489 return data
->state
== SUCCESS
;
493 int eap_server_psk_register(void)
495 struct eap_method
*eap
;
498 eap
= eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION
,
499 EAP_VENDOR_IETF
, EAP_TYPE_PSK
, "PSK");
503 eap
->init
= eap_psk_init
;
504 eap
->reset
= eap_psk_reset
;
505 eap
->buildReq
= eap_psk_buildReq
;
506 eap
->check
= eap_psk_check
;
507 eap
->process
= eap_psk_process
;
508 eap
->isDone
= eap_psk_isDone
;
509 eap
->getKey
= eap_psk_getKey
;
510 eap
->isSuccess
= eap_psk_isSuccess
;
511 eap
->get_emsk
= eap_psk_get_emsk
;
513 ret
= eap_server_method_register(eap
);
515 eap_server_method_free(eap
);