2 * Testing tool for EAPOL-Key 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 "ap/wpa_auth.h"
14 #include "../fuzzer-common.h"
23 u8 auth_addr
[ETH_ALEN
];
24 u8 supp_addr
[ETH_ALEN
];
29 size_t supp_eapol_len
;
31 struct wpa_auth_callbacks auth_cb
;
32 struct wpa_authenticator
*auth_group
;
33 struct wpa_state_machine
*auth
;
39 int key_request_done1
;
44 const struct wpa_driver_ops
*const wpa_drivers
[] = { NULL
};
47 static int auth_read_msg(struct wpa
*wpa
);
48 static void supp_eapol_key_request(void *eloop_data
, void *user_ctx
);
51 static u8
* read_msg(struct wpa
*wpa
, size_t *ret_len
)
56 if (wpa
->data_len
- wpa
->data_offset
< 2) {
57 wpa_printf(MSG_ERROR
, "TEST-ERROR: Could not read msg len");
61 msg_len
= WPA_GET_BE16(&wpa
->data
[wpa
->data_offset
]);
62 wpa
->data_offset
+= 2;
64 msg
= os_malloc(msg_len
);
67 if (msg_len
> 0 && wpa
->data_len
- wpa
->data_offset
< msg_len
) {
68 wpa_printf(MSG_ERROR
, "TEST-ERROR: Truncated msg (msg_len=%u)",
74 os_memcpy(msg
, &wpa
->data
[wpa
->data_offset
], msg_len
);
75 wpa
->data_offset
+= msg_len
;
76 wpa_hexdump(MSG_DEBUG
, "TEST: Read message from file", msg
, msg_len
);
83 static void auth_eapol_rx(void *eloop_data
, void *user_ctx
)
85 struct wpa
*wpa
= eloop_data
;
87 wpa_printf(MSG_DEBUG
, "AUTH: RX EAPOL frame");
89 wpa_receive(wpa
->auth_group
, wpa
->auth
, wpa
->supp_eapol
,
91 if (!wpa
->auth_sent
) {
92 /* Speed up process by not going through retransmit timeout */
94 "AUTH: No response was sent - process next message");
97 if (wpa
->wpa1
&& wpa
->key_request_done
&& !wpa
->key_request_done1
) {
98 wpa
->key_request_done1
= 1;
99 eloop_register_timeout(0, 0, supp_eapol_key_request
,
106 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
110 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
113 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
117 static int auth_read_msg(struct wpa
*wpa
)
119 os_free(wpa
->supp_eapol
);
120 wpa
->supp_eapol
= read_msg(wpa
, &wpa
->supp_eapol_len
);
121 if (!wpa
->supp_eapol
)
123 eloop_register_timeout(0, 0, auth_eapol_rx
, wpa
, NULL
);
128 static int auth_send_eapol(void *ctx
, const u8
*addr
, const u8
*data
,
129 size_t data_len
, int encrypt
)
131 struct wpa
*wpa
= ctx
;
133 wpa_printf(MSG_DEBUG
, "AUTH: %s(addr=" MACSTR
" data_len=%lu "
135 __func__
, MAC2STR(addr
), (unsigned long) data_len
, encrypt
);
138 return auth_read_msg(wpa
);
142 static const u8
* auth_get_psk(void *ctx
, const u8
*addr
,
143 const u8
*p2p_dev_addr
, const u8
*prev_psk
,
144 size_t *psk_len
, int *vlan_id
)
146 struct wpa
*wpa
= ctx
;
148 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
149 __func__
, MAC2STR(addr
), prev_psk
);
160 static void supp_eapol_key_request(void *eloop_data
, void *user_ctx
)
162 struct wpa
*wpa
= eloop_data
;
164 wpa_printf(MSG_DEBUG
, "SUPP: EAPOL-Key Request trigger");
165 if (!eloop_is_timeout_registered(auth_eapol_rx
, wpa
, NULL
))
170 static int auth_set_key(void *ctx
, int vlan_id
, enum wpa_alg alg
,
171 const u8
*addr
, int idx
, u8
*key
,
174 struct wpa
*wpa
= ctx
;
176 wpa_printf(MSG_DEBUG
, "AUTH: %s (vlan_id=%d alg=%d idx=%d key_len=%d)",
177 __func__
, vlan_id
, alg
, idx
, (int) key_len
);
179 wpa_printf(MSG_DEBUG
, "AUTH: addr=" MACSTR
, MAC2STR(addr
));
181 if (alg
!= WPA_ALG_NONE
&& idx
== 0 && key_len
> 0 &&
182 !wpa
->key_request_done
) {
183 wpa_printf(MSG_DEBUG
, "Test EAPOL-Key Request");
184 wpa
->key_request_done
= 1;
186 eloop_register_timeout(0, 0, supp_eapol_key_request
,
194 static int auth_init_group(struct wpa
*wpa
)
196 struct wpa_auth_config conf
;
198 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
200 os_memset(&conf
, 0, sizeof(conf
));
203 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
204 conf
.wpa_pairwise
= WPA_CIPHER_TKIP
;
205 conf
.wpa_group
= WPA_CIPHER_TKIP
;
208 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
209 conf
.wpa_pairwise
= WPA_CIPHER_CCMP
;
210 conf
.rsn_pairwise
= WPA_CIPHER_CCMP
;
211 conf
.wpa_group
= WPA_CIPHER_CCMP
;
213 conf
.group_mgmt_cipher
= WPA_CIPHER_AES_128_CMAC
;
215 conf
.eapol_version
= 2;
216 conf
.wpa_group_update_count
= 4;
217 conf
.wpa_pairwise_update_count
= 4;
219 wpa
->auth_cb
.logger
= auth_logger
;
220 wpa
->auth_cb
.send_eapol
= auth_send_eapol
;
221 wpa
->auth_cb
.get_psk
= auth_get_psk
;
222 wpa
->auth_cb
.set_key
= auth_set_key
;
224 wpa
->auth_group
= wpa_init(wpa
->auth_addr
, &conf
, &wpa
->auth_cb
, wpa
);
225 if (!wpa
->auth_group
) {
226 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
234 static int auth_init(struct wpa
*wpa
)
238 static const u8 ie_rsn
[] = {
239 0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
240 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
241 0x00, 0x0f, 0xac, 0x02, 0x80, 0x00
243 static const u8 ie_wpa
[] = {
244 0xdd, 0x16, 0x00, 0x50, 0xf2, 0x01, 0x01, 0x00,
245 0x00, 0x50, 0xf2, 0x02, 0x01, 0x00, 0x00, 0x50,
246 0xf2, 0x02, 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02
251 supp_ie_len
= sizeof(ie_wpa
);
254 supp_ie_len
= sizeof(ie_rsn
);
257 wpa
->auth
= wpa_auth_sta_init(wpa
->auth_group
, wpa
->supp_addr
, NULL
);
259 wpa_printf(MSG_DEBUG
, "AUTH: wpa_auth_sta_init() failed");
263 if (wpa_validate_wpa_ie(wpa
->auth_group
, wpa
->auth
, 2412, supp_ie
,
264 supp_ie_len
, NULL
, 0, NULL
, 0, NULL
, 0) !=
266 wpa_printf(MSG_DEBUG
, "AUTH: wpa_validate_wpa_ie() failed");
270 wpa_auth_sm_event(wpa
->auth
, WPA_ASSOC
);
272 wpa_auth_sta_associated(wpa
->auth_group
, wpa
->auth
);
278 static void deinit(struct wpa
*wpa
)
280 wpa_auth_sta_deinit(wpa
->auth
);
281 wpa_deinit(wpa
->auth_group
);
282 os_free(wpa
->supp_eapol
);
283 wpa
->supp_eapol
= NULL
;
287 int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
)
291 wpa_fuzzer_set_debug_level();
293 if (os_program_init())
296 os_memset(&wpa
, 0, sizeof(wpa
));
300 os_memset(wpa
.auth_addr
, 0x12, ETH_ALEN
);
301 os_memset(wpa
.supp_addr
, 0x32, ETH_ALEN
);
302 os_memset(wpa
.psk
, 0x44, PMK_LEN
);
305 wpa_printf(MSG_ERROR
, "Failed to initialize event loop");
309 if (auth_init_group(&wpa
) < 0)
312 if (auth_init(&wpa
) < 0)
315 wpa_printf(MSG_DEBUG
, "Starting eloop");
317 wpa_printf(MSG_DEBUG
, "eloop done");