1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: WAPI APIs
15 */
16
17 #include "securec.h"
18 #include "utils/includes.h"
19 #include "utils/common.h"
20 #include "utils/os.h"
21 #include "utils/eloop.h"
22 #include "utils/base64.h"
23 #include "utils/wpabuf.h"
24 #include "common/wpa_common.h"
25 #include "common/defs.h"
26 #include "common/wpa_ctrl.h"
27 #include "l2_packet/l2_packet.h"
28 #include "wpa_supplicant_i.h"
29 #include "driver_i.h"
30 #include "bss.h"
31 #include "wapi.h"
32 #include "wapi_api.h"
33 #include "wai_sm.h"
34 #include "wai_rxtx.h"
35
36 #define WAPI_HEAD_LEN (WAPI_IE_ID_SIZE + WAPI_IE_LENGTH_SIZE + WAPI_IE_VERSION_SIZE + WAPI_IE_AKM_CNT_LEN)
37
wapi_init_iface(struct wpa_supplicant * wpa)38 int wapi_init_iface(struct wpa_supplicant *wpa)
39 {
40 struct wapi_asue_struct *wapi = NULL;
41
42 if (wpa == NULL) {
43 wpa_error_log0(MSG_WARNING, "wpa struct is null");
44 return WAPI_FAILED;
45 }
46 if (wpa->wapi != NULL) {
47 wpa_error_log0(MSG_WARNING, "wapi has initialized");
48 return WAPI_FAILED;
49 }
50
51 wapi = (struct wapi_asue_struct *)os_zalloc(sizeof(struct wapi_asue_struct));
52 if (wapi == NULL) {
53 wpa_error_log0(MSG_WARNING, "Malloc wapi_s memory failed");
54 return WAPI_FAILED;
55 }
56
57 wpa_error_log0(MSG_DEBUG, "Initial WAPI L2 packet");
58 wapi->wapi_l2 = l2_packet_init(wpa->ifname,
59 wpa_drv_get_mac_addr(wpa), ETH_TYPE_WAI, wai_rx_packet, wpa, 1);
60 if (wapi->wapi_l2 == NULL) {
61 os_free(wapi);
62 wpa_error_log0(MSG_DEBUG, "l2_packet_init failed");
63 return WAPI_FAILED;
64 }
65
66 if (l2_packet_get_own_addr(wapi->wapi_l2, wapi->own_mac, ETH_ALEN) != 0) {
67 wpa_error_log0(MSG_DEBUG, "Failed to get own L2 address");
68 l2_packet_deinit(wapi->wapi_l2);
69 os_free(wapi);
70 return WAPI_FAILED;
71 }
72
73 wapi_iface_init(wapi);
74
75 wpa->wapi = wapi;
76 wapi->wpa = wpa;
77
78 wpa_error_log0(MSG_DEBUG, "wapi iface init success");
79 return WAPI_SUCCESS;
80 }
81
wapi_deinit_iface(struct wpa_supplicant * wpa)82 int wapi_deinit_iface(struct wpa_supplicant *wpa)
83 {
84 struct wapi_asue_struct *wapi = NULL;
85
86 if (wpa == NULL) {
87 wpa_error_log0(MSG_WARNING, "wpa is null");
88 return WAPI_FAILED;
89 }
90
91 if (wpa->wapi == NULL) {
92 wpa_error_log0(MSG_WARNING, "wapi is null");
93 return WAPI_FAILED;
94 }
95
96 wapi = wpa->wapi;
97
98 if (wapi->wapi_l2 != NULL) {
99 l2_packet_deinit(wapi->wapi_l2);
100 wapi->wapi_l2 = NULL;
101 }
102
103 wapi_iface_deinit(wapi);
104
105 os_free(wapi);
106 wpa->wapi = NULL;
107
108 return WAPI_SUCCESS;
109 }
110
wapi_parse_wapi_ie(const unsigned char * wapi_ie,unsigned int ie_len,struct wpa_ie_data * ie_data)111 int wapi_parse_wapi_ie(const unsigned char *wapi_ie, unsigned int ie_len,
112 struct wpa_ie_data *ie_data)
113 {
114 return wapi_parse_ie(wapi_ie, ie_len, ie_data);
115 }
116
wapi_config_associate_param(struct wpa_supplicant * wpa,struct wpa_bss * bss,struct wpa_ssid * ssid,struct wpa_driver_associate_params * params)117 static int wapi_config_associate_param(struct wpa_supplicant *wpa,
118 struct wpa_bss *bss, struct wpa_ssid *ssid,
119 struct wpa_driver_associate_params *params)
120 {
121 unsigned char *wapi_ie = NULL;
122 unsigned char *ie_ssid = NULL;
123 unsigned int cipher_pairwise;
124 unsigned int cipher_group;
125
126 cipher_pairwise = WPA_CIPHER_NONE;
127 cipher_group = WPA_CIPHER_NONE;
128
129 if (bss != NULL) {
130 ie_ssid = (unsigned char *)wpa_bss_get_ie(bss, 0);
131 if (ie_ssid == NULL) {
132 wpa_error_log0(MSG_WARNING, "get bss ie failed");
133 return WAPI_FAILED;
134 }
135 params->ssid = ie_ssid + 2; /* 2 bytes for EID and length */
136 params->ssid_len = ie_ssid[1];
137 params->bssid = bss->bssid;
138
139 wapi_ie = (unsigned char *)wpa_bss_get_ie(bss, WAPI_IE_ID);
140 if (wapi_ie != NULL) {
141 wpa->wapi->wapi_ie_len = (size_t)(wapi_ie[1] + 2); /* 2 bytes for EID and length */
142 /* 2 bytes for EID and length */
143 if (wapi_ie[1] &&
144 memcpy_s(wpa->wapi->wapi_ie, WAPI_IE_MAX_SIZE, wapi_ie, (size_t)(wapi_ie[1] + 2)) != EOK) {
145 wpa_error_log0(MSG_WARNING, "memcpy wapi ie failed");
146 return WAPI_FAILED;
147 }
148 wpa->wapi->wapi_ie[1] += 2; /* 2 bytes for EID and length */
149 wpa->wapi->wapi_ie_len += 2; /* 2 bytes for EID and length */
150 wpa->wapi->wapi_ie[wpa->wapi->wapi_ie_len - 2] = 0; /* 2 bytes for EID and length */
151 wpa->wapi->wapi_ie[wpa->wapi->wapi_ie_len - 1] = 0;
152 }
153
154 params->freq.freq = bss->freq;
155 } else {
156 wapi_ie = NULL;
157 params->ssid = ssid->ssid;
158 params->ssid_len = ssid->ssid_len;
159 }
160
161 params->mode = 0; /* Modes of operation: Let the driver decides */
162 params->wpa_ie = wpa->wapi->wapi_ie;
163 params->wpa_ie_len = wpa->wapi->wapi_ie_len;
164
165 params->pairwise_suite = cipher_pairwise;
166 params->group_suite = cipher_group;
167
168 if (!os_memcmp(wpa->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN)) {
169 if (wpa_drv_associate(wpa, params)) {
170 wpa_error_log0(MSG_WARNING, "wpa_drv_associate failed");
171 wpas_connection_failed(wpa, wpa->pending_bssid);
172 wpa_supplicant_set_state(wpa, WPA_DISCONNECTED);
173 if (memset_s(wpa->pending_bssid, ETH_ALEN, 0, ETH_ALEN) != EOK) {
174 wpa_error_log0(MSG_WARNING, "memset bssid failed");
175 return WAPI_FAILED;
176 }
177 wpa->current_bss = NULL;
178 wpa->current_ssid = NULL;
179 return WAPI_FAILED;
180 }
181
182 /* Timeout for IEEE 802.11 authentication and association */
183 wpa_supplicant_req_auth_timeout(wpa, WAI_AUTH_TIMEOUT, 0);
184 }
185
186 return WAPI_SUCCESS;
187 }
188
wapi_asue_event_assoc(struct wpa_supplicant * wpa,struct wpa_bss * bss,struct wpa_ssid * ssid,struct wpa_driver_associate_params * params)189 int wapi_asue_event_assoc(struct wpa_supplicant *wpa,
190 struct wpa_bss *bss, struct wpa_ssid *ssid,
191 struct wpa_driver_associate_params *params)
192 {
193 struct wapi_asue_struct *wapi = NULL;
194
195 if ((wpa == NULL) || (wpa->wapi == NULL) ||
196 (bss == NULL) || (ssid == NULL) || (params == NULL)) {
197 wpa_error_log0(MSG_WARNING, "wapi_asue_event_assoc input null pointer!");
198 return WAPI_FAILED;
199 }
200
201 wapi = wpa->wapi;
202
203 if (wapi_generate_addid(wapi, bss) != WAPI_SUCCESS) {
204 wpa_error_log0(MSG_WARNING, "generate addid failed");
205 return WAPI_FAILED;
206 }
207
208 if ((unsigned int)(wpa->key_mgmt) & WPA_KEY_MGMT_WAPI_PSK) {
209 wapi->auth_type = AUTH_TYPE_WAPI_PSK;
210 params->key_mgmt_suite = WPA_KEY_MGMT_WAPI_PSK;
211 if (WAPI_SUCCESS != wapi_psk_to_bk(wpa, ssid)) {
212 wpa_error_log0(MSG_WARNING, "fail to derivate psk");
213 return WAPI_FAILED;
214 }
215 } else if ((unsigned int)(wpa->key_mgmt) & WPA_KEY_MGMT_WAPI_CERT) {
216 wpa_error_log0(MSG_WARNING, "not support wapi-cert");
217 return WAPI_FAILED;
218 } else {
219 wpa->wapi->auth_type = AUTH_TYPE_NONE_WAPI;
220 }
221
222 wpa_error_log1(MSG_DEBUG, "auth_type %u", (unsigned int)wpa->wapi->auth_type);
223
224 if (wapi_init_ie(wpa) != WAPI_SUCCESS) {
225 wpa_error_log0(MSG_WARNING, "fail to init ie");
226 return WAPI_FAILED;
227 }
228
229 if (wapi_config_associate_param(wpa, bss, ssid, params) != WAPI_SUCCESS) {
230 wpa_error_log0(MSG_WARNING, "fail to configurate associating param");
231 return WAPI_FAILED;
232 }
233
234 return WAPI_SUCCESS;
235 }
236
wapi_asue_event_disassoc(struct wpa_supplicant * wpa,unsigned short us_reasonus_reason)237 int wapi_asue_event_disassoc(struct wpa_supplicant *wpa,
238 unsigned short us_reasonus_reason)
239 {
240 (void)us_reasonus_reason;
241 struct wapi_asue_struct *wapi = NULL;
242 unsigned char bssid[ETH_ALEN];
243
244 if ((wpa == NULL) || (wpa->wapi == NULL)) {
245 wpa_error_log0(MSG_WARNING, "wpa or wpa->wapi is null");
246 return WAPI_FAILED;
247 }
248
249 wapi = wpa->wapi;
250
251 (void)wpa_drv_get_bssid(wpa, bssid);
252
253 if (memcpy_s(wapi->own_mac, ETH_ALEN, wpa->own_addr, ETH_ALEN) != EOK) {
254 wpa_error_log0(MSG_WARNING, "memcpy own_mac failed");
255 return WAPI_FAILED;
256 }
257 if (memcpy_s(wapi->bssid, ETH_ALEN, bssid, ETH_ALEN) != EOK) {
258 wpa_error_log0(MSG_WARNING, "memcpy bssid failed");
259 return WAPI_FAILED;
260 }
261
262 (void)wapi_event_process(wapi, CONN_DISASSOC, NULL, 0);
263
264 return WAPI_SUCCESS;
265 }
266
wapi_asue_event(struct wpa_supplicant * wpa,enum wpa_event_type event,void * data)267 int wapi_asue_event(struct wpa_supplicant *wpa,
268 enum wpa_event_type event, void *data)
269 {
270 (void)data;
271 struct wapi_asue_struct *wapi = NULL;
272 unsigned char bssid[ETH_ALEN];
273
274 if ((wpa == NULL) || (wpa->wapi == NULL)) {
275 wpa_error_log0(MSG_WARNING, "wapi_asue_event input null pointer");
276 return WAPI_FAILED;
277 }
278
279 wapi = wpa->wapi;
280
281 wpa_error_log1(MSG_DEBUG, "event %u", (unsigned int)event);
282 switch (event) {
283 case EVENT_ASSOC:
284 (void)wpa_drv_get_bssid(wpa, bssid);
285 if (memcpy_s(wapi->own_mac, ETH_ALEN, wpa->own_addr, ETH_ALEN) != EOK) {
286 wpa_error_log0(MSG_WARNING, "memcpy own_mac failed");
287 return WAPI_FAILED;
288 }
289 if (memcpy_s(wapi->bssid, ETH_ALEN, bssid, ETH_ALEN) != EOK) {
290 wpa_error_log0(MSG_WARNING, "memcpy bssid failed");
291 return WAPI_FAILED;
292 }
293 if (wapi->wapi_ie_len) {
294 (void)wapi_event_process(wapi, CONN_ASSOC, wapi->wapi_ie, wapi->wapi_ie_len);
295 } else {
296 (void)wapi_event_process(wapi, CONN_ASSOC, NULL, 0);
297 }
298 break;
299 case EVENT_DISASSOC:
300 (void)wapi_event_process(wapi, CONN_DISASSOC, NULL, 0);
301 break;
302 default:
303 wpa_error_log0(MSG_DEBUG, "event is unknown");
304 break;
305 }
306
307 return WAPI_SUCCESS;
308 }
309
wpa_supplicant_wapi_ie_txt(char * pos,char * end,const unsigned char * ie,size_t ie_len)310 char *wpa_supplicant_wapi_ie_txt(char *pos, char *end, const unsigned char *ie, size_t ie_len)
311 {
312 int akm_suit_cnt = 0, i, ret;
313 unsigned char *ie_hdr = (unsigned char *)ie;
314 unsigned char *p_akm_auit_cnt = NULL;
315 unsigned char *p_akm = NULL;
316 char *old_pos = pos;
317
318 if (end <= pos) {
319 wpa_error_log0(MSG_ERROR, "end is smaller than pos");
320 return old_pos;
321 }
322
323 if (ie_len < WAPI_HEAD_LEN) {
324 /* ensure ie_len much more length */
325 wpa_error_log1(MSG_ERROR, "ie_len is too short,ie_len=%zu(<6)", ie_len);
326 return old_pos;
327 }
328
329 if (ie_hdr == NULL) {
330 wpa_error_log0(MSG_ERROR, "ie_hdr is NULL");
331 return old_pos;
332 }
333
334 p_akm_auit_cnt = ie_hdr + (WAPI_IE_ID_SIZE + WAPI_IE_LENGTH_SIZE + WAPI_IE_VERSION_SIZE);
335 akm_suit_cnt = (p_akm_auit_cnt[0] | ((p_akm_auit_cnt[1] << 8) & 0xff00)) & 0xffff;
336
337 wpa_error_log2(MSG_DEBUG, "wpa_supplicant_wapi_ie_txt,ie_len=%zu,akm_suit_cnt=%d", ie_len, akm_suit_cnt);
338
339 if (akm_suit_cnt > 2) {
340 wpa_error_log1(MSG_ERROR, "akm_suit_cnt(%d > 2) is error.", akm_suit_cnt);
341 return old_pos;
342 }
343
344 if (ie_len < (size_t)(WAPI_HEAD_LEN + akm_suit_cnt * WAPI_IE_AKM_SUIT_LEN)) {
345 wpa_error_log2(MSG_ERROR, "ie_len(%zu) is short,the right len should more than:%d",
346 ie_len, (WAPI_HEAD_LEN + akm_suit_cnt * WAPI_IE_AKM_SUIT_LEN));
347 return old_pos;
348 }
349
350 p_akm = (p_akm_auit_cnt + WAPI_IE_AKM_CNT_LEN);
351 for (i = 0; i < akm_suit_cnt; i++) {
352 if (WAPI_IE_AKM_SUIT_PSK == WPA_GET_BE32(p_akm)) {
353 ret = snprintf_s(pos, (size_t)(end - pos), (size_t)(end - pos), "[WAPI-PSK]");
354 if (os_snprintf_error((size_t)(end - pos), ret)) {
355 return pos;
356 }
357 pos += ret;
358 } else {
359 wpa_error_log0(MSG_ERROR, "unknow wpai akm_suit");
360 return old_pos;
361 }
362
363 p_akm += WAPI_IE_AKM_SUIT_LEN;
364 }
365 return pos;
366 }
367