1 /*
2  * EAP-SIM peer fuzzer
3  * Copyright (c) 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 "eap_peer/eap_methods.h"
13 #include "eap_peer/eap_config.h"
14 #include "eap_peer/eap_i.h"
15 #include "../fuzzer-common.h"
16 
17 int eap_peer_sim_register(void);
18 
19 struct eap_method * registered_eap_method = NULL;
20 
21 
eap_peer_method_alloc(int version,int vendor,enum eap_type method,const char * name)22 struct eap_method * eap_peer_method_alloc(int version, int vendor,
23 					  enum eap_type method,
24 					  const char *name)
25 {
26 	struct eap_method *eap;
27 	eap = os_zalloc(sizeof(*eap));
28 	if (!eap)
29 		return NULL;
30 	eap->version = version;
31 	eap->vendor = vendor;
32 	eap->method = method;
33 	eap->name = name;
34 	return eap;
35 }
36 
37 
eap_peer_method_register(struct eap_method * method)38 int eap_peer_method_register(struct eap_method *method)
39 {
40 	registered_eap_method = method;
41 	return 0;
42 }
43 
44 
45 static struct eap_peer_config eap_mschapv2_config = {
46 	.identity = (u8 *) "user",
47 	.identity_len = 4,
48 	.password = (u8 *) "password",
49 	.password_len = 8,
50 };
51 
eap_get_config(struct eap_sm * sm)52 struct eap_peer_config * eap_get_config(struct eap_sm *sm)
53 {
54 	return &eap_mschapv2_config;
55 }
56 
57 
eap_get_config_identity(struct eap_sm * sm,size_t * len)58 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
59 {
60 	static const char *id = "user";
61 
62 	*len = os_strlen(id);
63 	return (const u8 *) id;
64 }
65 
66 
eap_get_config_password(struct eap_sm * sm,size_t * len)67 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
68 {
69 	struct eap_peer_config *config = eap_get_config(sm);
70 
71 	*len = config->password_len;
72 	return config->password;
73 }
74 
75 
eap_get_config_password2(struct eap_sm * sm,size_t * len,int * hash)76 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
77 {
78 	struct eap_peer_config *config = eap_get_config(sm);
79 
80 	*len = config->password_len;
81 	if (hash)
82 		*hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH);
83 	return config->password;
84 }
85 
86 
eap_get_config_new_password(struct eap_sm * sm,size_t * len)87 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len)
88 {
89 	*len = 3;
90 	return (const u8 *) "new";
91 }
92 
93 
eap_sm_request_identity(struct eap_sm * sm)94 void eap_sm_request_identity(struct eap_sm *sm)
95 {
96 }
97 
98 
eap_sm_request_password(struct eap_sm * sm)99 void eap_sm_request_password(struct eap_sm *sm)
100 {
101 }
102 
103 
eap_sm_request_new_password(struct eap_sm * sm)104 void eap_sm_request_new_password(struct eap_sm *sm)
105 {
106 }
107 
108 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)109 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
110 {
111 	const u8 *pos, *end;
112 	struct eap_sm *sm;
113 	void *priv;
114 	struct eap_method_ret ret;
115 
116 	wpa_fuzzer_set_debug_level();
117 
118 	eap_peer_mschapv2_register();
119 	sm = os_zalloc(sizeof(*sm));
120 	if (!sm)
121 		return 0;
122 	priv = registered_eap_method->init(sm);
123 	os_memset(&ret, 0, sizeof(ret));
124 
125 	pos = data;
126 	end = pos + size;
127 
128 	while (end - pos > 2) {
129 		u16 flen;
130 		struct wpabuf *buf, *req;
131 
132 		flen = WPA_GET_BE16(pos);
133 		pos += 2;
134 		if (end - pos < flen)
135 			break;
136 		req = wpabuf_alloc_copy(pos, flen);
137 		if (!req)
138 			break;
139 		wpa_hexdump_buf(MSG_MSGDUMP, "fuzzer - request", req);
140 		buf = registered_eap_method->process(sm, priv, &ret, req);
141 		wpa_hexdump_buf(MSG_MSGDUMP, "fuzzer - local response", buf);
142 		wpabuf_free(req);
143 		wpabuf_free(buf);
144 		pos += flen;
145 	}
146 
147 	registered_eap_method->deinit(sm, priv);
148 	os_free(registered_eap_method);
149 	os_free(sm);
150 
151 	return 0;
152 }
153