/src/hostap/tests/fuzzing/eapol-supp/eapol-supp.c
Line | Count | Source |
1 | | /* |
2 | | * wpa_supplicant - EAPOL fuzzer |
3 | | * Copyright (c) 2015-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 "eapol_supp/eapol_supp_sm.h" |
14 | | #include "rsn_supp/wpa.h" |
15 | | #include "rsn_supp/wpa_i.h" |
16 | | #include "../fuzzer-common.h" |
17 | | |
18 | | |
19 | | struct arg_ctx { |
20 | | const u8 *data; |
21 | | size_t data_len; |
22 | | struct wpa_sm *wpa; |
23 | | struct eapol_sm *eapol; |
24 | | }; |
25 | | |
26 | | |
27 | | static void test_send_eapol(void *eloop_data, void *user_ctx) |
28 | 2.11k | { |
29 | 2.11k | struct arg_ctx *ctx = eloop_data; |
30 | 2.11k | u8 src[ETH_ALEN] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 }; |
31 | 2.11k | u8 wpa_ie[200]; |
32 | 2.11k | size_t wpa_ie_len; |
33 | | |
34 | 2.11k | wpa_hexdump(MSG_MSGDUMP, "fuzzer - EAPOL", ctx->data, ctx->data_len); |
35 | | |
36 | 2.11k | eapol_sm_notify_portEnabled(ctx->eapol, true); |
37 | | |
38 | 2.11k | wpa_sm_set_param(ctx->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN); |
39 | 2.11k | wpa_sm_set_param(ctx->wpa, WPA_PARAM_RSN_ENABLED, 1); |
40 | 2.11k | wpa_sm_set_param(ctx->wpa, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK); |
41 | 2.11k | wpa_sm_set_param(ctx->wpa, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP); |
42 | 2.11k | wpa_sm_set_param(ctx->wpa, WPA_PARAM_GROUP, WPA_CIPHER_CCMP); |
43 | | |
44 | 2.11k | wpa_ie_len = sizeof(wpa_ie); |
45 | 2.11k | wpa_sm_set_assoc_wpa_ie_default(ctx->wpa, wpa_ie, &wpa_ie_len); |
46 | | |
47 | 2.11k | if (eapol_sm_rx_eapol(ctx->eapol, src, ctx->data, ctx->data_len, |
48 | 2.11k | FRAME_ENCRYPTION_UNKNOWN) <= 0) |
49 | 1.85k | wpa_sm_rx_eapol(ctx->wpa, src, ctx->data, ctx->data_len, |
50 | 1.85k | FRAME_ENCRYPTION_UNKNOWN); |
51 | | |
52 | 2.11k | eloop_terminate(); |
53 | 2.11k | } |
54 | | |
55 | | |
56 | | static void * get_network_ctx(void *arg) |
57 | 1.68k | { |
58 | 1.68k | return (void *) 1; |
59 | 1.68k | } |
60 | | |
61 | | |
62 | | static void set_state(void *arg, enum wpa_states state) |
63 | 1.29k | { |
64 | 1.29k | } |
65 | | |
66 | | |
67 | | static void deauthenticate(void *arg, u16 reason_code) |
68 | 0 | { |
69 | 0 | } |
70 | | |
71 | | |
72 | | static u8 * alloc_eapol(void *arg, u8 type, |
73 | | const void *data, u16 data_len, |
74 | | size_t *msg_len, void **data_pos) |
75 | 1.29k | { |
76 | 1.29k | struct ieee802_1x_hdr *hdr; |
77 | | |
78 | 1.29k | *msg_len = sizeof(*hdr) + data_len; |
79 | 1.29k | hdr = os_malloc(*msg_len); |
80 | 1.29k | if (hdr == NULL) |
81 | 0 | return NULL; |
82 | | |
83 | 1.29k | hdr->version = 2; |
84 | 1.29k | hdr->type = type; |
85 | 1.29k | hdr->length = host_to_be16(data_len); |
86 | | |
87 | 1.29k | if (data) |
88 | 0 | os_memcpy(hdr + 1, data, data_len); |
89 | 1.29k | else |
90 | 1.29k | os_memset(hdr + 1, 0, data_len); |
91 | | |
92 | 1.29k | if (data_pos) |
93 | 1.29k | *data_pos = hdr + 1; |
94 | | |
95 | 1.29k | return (u8 *) hdr; |
96 | 1.29k | } |
97 | | |
98 | | |
99 | | static int ether_send(void *arg, const u8 *dest, u16 proto, |
100 | | const u8 *buf, size_t len) |
101 | 1.29k | { |
102 | 1.29k | return 0; |
103 | 1.29k | } |
104 | | |
105 | | |
106 | | static int get_bssid(void *ctx, u8 *bssid) |
107 | 1.29k | { |
108 | 1.29k | return -1; |
109 | 1.29k | } |
110 | | |
111 | | |
112 | | static int eapol_send(void *ctx, int type, const u8 *buf, size_t len) |
113 | 84 | { |
114 | 84 | return 0; |
115 | 84 | } |
116 | | |
117 | | |
118 | | static int init_wpa(struct arg_ctx *arg) |
119 | 2.11k | { |
120 | 2.11k | struct wpa_sm_ctx *ctx; |
121 | | |
122 | 2.11k | ctx = os_zalloc(sizeof(*ctx)); |
123 | 2.11k | if (ctx == NULL) { |
124 | 0 | wpa_printf(MSG_ERROR, "Failed to allocate WPA context."); |
125 | 0 | return -1; |
126 | 0 | } |
127 | | |
128 | 2.11k | ctx->ctx = arg; |
129 | 2.11k | ctx->msg_ctx = arg; |
130 | 2.11k | ctx->get_network_ctx = get_network_ctx; |
131 | 2.11k | ctx->set_state = set_state; |
132 | 2.11k | ctx->deauthenticate = deauthenticate; |
133 | 2.11k | ctx->alloc_eapol = alloc_eapol; |
134 | 2.11k | ctx->ether_send = ether_send; |
135 | 2.11k | ctx->get_bssid = get_bssid; |
136 | | |
137 | 2.11k | arg->wpa = wpa_sm_init(ctx); |
138 | 2.11k | if (!arg->wpa) |
139 | 0 | return -1; |
140 | 2.11k | arg->wpa->pmk_len = PMK_LEN; |
141 | 2.11k | return 0; |
142 | 2.11k | } |
143 | | |
144 | | |
145 | | static int init_eapol(struct arg_ctx *arg) |
146 | 2.11k | { |
147 | 2.11k | struct eapol_ctx *ctx; |
148 | | |
149 | 2.11k | ctx = os_zalloc(sizeof(*ctx)); |
150 | 2.11k | if (ctx == NULL) { |
151 | 0 | wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context."); |
152 | 0 | return -1; |
153 | 0 | } |
154 | | |
155 | 2.11k | ctx->ctx = arg; |
156 | 2.11k | ctx->msg_ctx = arg; |
157 | 2.11k | ctx->eapol_send = eapol_send; |
158 | | |
159 | 2.11k | arg->eapol = eapol_sm_init(ctx); |
160 | 2.11k | return arg->eapol ? 0 : -1; |
161 | 2.11k | } |
162 | | |
163 | | |
164 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
165 | 2.11k | { |
166 | 2.11k | struct arg_ctx ctx; |
167 | | |
168 | 2.11k | wpa_fuzzer_set_debug_level(); |
169 | | |
170 | 2.11k | if (os_program_init()) |
171 | 0 | return 0; |
172 | | |
173 | 2.11k | if (eloop_init()) { |
174 | 0 | wpa_printf(MSG_ERROR, "Failed to initialize event loop"); |
175 | 0 | return 0; |
176 | 0 | } |
177 | | |
178 | 2.11k | os_memset(&ctx, 0, sizeof(ctx)); |
179 | 2.11k | ctx.data = data; |
180 | 2.11k | ctx.data_len = size; |
181 | 2.11k | if (init_wpa(&ctx) || init_eapol(&ctx)) |
182 | 0 | goto fail; |
183 | | |
184 | 2.11k | eloop_register_timeout(0, 0, test_send_eapol, &ctx, NULL); |
185 | | |
186 | 2.11k | wpa_printf(MSG_DEBUG, "Starting eloop"); |
187 | 2.11k | eloop_run(); |
188 | 2.11k | wpa_printf(MSG_DEBUG, "eloop done"); |
189 | | |
190 | 2.11k | fail: |
191 | 2.11k | if (ctx.wpa) |
192 | 2.11k | wpa_sm_deinit(ctx.wpa); |
193 | 2.11k | if (ctx.eapol) |
194 | 2.11k | eapol_sm_deinit(ctx.eapol); |
195 | | |
196 | 2.11k | eloop_destroy(); |
197 | 2.11k | os_program_deinit(); |
198 | | |
199 | 2.11k | return 0; |
200 | 2.11k | } |