• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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