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