2 * Testing tool for EAPOL-Key Supplicant/Authenticator routines
3 * Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "rsn_supp/wpa.h"
14 #include "ap/wpa_auth.h"
18 enum { AUTH
, SUPP
} test_peer
;
19 enum { READ
, WRITE
} test_oper
;
23 u8 auth_addr
[ETH_ALEN
];
24 u8 supp_addr
[ETH_ALEN
];
27 /* from authenticator */
29 size_t auth_eapol_len
;
33 size_t supp_eapol_len
;
36 struct wpa_authenticator
*auth_group
;
37 struct wpa_state_machine
*auth
;
43 int key_request_done1
;
48 const struct wpa_driver_ops
*const wpa_drivers
[] = { NULL
};
51 static int auth_read_msg(struct wpa
*wpa
);
52 static void supp_eapol_key_request(void *eloop_data
, void *user_ctx
);
55 static void usage(void) {
57 "usage: test-eapol <auth/supp> <read/write> <file>");
62 static void write_msg(FILE *f
, const u8
*msg
, size_t msg_len
)
66 wpa_printf(MSG_DEBUG
, "TEST: Write message to file (msg_len=%u)",
67 (unsigned int) msg_len
);
68 WPA_PUT_BE16(len
, msg_len
);
70 fwrite(msg
, msg_len
, 1, f
);
74 static u8
* read_msg(FILE *f
, size_t *ret_len
)
80 if (fread(len
, 2, 1, f
) != 1) {
81 wpa_printf(MSG_ERROR
, "TEST-ERROR: Could not read msg len");
85 msg_len
= WPA_GET_BE16(len
);
87 msg
= os_malloc(msg_len
);
90 if (msg_len
> 0 && fread(msg
, msg_len
, 1, f
) != 1) {
91 wpa_printf(MSG_ERROR
, "TEST-ERROR: Truncated msg (msg_len=%u)",
97 wpa_hexdump(MSG_DEBUG
, "TEST: Read message from file", msg
, msg_len
);
104 static int supp_get_bssid(void *ctx
, u8
*bssid
)
106 struct wpa
*wpa
= ctx
;
107 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
108 os_memcpy(bssid
, wpa
->auth_addr
, ETH_ALEN
);
113 static void supp_set_state(void *ctx
, enum wpa_states state
)
115 wpa_printf(MSG_DEBUG
, "SUPP: %s(state=%d)", __func__
, state
);
119 static void auth_eapol_rx(void *eloop_data
, void *user_ctx
)
121 struct wpa
*wpa
= eloop_data
;
123 wpa_printf(MSG_DEBUG
, "AUTH: RX EAPOL frame");
125 wpa_receive(wpa
->auth_group
, wpa
->auth
, wpa
->supp_eapol
,
126 wpa
->supp_eapol_len
);
127 if (!wpa
->auth_sent
&& wpa
->test_peer
== SUPP
&&
128 wpa
->test_oper
== READ
) {
129 /* Speed up process by not going through retransmit timeout */
130 wpa_printf(MSG_DEBUG
,
131 "AUTH: No response was sent - process next message");
134 if (wpa
->wpa1
&& wpa
->key_request_done
&& !wpa
->key_request_done1
) {
135 wpa
->key_request_done1
= 1;
136 eloop_register_timeout(0, 0, supp_eapol_key_request
,
143 static void supp_eapol_rx(void *eloop_data
, void *user_ctx
)
145 struct wpa
*wpa
= eloop_data
;
147 wpa_printf(MSG_DEBUG
, "SUPP: RX EAPOL frame");
148 wpa_sm_rx_eapol(wpa
->supp
, wpa
->auth_addr
, wpa
->auth_eapol
,
149 wpa
->auth_eapol_len
);
153 static int supp_read_msg(struct wpa
*wpa
)
155 os_free(wpa
->auth_eapol
);
156 wpa
->auth_eapol
= read_msg(wpa
->f
, &wpa
->auth_eapol_len
);
157 if (!wpa
->auth_eapol
)
159 eloop_register_timeout(0, 0, supp_eapol_rx
, wpa
, NULL
);
164 static int supp_ether_send(void *ctx
, const u8
*dest
, u16 proto
, const u8
*buf
,
167 struct wpa
*wpa
= ctx
;
169 wpa_printf(MSG_DEBUG
, "SUPP: %s(dest=" MACSTR
" proto=0x%04x "
171 __func__
, MAC2STR(dest
), proto
, (unsigned long) len
);
173 if (wpa
->test_peer
== SUPP
&& wpa
->test_oper
== WRITE
)
174 write_msg(wpa
->f
, buf
, len
);
176 if (wpa
->test_peer
== AUTH
&& wpa
->test_oper
== READ
)
177 return supp_read_msg(wpa
);
179 os_free(wpa
->supp_eapol
);
180 wpa
->supp_eapol
= os_malloc(len
);
181 if (!wpa
->supp_eapol
)
183 os_memcpy(wpa
->supp_eapol
, buf
, len
);
184 wpa
->supp_eapol_len
= len
;
185 eloop_register_timeout(0, 0, auth_eapol_rx
, wpa
, NULL
);
191 static u8
* supp_alloc_eapol(void *ctx
, u8 type
, const void *data
,
192 u16 data_len
, size_t *msg_len
, void **data_pos
)
194 struct ieee802_1x_hdr
*hdr
;
196 wpa_printf(MSG_DEBUG
, "SUPP: %s(type=%d data_len=%d)",
197 __func__
, type
, data_len
);
199 *msg_len
= sizeof(*hdr
) + data_len
;
200 hdr
= os_malloc(*msg_len
);
206 hdr
->length
= host_to_be16(data_len
);
209 os_memcpy(hdr
+ 1, data
, data_len
);
211 os_memset(hdr
+ 1, 0, data_len
);
220 static int supp_get_beacon_ie(void *ctx
)
222 struct wpa
*wpa
= ctx
;
226 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
228 ie
= wpa_auth_get_wpa_ie(wpa
->auth_group
, &ielen
);
229 if (ie
== NULL
|| ielen
< 1)
231 if (ie
[0] == WLAN_EID_RSN
)
232 return wpa_sm_set_ap_rsn_ie(wpa
->supp
, ie
, 2 + ie
[1]);
233 return wpa_sm_set_ap_wpa_ie(wpa
->supp
, ie
, 2 + ie
[1]);
237 static int supp_set_key(void *ctx
, enum wpa_alg alg
,
238 const u8
*addr
, int key_idx
, int set_tx
,
239 const u8
*seq
, size_t seq_len
,
240 const u8
*key
, size_t key_len
)
242 wpa_printf(MSG_DEBUG
, "SUPP: %s(alg=%d addr=" MACSTR
" key_idx=%d "
244 __func__
, alg
, MAC2STR(addr
), key_idx
, set_tx
);
245 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - seq", seq
, seq_len
);
246 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - key", key
, key_len
);
251 static int supp_mlme_setprotection(void *ctx
, const u8
*addr
,
252 int protection_type
, int key_type
)
254 wpa_printf(MSG_DEBUG
, "SUPP: %s(addr=" MACSTR
" protection_type=%d "
256 __func__
, MAC2STR(addr
), protection_type
, key_type
);
261 static void supp_cancel_auth_timeout(void *ctx
)
263 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
267 static void * supp_get_network_ctx(void *ctx
)
273 static void supp_deauthenticate(void *ctx
, u16 reason_code
)
275 wpa_printf(MSG_DEBUG
, "SUPP: %s(%d)", __func__
, reason_code
);
279 static enum wpa_states
supp_get_state(void *ctx
)
281 return WPA_COMPLETED
;
285 static int supp_init(struct wpa
*wpa
)
287 struct wpa_sm_ctx
*ctx
= os_zalloc(sizeof(*ctx
));
294 ctx
->set_state
= supp_set_state
;
295 ctx
->get_bssid
= supp_get_bssid
;
296 ctx
->ether_send
= supp_ether_send
;
297 ctx
->get_beacon_ie
= supp_get_beacon_ie
;
298 ctx
->alloc_eapol
= supp_alloc_eapol
;
299 ctx
->set_key
= supp_set_key
;
300 ctx
->mlme_setprotection
= supp_mlme_setprotection
;
301 ctx
->cancel_auth_timeout
= supp_cancel_auth_timeout
;
302 ctx
->get_network_ctx
= supp_get_network_ctx
;
303 ctx
->deauthenticate
= supp_deauthenticate
;
304 ctx
->get_state
= supp_get_state
;
305 wpa
->supp
= wpa_sm_init(ctx
);
307 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_init() failed");
311 wpa_sm_set_own_addr(wpa
->supp
, wpa
->supp_addr
);
313 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_RSN_ENABLED
, 0);
314 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PROTO
, WPA_PROTO_WPA
);
315 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PAIRWISE
,
317 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_GROUP
, WPA_CIPHER_TKIP
);
318 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_KEY_MGMT
,
321 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_RSN_ENABLED
, 1);
322 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PROTO
, WPA_PROTO_RSN
);
323 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PAIRWISE
,
325 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_GROUP
, WPA_CIPHER_CCMP
);
326 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_KEY_MGMT
,
328 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_MFP
,
329 MGMT_FRAME_PROTECTION_OPTIONAL
);
331 wpa_sm_set_pmk(wpa
->supp
, wpa
->psk
, PMK_LEN
, NULL
, NULL
);
333 wpa
->supp_ie_len
= sizeof(wpa
->supp_ie
);
334 if (wpa_sm_set_assoc_wpa_ie_default(wpa
->supp
, wpa
->supp_ie
,
335 &wpa
->supp_ie_len
) < 0) {
336 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
341 wpa_sm_notify_assoc(wpa
->supp
, wpa
->auth_addr
);
347 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
351 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
354 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
358 static int auth_read_msg(struct wpa
*wpa
)
360 os_free(wpa
->supp_eapol
);
361 wpa
->supp_eapol
= read_msg(wpa
->f
, &wpa
->supp_eapol_len
);
362 if (!wpa
->supp_eapol
)
364 eloop_register_timeout(0, 0, auth_eapol_rx
, wpa
, NULL
);
369 static int auth_send_eapol(void *ctx
, const u8
*addr
, const u8
*data
,
370 size_t data_len
, int encrypt
)
372 struct wpa
*wpa
= ctx
;
374 wpa_printf(MSG_DEBUG
, "AUTH: %s(addr=" MACSTR
" data_len=%lu "
376 __func__
, MAC2STR(addr
), (unsigned long) data_len
, encrypt
);
379 if (wpa
->test_peer
== AUTH
&& wpa
->test_oper
== WRITE
)
380 write_msg(wpa
->f
, data
, data_len
);
382 if (wpa
->test_peer
== SUPP
&& wpa
->test_oper
== READ
)
383 return auth_read_msg(wpa
);
385 os_free(wpa
->auth_eapol
);
386 wpa
->auth_eapol
= os_malloc(data_len
);
387 if (!wpa
->auth_eapol
)
389 os_memcpy(wpa
->auth_eapol
, data
, data_len
);
390 wpa
->auth_eapol_len
= data_len
;
391 eloop_register_timeout(0, 0, supp_eapol_rx
, wpa
, NULL
);
397 static const u8
* auth_get_psk(void *ctx
, const u8
*addr
,
398 const u8
*p2p_dev_addr
, const u8
*prev_psk
,
399 size_t *psk_len
, int *vlan_id
)
401 struct wpa
*wpa
= ctx
;
403 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
404 __func__
, MAC2STR(addr
), prev_psk
);
415 static void supp_eapol_key_request(void *eloop_data
, void *user_ctx
)
417 struct wpa
*wpa
= eloop_data
;
419 wpa_printf(MSG_DEBUG
, "SUPP: EAPOL-Key Request trigger");
420 if (wpa
->test_peer
== SUPP
&& wpa
->test_oper
== READ
) {
421 if (!eloop_is_timeout_registered(auth_eapol_rx
, wpa
, NULL
))
424 wpa_sm_key_request(wpa
->supp
, 0, 1);
429 static int auth_set_key(void *ctx
, int vlan_id
, enum wpa_alg alg
,
430 const u8
*addr
, int idx
, u8
*key
,
433 struct wpa
*wpa
= ctx
;
435 wpa_printf(MSG_DEBUG
, "AUTH: %s (vlan_id=%d alg=%d idx=%d key_len=%d)",
436 __func__
, vlan_id
, alg
, idx
, (int) key_len
);
438 wpa_printf(MSG_DEBUG
, "AUTH: addr=" MACSTR
, MAC2STR(addr
));
440 if (alg
!= WPA_ALG_NONE
&& idx
== 0 && key_len
> 0 &&
441 !wpa
->key_request_done
) {
442 wpa_printf(MSG_DEBUG
, "Test EAPOL-Key Request");
443 wpa
->key_request_done
= 1;
445 eloop_register_timeout(0, 0, supp_eapol_key_request
,
453 static int auth_init_group(struct wpa
*wpa
)
455 struct wpa_auth_config conf
;
456 struct wpa_auth_callbacks cb
;
458 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
460 os_memset(&conf
, 0, sizeof(conf
));
463 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
464 conf
.wpa_pairwise
= WPA_CIPHER_TKIP
;
465 conf
.wpa_group
= WPA_CIPHER_TKIP
;
468 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
469 conf
.wpa_pairwise
= WPA_CIPHER_CCMP
;
470 conf
.rsn_pairwise
= WPA_CIPHER_CCMP
;
471 conf
.wpa_group
= WPA_CIPHER_CCMP
;
473 conf
.group_mgmt_cipher
= WPA_CIPHER_AES_128_CMAC
;
475 conf
.eapol_version
= 2;
476 conf
.wpa_group_update_count
= 4;
477 conf
.wpa_pairwise_update_count
= 4;
479 os_memset(&cb
, 0, sizeof(cb
));
480 cb
.logger
= auth_logger
;
481 cb
.send_eapol
= auth_send_eapol
;
482 cb
.get_psk
= auth_get_psk
;
483 cb
.set_key
= auth_set_key
,
485 wpa
->auth_group
= wpa_init(wpa
->auth_addr
, &conf
, &cb
, wpa
);
486 if (!wpa
->auth_group
) {
487 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
495 static int auth_init(struct wpa
*wpa
)
497 if (wpa
->test_peer
== AUTH
&& wpa
->test_oper
== READ
)
498 return supp_read_msg(wpa
);
500 wpa
->auth
= wpa_auth_sta_init(wpa
->auth_group
, wpa
->supp_addr
, NULL
);
502 wpa_printf(MSG_DEBUG
, "AUTH: wpa_auth_sta_init() failed");
506 if (wpa_validate_wpa_ie(wpa
->auth_group
, wpa
->auth
, 2412, wpa
->supp_ie
,
507 wpa
->supp_ie_len
, NULL
, 0, NULL
, 0) !=
509 wpa_printf(MSG_DEBUG
, "AUTH: wpa_validate_wpa_ie() failed");
513 wpa_auth_sm_event(wpa
->auth
, WPA_ASSOC
);
515 wpa_auth_sta_associated(wpa
->auth_group
, wpa
->auth
);
521 static void deinit(struct wpa
*wpa
)
523 wpa_auth_sta_deinit(wpa
->auth
);
524 wpa_sm_deinit(wpa
->supp
);
525 wpa_deinit(wpa
->auth_group
);
526 os_free(wpa
->auth_eapol
);
527 wpa
->auth_eapol
= NULL
;
528 os_free(wpa
->supp_eapol
);
529 wpa
->supp_eapol
= NULL
;
533 int main(int argc
, char *argv
[])
539 if (os_program_init())
543 wpa_debug_show_keys
= 1;
544 os_memset(&wpa
, 0, sizeof(wpa
));
549 if (os_strcmp(argv
[1], "auth") == 0) {
550 wpa
.test_peer
= AUTH
;
551 } else if (os_strcmp(argv
[1], "auth1") == 0) {
552 wpa
.test_peer
= AUTH
;
554 } else if (os_strcmp(argv
[1], "supp") == 0) {
555 wpa
.test_peer
= SUPP
;
556 } else if (os_strcmp(argv
[1], "supp1") == 0) {
557 wpa
.test_peer
= SUPP
;
563 if (os_strcmp(argv
[2], "read") == 0)
564 wpa
.test_oper
= READ
;
565 else if (os_strcmp(argv
[2], "write") == 0)
566 wpa
.test_oper
= WRITE
;
572 wpa
.f
= fopen(file
, wpa
.test_oper
== READ
? "r" : "w");
576 os_memset(wpa
.auth_addr
, 0x12, ETH_ALEN
);
577 os_memset(wpa
.supp_addr
, 0x32, ETH_ALEN
);
578 os_memset(wpa
.psk
, 0x44, PMK_LEN
);
581 wpa_printf(MSG_ERROR
, "Failed to initialize event loop");
585 if (auth_init_group(&wpa
) < 0)
588 if (supp_init(&wpa
) < 0)
591 if (auth_init(&wpa
) < 0)
594 wpa_printf(MSG_DEBUG
, "Starting eloop");
596 wpa_printf(MSG_DEBUG
, "eloop done");