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.
24 #include "eap_psk_common.h"
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
];
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
];
35 u8 emsk
[EAP_EMSK_LEN
];
39 static void * eap_psk_init(struct eap_sm
*sm
)
41 struct eap_psk_data
*data
;
43 data
= wpa_zalloc(sizeof(*data
));
47 data
->id_s
= (u8
*) "hostapd";
54 static void eap_psk_reset(struct eap_sm
*sm
, void *priv
)
56 struct eap_psk_data
*data
= priv
;
62 static u8
* eap_psk_build_1(struct eap_sm
*sm
, struct eap_psk_data
*data
,
63 int id
, size_t *reqDataLen
)
65 struct eap_psk_hdr_1
*req
;
67 wpa_printf(MSG_DEBUG
, "EAP-PSK: PSK-1 (sending)");
69 if (hostapd_get_rand(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 *reqDataLen
= sizeof(*req
) + data
->id_s_len
;
78 req
= malloc(*reqDataLen
);
80 wpa_printf(MSG_ERROR
, "EAP-PSK: Failed to allocate memory "
82 data
->state
= FAILURE
;
86 req
->code
= EAP_CODE_REQUEST
;
88 req
->length
= htons(*reqDataLen
);
89 req
->type
= EAP_TYPE_PSK
;
90 req
->flags
= EAP_PSK_FLAGS_SET_T(0); /* T=0 */
91 memcpy(req
->rand_s
, data
->rand_s
, EAP_PSK_RAND_LEN
);
92 memcpy((u8
*) (req
+ 1), data
->id_s
, data
->id_s_len
);
98 static u8
* eap_psk_build_3(struct eap_sm
*sm
, struct eap_psk_data
*data
,
99 int id
, size_t *reqDataLen
)
101 struct eap_psk_hdr_3
*req
;
102 u8
*buf
, *pchannel
, nonce
[16];
105 wpa_printf(MSG_DEBUG
, "EAP-PSK: PSK-3 (sending)");
107 *reqDataLen
= sizeof(*req
) + 4 + 16 + 1;
108 req
= malloc(*reqDataLen
);
110 wpa_printf(MSG_ERROR
, "EAP-PSK: Failed to allocate memory "
112 data
->state
= FAILURE
;
116 req
->code
= EAP_CODE_REQUEST
;
117 req
->identifier
= id
;
118 req
->length
= htons(*reqDataLen
);
119 req
->type
= EAP_TYPE_PSK
;
120 req
->flags
= EAP_PSK_FLAGS_SET_T(2); /* T=2 */
121 memcpy(req
->rand_s
, data
->rand_s
, EAP_PSK_RAND_LEN
);
123 /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
124 buflen
= data
->id_s_len
+ EAP_PSK_RAND_LEN
;
125 buf
= malloc(buflen
);
128 data
->state
= FAILURE
;
131 memcpy(buf
, data
->id_s
, data
->id_s_len
);
132 memcpy(buf
+ data
->id_s_len
, data
->rand_p
, EAP_PSK_RAND_LEN
);
133 omac1_aes_128(data
->ak
, buf
, buflen
, req
->mac_s
);
136 eap_psk_derive_keys(data
->kdk
, data
->rand_p
, data
->tek
, data
->msk
,
138 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: TEK", data
->tek
, EAP_PSK_TEK_LEN
);
139 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: MSK", data
->msk
, EAP_MSK_LEN
);
140 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: EMSK", data
->emsk
, EAP_EMSK_LEN
);
142 memset(nonce
, 0, sizeof(nonce
));
143 pchannel
= (u8
*) (req
+ 1);
144 memcpy(pchannel
, nonce
+ 12, 4);
145 memset(pchannel
+ 4, 0, 16); /* Tag */
146 pchannel
[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS
<< 6;
147 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: PCHANNEL (plaintext)",
148 pchannel
, 4 + 16 + 1);
149 aes_128_eax_encrypt(data
->tek
, nonce
, sizeof(nonce
), (u8
*) req
, 22,
150 pchannel
+ 4 + 16, 1, pchannel
+ 4);
151 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: PCHANNEL (encrypted)",
152 pchannel
, 4 + 16 + 1);
158 static u8
* eap_psk_buildReq(struct eap_sm
*sm
, void *priv
, int id
,
161 struct eap_psk_data
*data
= priv
;
163 switch (data
->state
) {
165 return eap_psk_build_1(sm
, data
, id
, reqDataLen
);
167 return eap_psk_build_3(sm
, data
, id
, reqDataLen
);
169 wpa_printf(MSG_DEBUG
, "EAP-PSK: Unknown state %d in buildReq",
177 static Boolean
eap_psk_check(struct eap_sm
*sm
, void *priv
,
178 u8
*respData
, size_t respDataLen
)
180 struct eap_psk_data
*data
= priv
;
181 struct eap_psk_hdr
*resp
;
185 resp
= (struct eap_psk_hdr
*) respData
;
186 if (respDataLen
< sizeof(*resp
) || resp
->type
!= EAP_TYPE_PSK
||
187 (len
= ntohs(resp
->length
)) > respDataLen
||
188 len
< sizeof(*resp
)) {
189 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid frame");
192 t
= EAP_PSK_FLAGS_GET_T(resp
->flags
);
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 u8
*respData
, size_t respDataLen
)
222 struct eap_psk_hdr_2
*resp
;
223 u8
*pos
, mac
[EAP_PSK_MAC_LEN
], *buf
;
224 size_t len
, left
, buflen
;
227 if (data
->state
!= PSK_1
)
230 wpa_printf(MSG_DEBUG
, "EAP-PSK: Received PSK-2");
232 resp
= (struct eap_psk_hdr_2
*) respData
;
233 len
= ntohs(resp
->length
);
234 pos
= (u8
*) (resp
+ 1);
235 left
= len
- sizeof(*resp
);
238 data
->id_p
= malloc(left
);
239 if (data
->id_p
== NULL
) {
240 wpa_printf(MSG_INFO
, "EAP-PSK: Failed to allocate memory for "
244 memcpy(data
->id_p
, pos
, left
);
245 data
->id_p_len
= left
;
246 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-PSK: ID_P",
247 data
->id_p
, data
->id_p_len
);
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
;
257 i
< EAP_MAX_METHODS
&&
258 (sm
->user
->methods
[i
].vendor
!= EAP_VENDOR_IETF
||
259 sm
->user
->methods
[i
].method
!= EAP_TYPE_NONE
);
261 if (sm
->user
->methods
[i
].vendor
== EAP_VENDOR_IETF
&&
262 sm
->user
->methods
[i
].method
== EAP_TYPE_PSK
)
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
;
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
;
284 eap_psk_key_setup(sm
->user
->password
, data
->ak
, data
->kdk
);
285 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: AK", data
->ak
, EAP_PSK_AK_LEN
);
286 wpa_hexdump_key(MSG_DEBUG
, "EAP-PSK: KDK", data
->kdk
, EAP_PSK_KDK_LEN
);
288 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: RAND_P (client rand)",
289 resp
->rand_p
, EAP_PSK_RAND_LEN
);
290 memcpy(data
->rand_p
, resp
->rand_p
, EAP_PSK_RAND_LEN
);
292 /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
293 buflen
= data
->id_p_len
+ data
->id_s_len
+ 2 * EAP_PSK_RAND_LEN
;
294 buf
= malloc(buflen
);
296 data
->state
= FAILURE
;
299 memcpy(buf
, data
->id_p
, data
->id_p_len
);
300 pos
= buf
+ data
->id_p_len
;
301 memcpy(pos
, data
->id_s
, data
->id_s_len
);
302 pos
+= data
->id_s_len
;
303 memcpy(pos
, data
->rand_s
, EAP_PSK_RAND_LEN
);
304 pos
+= EAP_PSK_RAND_LEN
;
305 memcpy(pos
, data
->rand_p
, EAP_PSK_RAND_LEN
);
306 omac1_aes_128(data
->ak
, buf
, buflen
, mac
);
308 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: MAC_P", resp
->mac_p
, EAP_PSK_MAC_LEN
);
309 if (memcmp(mac
, resp
->mac_p
, EAP_PSK_MAC_LEN
) != 0) {
310 wpa_printf(MSG_INFO
, "EAP-PSK: Invalid MAC_P");
311 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: Expected MAC_P",
312 mac
, EAP_PSK_MAC_LEN
);
313 data
->state
= FAILURE
;
321 static void eap_psk_process_4(struct eap_sm
*sm
,
322 struct eap_psk_data
*data
,
323 u8
*respData
, size_t respDataLen
)
325 struct eap_psk_hdr_4
*resp
;
326 u8
*pos
, *decrypted
, nonce
[16], *tag
;
329 if (data
->state
!= PSK_3
)
332 wpa_printf(MSG_DEBUG
, "EAP-PSK: Received PSK-4");
334 resp
= (struct eap_psk_hdr_4
*) respData
;
335 pos
= (u8
*) (resp
+ 1);
336 left
= ntohs(resp
->length
) - sizeof(*resp
);
338 wpa_hexdump(MSG_MSGDUMP
, "EAP-PSK: Encrypted PCHANNEL", pos
, left
);
340 if (left
< 4 + 16 + 1) {
341 wpa_printf(MSG_INFO
, "EAP-PSK: Too short PCHANNEL data in "
342 "PSK-4 (len=%lu, expected 21)",
343 (unsigned long) left
);
347 if (pos
[0] == 0 && pos
[1] == 0 && pos
[2] == 0 && pos
[3] == 0) {
348 wpa_printf(MSG_DEBUG
, "EAP-PSK: Nonce did not increase");
352 memset(nonce
, 0, 12);
353 memcpy(nonce
+ 12, pos
, 4);
360 decrypted
= malloc(left
);
361 if (decrypted
== NULL
)
363 memcpy(decrypted
, pos
, left
);
365 if (aes_128_eax_decrypt(data
->tek
, nonce
, sizeof(nonce
),
366 respData
, 22, decrypted
, left
, tag
)) {
367 wpa_printf(MSG_WARNING
, "EAP-PSK: PCHANNEL decryption failed");
369 data
->state
= FAILURE
;
372 wpa_hexdump(MSG_DEBUG
, "EAP-PSK: Decrypted PCHANNEL message",
376 switch (decrypted
[0] >> 6) {
377 case EAP_PSK_R_FLAG_CONT
:
378 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - CONT - unsupported");
379 data
->state
= FAILURE
;
381 case EAP_PSK_R_FLAG_DONE_SUCCESS
:
382 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - DONE_SUCCESS");
383 data
->state
= SUCCESS
;
385 case EAP_PSK_R_FLAG_DONE_FAILURE
:
386 wpa_printf(MSG_DEBUG
, "EAP-PSK: R flag - DONE_FAILURE");
387 data
->state
= FAILURE
;
394 static void eap_psk_process(struct eap_sm
*sm
, void *priv
,
395 u8
*respData
, size_t respDataLen
)
397 struct eap_psk_data
*data
= priv
;
398 struct eap_psk_hdr
*resp
;
400 if (sm
->user
== NULL
|| sm
->user
->password
== NULL
) {
401 wpa_printf(MSG_INFO
, "EAP-PSK: Plaintext password not "
403 data
->state
= FAILURE
;
407 resp
= (struct eap_psk_hdr
*) respData
;
409 switch (EAP_PSK_FLAGS_GET_T(resp
->flags
)) {
411 eap_psk_process_2(sm
, data
, respData
, respDataLen
);
414 eap_psk_process_4(sm
, data
, respData
, respDataLen
);
420 static Boolean
eap_psk_isDone(struct eap_sm
*sm
, void *priv
)
422 struct eap_psk_data
*data
= priv
;
423 return data
->state
== SUCCESS
|| data
->state
== FAILURE
;
427 static u8
* eap_psk_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
429 struct eap_psk_data
*data
= priv
;
432 if (data
->state
!= SUCCESS
)
435 key
= malloc(EAP_MSK_LEN
);
438 memcpy(key
, data
->msk
, EAP_MSK_LEN
);
445 static u8
* eap_psk_get_emsk(struct eap_sm
*sm
, void *priv
, size_t *len
)
447 struct eap_psk_data
*data
= priv
;
450 if (data
->state
!= SUCCESS
)
453 key
= malloc(EAP_EMSK_LEN
);
456 memcpy(key
, data
->emsk
, EAP_EMSK_LEN
);
463 static Boolean
eap_psk_isSuccess(struct eap_sm
*sm
, void *priv
)
465 struct eap_psk_data
*data
= priv
;
466 return data
->state
== SUCCESS
;
470 int eap_server_psk_register(void)
472 struct eap_method
*eap
;
475 eap
= eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION
,
476 EAP_VENDOR_IETF
, EAP_TYPE_PSK
, "PSK");
480 eap
->init
= eap_psk_init
;
481 eap
->reset
= eap_psk_reset
;
482 eap
->buildReq
= eap_psk_buildReq
;
483 eap
->check
= eap_psk_check
;
484 eap
->process
= eap_psk_process
;
485 eap
->isDone
= eap_psk_isDone
;
486 eap
->getKey
= eap_psk_getKey
;
487 eap
->isSuccess
= eap_psk_isSuccess
;
488 eap
->get_emsk
= eap_psk_get_emsk
;
490 ret
= eap_server_method_register(eap
);
492 eap_server_method_free(eap
);