]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/fuzzing/eapol-key-supp/eapol-key-supp.c
tests: New style fuzzing tools for EAPOL-Key frame processing
[thirdparty/hostap.git] / tests / fuzzing / eapol-key-supp / eapol-key-supp.c
1 /*
2 * Testing tool for EAPOL-Key Supplicant routines
3 * Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "rsn_supp/wpa.h"
14 #include "../fuzzer-common.h"
15
16
17 struct wpa {
18 const u8 *data;
19 size_t data_len;
20 size_t data_offset;
21 int wpa1;
22
23 u8 auth_addr[ETH_ALEN];
24 u8 supp_addr[ETH_ALEN];
25 u8 psk[PMK_LEN];
26
27 /* from authenticator */
28 u8 *auth_eapol;
29 size_t auth_eapol_len;
30
31 struct wpa_sm *supp;
32
33 u8 supp_ie[80];
34 size_t supp_ie_len;
35 };
36
37
38 const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
39
40
41 static u8 * read_msg(struct wpa *wpa, size_t *ret_len)
42 {
43 u16 msg_len;
44 u8 *msg;
45
46 if (wpa->data_len - wpa->data_offset < 2) {
47 wpa_printf(MSG_ERROR, "TEST-ERROR: Could not read msg len");
48 eloop_terminate();
49 return NULL;
50 }
51 msg_len = WPA_GET_BE16(&wpa->data[wpa->data_offset]);
52 wpa->data_offset += 2;
53
54 msg = os_malloc(msg_len);
55 if (!msg)
56 return NULL;
57 if (msg_len > 0 && wpa->data_len - wpa->data_offset < msg_len) {
58 wpa_printf(MSG_ERROR, "TEST-ERROR: Truncated msg (msg_len=%u)",
59 msg_len);
60 os_free(msg);
61 eloop_terminate();
62 return NULL;
63 }
64 os_memcpy(msg, &wpa->data[wpa->data_offset], msg_len);
65 wpa->data_offset += msg_len;
66 wpa_hexdump(MSG_DEBUG, "TEST: Read message from file", msg, msg_len);
67
68 *ret_len = msg_len;
69 return msg;
70 }
71
72
73 static int supp_get_bssid(void *ctx, u8 *bssid)
74 {
75 struct wpa *wpa = ctx;
76 wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
77 os_memcpy(bssid, wpa->auth_addr, ETH_ALEN);
78 return 0;
79 }
80
81
82 static void supp_set_state(void *ctx, enum wpa_states state)
83 {
84 wpa_printf(MSG_DEBUG, "SUPP: %s(state=%d)", __func__, state);
85 }
86
87
88 static void supp_eapol_rx(void *eloop_data, void *user_ctx)
89 {
90 struct wpa *wpa = eloop_data;
91
92 wpa_printf(MSG_DEBUG, "SUPP: RX EAPOL frame");
93 wpa_sm_rx_eapol(wpa->supp, wpa->auth_addr, wpa->auth_eapol,
94 wpa->auth_eapol_len);
95 }
96
97
98 static int supp_read_msg(struct wpa *wpa)
99 {
100 os_free(wpa->auth_eapol);
101 wpa->auth_eapol = read_msg(wpa, &wpa->auth_eapol_len);
102 if (!wpa->auth_eapol)
103 return -1;
104 eloop_register_timeout(0, 0, supp_eapol_rx, wpa, NULL);
105 return 0;
106 }
107
108
109 static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
110 size_t len)
111 {
112 struct wpa *wpa = ctx;
113
114 wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x "
115 "len=%lu)",
116 __func__, MAC2STR(dest), proto, (unsigned long) len);
117
118 return supp_read_msg(wpa);
119 }
120
121
122 static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data,
123 u16 data_len, size_t *msg_len, void **data_pos)
124 {
125 struct ieee802_1x_hdr *hdr;
126
127 wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)",
128 __func__, type, data_len);
129
130 *msg_len = sizeof(*hdr) + data_len;
131 hdr = os_malloc(*msg_len);
132 if (hdr == NULL)
133 return NULL;
134
135 hdr->version = 2;
136 hdr->type = type;
137 hdr->length = host_to_be16(data_len);
138
139 if (data)
140 os_memcpy(hdr + 1, data, data_len);
141 else
142 os_memset(hdr + 1, 0, data_len);
143
144 if (data_pos)
145 *data_pos = hdr + 1;
146
147 return (u8 *) hdr;
148 }
149
150
151 static int supp_get_beacon_ie(void *ctx)
152 {
153 struct wpa *wpa = ctx;
154 const u8 *ie;
155 static const u8 wpaie[] = {
156 0xdd, 0x16, 0x00, 0x50, 0xf2, 0x01, 0x01, 0x00,
157 0x00, 0x50, 0xf2, 0x02, 0x01, 0x00, 0x00, 0x50,
158 0xf2, 0x02, 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02
159 };
160 static const u8 rsne[] = {
161 0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
162 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
163 0x00, 0x0f, 0xac, 0x02, 0xc0, 0x00
164 };
165
166 wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
167
168 ie = wpa->wpa1 ? wpaie : rsne;
169 if (ie[0] == WLAN_EID_RSN)
170 return wpa_sm_set_ap_rsn_ie(wpa->supp, ie, 2 + ie[1]);
171 return wpa_sm_set_ap_wpa_ie(wpa->supp, ie, 2 + ie[1]);
172 }
173
174
175 static int supp_set_key(void *ctx, enum wpa_alg alg,
176 const u8 *addr, int key_idx, int set_tx,
177 const u8 *seq, size_t seq_len,
178 const u8 *key, size_t key_len)
179 {
180 wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
181 "set_tx=%d)",
182 __func__, alg, MAC2STR(addr), key_idx, set_tx);
183 wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
184 wpa_hexdump(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
185 return 0;
186 }
187
188
189 static int supp_mlme_setprotection(void *ctx, const u8 *addr,
190 int protection_type, int key_type)
191 {
192 wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d "
193 "key_type=%d)",
194 __func__, MAC2STR(addr), protection_type, key_type);
195 return 0;
196 }
197
198
199 static void supp_cancel_auth_timeout(void *ctx)
200 {
201 wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
202 }
203
204
205 static void * supp_get_network_ctx(void *ctx)
206 {
207 return (void *) 1;
208 }
209
210
211 static void supp_deauthenticate(void *ctx, u16 reason_code)
212 {
213 wpa_printf(MSG_DEBUG, "SUPP: %s(%d)", __func__, reason_code);
214 }
215
216
217 static enum wpa_states supp_get_state(void *ctx)
218 {
219 return WPA_COMPLETED;
220 }
221
222
223 static int supp_init(struct wpa *wpa)
224 {
225 struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx));
226
227 if (!ctx)
228 return -1;
229
230 ctx->ctx = wpa;
231 ctx->msg_ctx = wpa;
232 ctx->set_state = supp_set_state;
233 ctx->get_bssid = supp_get_bssid;
234 ctx->ether_send = supp_ether_send;
235 ctx->get_beacon_ie = supp_get_beacon_ie;
236 ctx->alloc_eapol = supp_alloc_eapol;
237 ctx->set_key = supp_set_key;
238 ctx->mlme_setprotection = supp_mlme_setprotection;
239 ctx->cancel_auth_timeout = supp_cancel_auth_timeout;
240 ctx->get_network_ctx = supp_get_network_ctx;
241 ctx->deauthenticate = supp_deauthenticate;
242 ctx->get_state = supp_get_state;
243 wpa->supp = wpa_sm_init(ctx);
244 if (!wpa->supp) {
245 wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed");
246 return -1;
247 }
248
249 wpa_sm_set_own_addr(wpa->supp, wpa->supp_addr);
250 if (wpa->wpa1) {
251 wpa_sm_set_param(wpa->supp, WPA_PARAM_RSN_ENABLED, 0);
252 wpa_sm_set_param(wpa->supp, WPA_PARAM_PROTO, WPA_PROTO_WPA);
253 wpa_sm_set_param(wpa->supp, WPA_PARAM_PAIRWISE,
254 WPA_CIPHER_TKIP);
255 wpa_sm_set_param(wpa->supp, WPA_PARAM_GROUP, WPA_CIPHER_TKIP);
256 wpa_sm_set_param(wpa->supp, WPA_PARAM_KEY_MGMT,
257 WPA_KEY_MGMT_PSK);
258 } else {
259 wpa_sm_set_param(wpa->supp, WPA_PARAM_RSN_ENABLED, 1);
260 wpa_sm_set_param(wpa->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN);
261 wpa_sm_set_param(wpa->supp, WPA_PARAM_PAIRWISE,
262 WPA_CIPHER_CCMP);
263 wpa_sm_set_param(wpa->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
264 wpa_sm_set_param(wpa->supp, WPA_PARAM_KEY_MGMT,
265 WPA_KEY_MGMT_PSK);
266 wpa_sm_set_param(wpa->supp, WPA_PARAM_MFP,
267 MGMT_FRAME_PROTECTION_OPTIONAL);
268 }
269 wpa_sm_set_pmk(wpa->supp, wpa->psk, PMK_LEN, NULL, NULL);
270
271 wpa->supp_ie_len = sizeof(wpa->supp_ie);
272 if (wpa_sm_set_assoc_wpa_ie_default(wpa->supp, wpa->supp_ie,
273 &wpa->supp_ie_len) < 0) {
274 wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
275 " failed");
276 return -1;
277 }
278
279 wpa_sm_notify_assoc(wpa->supp, wpa->auth_addr);
280 supp_read_msg(wpa);
281
282 return 0;
283 }
284
285
286 static void deinit(struct wpa *wpa)
287 {
288 wpa_sm_deinit(wpa->supp);
289 os_free(wpa->auth_eapol);
290 wpa->auth_eapol = NULL;
291 }
292
293
294 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
295 {
296 struct wpa wpa;
297
298 wpa_fuzzer_set_debug_level();
299
300 if (os_program_init())
301 return -1;
302
303 os_memset(&wpa, 0, sizeof(wpa));
304 wpa.data = data;
305 wpa.data_len = size;
306
307 os_memset(wpa.auth_addr, 0x12, ETH_ALEN);
308 os_memset(wpa.supp_addr, 0x32, ETH_ALEN);
309 os_memset(wpa.psk, 0x44, PMK_LEN);
310
311 if (eloop_init()) {
312 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
313 goto fail;
314 }
315
316 if (supp_init(&wpa) < 0)
317 goto fail;
318
319 wpa_printf(MSG_DEBUG, "Starting eloop");
320 eloop_run();
321 wpa_printf(MSG_DEBUG, "eloop done");
322
323 fail:
324 deinit(&wpa);
325
326 eloop_destroy();
327
328 os_program_deinit();
329
330 return 0;
331 }