• 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: wpi数据加解密.
15  */
16 
17 /*****************************************************************************
18   1 头文件包含
19 *****************************************************************************/
20 #include "hmac_wapi.h"
21 #include "oal_ext_if.h"
22 #include "oal_types.h"
23 #include "mac_frame.h"
24 #include "hmac_wapi_sms4.h"
25 #include "hmac_wapi_wpi.h"
26 #include "mac_data.h"
27 #include "hmac_feature_dft.h"
28 #include "hmac_tx_data.h"
29 #include "oam_struct.h"
30 #include "frw_util_notifier.h"
31 #include "hmac_feature_interface.h"
32 
33 #ifdef __cplusplus
34 #if __cplusplus
35 extern "C" {
36 #endif
37 #endif
38 
39 #undef THIS_FILE_ID
40 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_WAPI_C
41 
42 #undef THIS_MOD_ID
43 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
44 
45 /*****************************************************************************
46   2 全局变量定义
47 *****************************************************************************/
48 OAL_CONST osal_u8 g_auc_wapi_oui_etc[WAPI_IE_OUI_SIZE] = {0x00, 0x14, 0x72};
49 
50 OAL_STATIC hmac_wapi_stru *g_wapi_userinfo[WLAN_USER_MAX_USER_LIMIT];
51 
hmac_wapi_get_user_info(osal_u16 user_id)52 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OAL_STATIC hmac_wapi_stru *hmac_wapi_get_user_info(osal_u16 user_id)
53 {
54     if (user_id >= WLAN_USER_MAX_USER_LIMIT) {
55         return OAL_PTR_NULL;
56     }
57     return g_wapi_userinfo[user_id];
58 }
59 /*****************************************************************************
60   3 函数实现
61 *****************************************************************************/
62 
63 /*****************************************************************************
64  功能描述  : 判断是否为qos帧
65 *****************************************************************************/
hmac_wapi_is_qos_etc(const mac_ieee80211_frame_stru * pst_mac_hdr)66 OAL_STATIC oal_bool_enum_uint8  hmac_wapi_is_qos_etc(const mac_ieee80211_frame_stru *pst_mac_hdr)
67 {
68     if ((pst_mac_hdr->frame_control.type == WLAN_DATA_BASICTYPE) &&
69         ((WLAN_QOS_DATA & pst_mac_hdr->frame_control.sub_type) != 0)) {
70         return OAL_TRUE;
71     }
72 
73     return OAL_FALSE;
74 }
75 
76 /*****************************************************************************
77  功能描述  : 计算mic数据,作为计算mic之用
78 *****************************************************************************/
hmac_wapi_calc_mic_data_etc(mac_ieee80211_frame_stru * pst_mac_hdr,osal_u8 mac_hdr_len,osal_u8 keyidx,osal_u8 * payload,osal_u16 pdu_len,osal_u8 * mic,osal_u16 mic_len)79 OAL_STATIC osal_u32 hmac_wapi_calc_mic_data_etc(mac_ieee80211_frame_stru *pst_mac_hdr, osal_u8 mac_hdr_len,
80     osal_u8 keyidx, osal_u8 *payload, osal_u16 pdu_len, osal_u8 *mic, osal_u16 mic_len)
81 {
82     osal_u8       is_qos;
83     osal_u8      *mic_oringin;
84     osal_u32 frag_num_len = 2; /* 2:frag_num长度值 */
85 
86     unref_param(mac_hdr_len);
87 
88     memset_s(mic, mic_len, 0, mic_len);
89 
90     mic_oringin = mic;
91 
92     /* frame control */
93     if (memcpy_s(mic, mic_len, (osal_u8 *)&(pst_mac_hdr->frame_control),
94         OAL_SIZEOF(pst_mac_hdr->frame_control)) != EOK) {
95         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_calc_mic_data_etc::memcpy_s frame_control error}");
96     }
97     mic[0] &= ~(BIT4 | BIT5 | BIT6);                 /* sub type */
98     mic[1] &= ~(BIT3 | BIT4 | BIT5);                 /* retry, pwr Mgmt, more data */
99     mic[1] |= BIT6;
100 
101     mic += OAL_SIZEOF(pst_mac_hdr->frame_control);
102 
103     /* addr1 */
104     mac_get_address1((osal_u8 *)pst_mac_hdr, mic);
105     mic += OAL_MAC_ADDR_LEN;
106 
107     /* addr2 */
108     mac_get_address2((osal_u8 *)pst_mac_hdr, mic);
109     mic += OAL_MAC_ADDR_LEN;
110 
111     /* 序列控制 */
112     memset_s(mic, frag_num_len, 0, frag_num_len);
113     mic[0] = (osal_u8)(pst_mac_hdr->frag_num);
114     mic += frag_num_len; /* 2长度值 */
115 
116     /* addr3 */
117     mac_get_address3((osal_u8 *)pst_mac_hdr, mic);
118     mic += OAL_MAC_ADDR_LEN;
119 
120     /* 跳过addr4 */
121     mic += OAL_MAC_ADDR_LEN;
122 
123     /* qos ctrl */
124     is_qos = hmac_wapi_is_qos_etc(pst_mac_hdr);
125     if (is_qos == OAL_TRUE) {
126         mac_get_qos_ctrl((osal_u8 *)pst_mac_hdr, mic);
127         mic += MAC_QOS_CTL_LEN;
128     }
129 
130     /* keyidx + reserve总共2个字节 */
131     *mic = keyidx;
132     mic += 2; /* 2长度值 */
133 
134     /* 填充pdulen 协议写明大端字节序 */
135     *mic = (osal_u8)((pdu_len & 0xff00) >> 8); /* 8偏移值 */
136     *(mic + 1) = (osal_u8)(pdu_len & 0x00ff);
137     mic += 2; /* 2长度值 */
138 
139     mic_oringin +=
140         (hmac_wapi_is_qos_etc(pst_mac_hdr) == OAL_TRUE) ? SMS4_MIC_PART1_QOS_LEN : SMS4_MIC_PART1_NO_QOS_LEN;
141     if (memcpy_s(mic_oringin, pdu_len, payload, pdu_len) != EOK) {
142         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_calc_mic_data_etc::memcpy_s payload error}");
143     }
144 
145     return OAL_SUCC;
146 }
147 
148 /*****************************************************************************
149  功能描述  : 申请空间,用于存放mic
150 *****************************************************************************/
hmac_wapi_mic_alloc_etc(osal_u8 is_qos,osal_u16 pdu_len,osal_u16 * pus_mic_len)151 OAL_STATIC osal_u8 *hmac_wapi_mic_alloc_etc(osal_u8 is_qos, osal_u16 pdu_len, osal_u16 *pus_mic_len)
152 {
153     osal_u16      mic_part1_len;
154     osal_u16      mic_part2_len;
155     osal_u16      mic_len;
156 
157     mic_part1_len = (is_qos == OAL_TRUE) ? SMS4_MIC_PART1_QOS_LEN : SMS4_MIC_PART1_NO_QOS_LEN;
158 
159     /* 按照协议,补齐不足位,16字节对齐 */
160     mic_part2_len = (osal_u16)((pdu_len + SMS4_PADDING_LEN - 1) & (~(SMS4_PADDING_LEN - 1)));
161 
162     mic_len = mic_part1_len + mic_part2_len;
163 
164     *pus_mic_len = mic_len;
165 
166     return oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, mic_len, OAL_TRUE);
167 }
168 
169 /*****************************************************************************
170  功能描述  : 释放申请的mic空间
171 *****************************************************************************/
hmac_wapi_mic_free_etc(osal_u8 * mic)172 OAL_STATIC osal_u32 hmac_wapi_mic_free_etc(osal_u8 *mic)
173 {
174     if (mic != OAL_PTR_NULL) {
175         oal_mem_free(mic, OAL_TRUE);
176         return OAL_SUCC;
177     }
178 
179     return OAL_FAIL;
180 }
181 
182 /*****************************************************************************
183  功能描述  : 判断keyidx是否合法
184 *****************************************************************************/
hmac_wapi_is_keyidx_valid_etc(hmac_wapi_stru * wapi,osal_u8 keyidx_rx)185 OAL_STATIC osal_u8 hmac_wapi_is_keyidx_valid_etc(hmac_wapi_stru *wapi, osal_u8 keyidx_rx)
186 {
187     if ((wapi->keyidx != keyidx_rx) &&
188         (wapi->keyupdate_flg != OAL_TRUE)) {
189         oam_warning_log3(0, OAM_SF_ANY, "{hmac_wapi_is_keyidx_valid_etc::keyidx==%u, keyidx_rx==%u, update==%u.}",
190                          wapi->keyidx, keyidx_rx, wapi->keyupdate_flg);
191         return OAL_FALSE;
192     }
193 
194     wapi->keyupdate_flg = OAL_FALSE; /* 更新完成取消标志 */
195 
196     /* key没有启用 */
197     if (wapi->wapi_key[keyidx_rx].key_en != OAL_TRUE) {
198         oam_warning_log1(0, OAM_SF_ANY, "{hmac_wapi_is_keyidx_valid_etc::keyen==%u.}",
199                          wapi->wapi_key[keyidx_rx].key_en);
200         return OAL_FALSE;
201     }
202 
203     return OAL_TRUE;
204 }
205 
206 /*****************************************************************************
207  功能描述  : 单播帧判断数据奇偶正确性
208 *****************************************************************************/
hmac_wapi_is_pn_odd_ucast_etc(const osal_u8 * pn)209 OAL_STATIC oal_bool_enum_uint8 hmac_wapi_is_pn_odd_ucast_etc(const osal_u8 *pn)
210 {
211     return (oal_bool_enum_uint8)(((*pn & BIT0) == 0) ? OAL_FALSE : OAL_TRUE);
212 }
213 
214 /*****************************************************************************
215  功能描述  : 组播帧判断数据奇偶性
216 *****************************************************************************/
hmac_wapi_is_pn_odd_bcast_etc(const osal_u8 * pn)217 OAL_STATIC osal_u8 hmac_wapi_is_pn_odd_bcast_etc(const osal_u8 *pn)
218 {
219     unref_param(pn);
220     return OAL_TRUE;
221 }
222 
223 /*****************************************************************************
224  功能描述  : 每收到一个帧,更新pn
225 *****************************************************************************/
hmac_wapi_pn_update_etc(osal_u8 * pn,osal_u8 inc)226 OAL_STATIC osal_u8 hmac_wapi_pn_update_etc(osal_u8 *pn, osal_u8  inc)
227 {
228     osal_u32          loop;
229     osal_u32          loop_num;
230     osal_u32          overlow;     /* 进位 */
231     osal_u32         *pul_pn;
232 
233     pul_pn = (osal_u32 *)pn;
234     loop_num = (osal_u32)(WAPI_PN_LEN / OAL_SIZEOF(osal_u32));
235     overlow = inc;
236 
237     for (loop = 0; loop < loop_num; loop++) {
238         if (*pul_pn > (*pul_pn + overlow)) {
239             *pul_pn    += overlow;
240             overlow = 1;     /* 溢出高位加1 */
241         } else {
242             *pul_pn    += overlow;
243             break;
244         }
245         pul_pn++;
246     }
247 
248     return OAL_TRUE;
249 }
250 
251 /*****************************************************************************
252  功能描述  : 处理已经分片或者不需分片的netbuff链
253              1)如果已经分片,则处理这个链,将链上所有netbuff上的数据进行加密处理
254              2)如果没有分片,则处理单个netbuff,将这个netbuff上的数据进行加密处理
255 *****************************************************************************/
hmac_wapi_netbuff_tx_handle_etc(hmac_wapi_stru * wapi,oal_netbuf_stru * buf)256 OAL_STATIC oal_netbuf_stru  *hmac_wapi_netbuff_tx_handle_etc(hmac_wapi_stru *wapi, oal_netbuf_stru  *buf)
257 {
258     osal_u32           ul_ret;
259     oal_netbuf_stru     *netbuf_tmp;    /* 指向需要释放的netbuff */
260     oal_netbuf_stru     *netbuf_prev;   /* 指向已经加密的netbuff */
261     oal_netbuf_stru     *buf_first;     /* 指向还未加密的netbuff */
262 
263     /* buf的初始位置在snap头的llc处 */
264     if (hmac_get_data_type_from_80211_etc(buf, 0) == MAC_DATA_WAPI) {
265         oam_warning_log0(0, OAM_SF_WAPI, "{hmac_wapi_netbuff_tx_handle_etc::wapi, dont encrypt!.}");
266         return buf;
267     }
268 
269     ul_ret = wapi->wapi_encrypt(wapi, buf);
270     if (ul_ret != OAL_SUCC) {
271         hmac_free_netbuf_list_etc(buf);
272         return OAL_PTR_NULL;
273     }
274 
275     netbuf_tmp = buf;
276 
277     /* 使netbuff指针指向下一个需要加密的分片帧 */
278     netbuf_prev = OAL_NETBUF_NEXT(buf);
279     if (netbuf_prev == OAL_PTR_NULL) {
280         return OAL_PTR_NULL;
281     }
282     buf_first = netbuf_prev;
283     buf = OAL_NETBUF_NEXT(netbuf_prev);
284 
285     oal_netbuf_free(netbuf_tmp);
286 
287     while (buf != OAL_PTR_NULL) {
288         ul_ret = wapi->wapi_encrypt(wapi, buf);
289         if (ul_ret != OAL_SUCC) {
290             hmac_free_netbuf_list_etc(buf_first);
291             return OAL_PTR_NULL;
292         }
293         OAL_NETBUF_NEXT(netbuf_prev) = OAL_NETBUF_NEXT(buf);
294         netbuf_tmp = buf;
295         netbuf_prev = OAL_NETBUF_NEXT(buf);
296         if (netbuf_prev == OAL_PTR_NULL) {
297             return OAL_PTR_NULL;
298         }
299         buf = OAL_NETBUF_NEXT(netbuf_prev);
300 
301         oal_netbuf_free(netbuf_tmp);
302     }
303     return buf_first;
304 }
305 
306 /*****************************************************************************
307  功能描述  : 接收处理比发送要简单,因为每次只会有一个netbuff需要处理
308              假设加密的netbuff为1,解密后的为0,那么输入为1,解密完成后变为
309              1->0 本函数将1删掉,然后将已经解密的0往上送
310 *****************************************************************************/
hmac_wapi_netbuff_rx_handle_etc(hmac_wapi_stru * wapi,oal_netbuf_stru * buf)311 OAL_STATIC oal_netbuf_stru *hmac_wapi_netbuff_rx_handle_etc(hmac_wapi_stru *wapi, oal_netbuf_stru *buf)
312 {
313     osal_u32                    ul_ret;
314     oal_netbuf_stru              *netbuf_tmp;    /* 指向需要释放的netbuff */
315 
316     /* 非加密帧,不进行解密 */
317     if (((oal_netbuf_data(buf))[1] & 0x40) == 0) {
318         return buf;
319     }
320 
321     ul_ret = wapi->wapi_decrypt(wapi, buf);
322     if (ul_ret != OAL_SUCC) {
323         return OAL_PTR_NULL;
324     }
325 
326     netbuf_tmp = buf;
327     buf = OAL_NETBUF_NEXT(buf);
328     oal_netbuf_free(netbuf_tmp);
329 
330     return buf;
331 }
332 
333 /*****************************************************************************
334  功能描述  : 增加/更新 key
335 *****************************************************************************/
hmac_wapi_add_key_etc(hmac_wapi_stru * wapi,osal_u8 key_index,osal_u8 * key)336 OAL_STATIC osal_u32 hmac_wapi_add_key_etc(hmac_wapi_stru *wapi, osal_u8 key_index, osal_u8 *key)
337 {
338     hmac_wapi_key_stru *pst_key;
339     OAL_CONST osal_u8 wapi_pn_init_etc[WAPI_PN_LEN] = {
340         0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c
341     };
342 
343     wapi->port_valid = OAL_TRUE;
344     wapi->keyidx = key_index;
345     wapi->keyupdate_flg = OAL_TRUE;
346     pst_key = &(wapi->wapi_key[key_index]);
347 
348     if (memcpy_s(pst_key->wpi_ek, sizeof(pst_key->wpi_ek), key, WAPI_KEY_LEN) != EOK) {
349         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_add_key_etc::memcpy_s wpi_ek error}");
350     }
351     if (memcpy_s(pst_key->wpi_ck, sizeof(pst_key->wpi_ck), key + WAPI_KEY_LEN, WAPI_KEY_LEN) != EOK) {
352         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_add_key_etc::memcpy_s wpi_ck error}");
353     }
354     pst_key->key_en = OAL_TRUE;
355 
356     /* 重置PN */
357     if (memcpy_s(pst_key->pn_rx, sizeof(pst_key->pn_rx), wapi_pn_init_etc, WAPI_PN_LEN) != EOK) {
358         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_add_key_etc::memcpy_s pn_rx error}");
359     }
360     if (memcpy_s(pst_key->pn_tx, sizeof(pst_key->pn_tx), wapi_pn_init_etc, WAPI_PN_LEN) != EOK) {
361         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_add_key_etc::memcpy_s pn_tx error}");
362     }
363 
364     return OAL_SUCC;
365 }
366 
367 /*****************************************************************************
368  功能描述  : 检验wpi头的合法性
369 *****************************************************************************/
hmac_wapi_is_wpihdr_valid_etc(hmac_wapi_stru * wapi,osal_u8 * wapi_hdr)370 OAL_STATIC osal_u8 hmac_wapi_is_wpihdr_valid_etc(hmac_wapi_stru *wapi, osal_u8  *wapi_hdr)
371 {
372     osal_u8 keyidx_rx;
373     osal_u8 *pn_rx;
374 
375     keyidx_rx = *wapi_hdr;
376 
377     if (hmac_wapi_is_keyidx_valid_etc(wapi, keyidx_rx) != OAL_TRUE) {
378         return OAL_FALSE;
379     }
380 
381     pn_rx = wapi_hdr + SMS4_KEY_IDX + SMS4_WAPI_HDR_RESERVE;
382     if (wapi->wapi_is_pn_odd(pn_rx) != OAL_TRUE) {
383         oam_warning_log0(0, OAM_SF_ANY, "{hmac_wapi_is_wpihdr_valid_etc::wapi_is_pn_odd==false.}");
384         return OAL_FALSE;
385     }
386 
387     return OAL_TRUE;
388 }
389 
390 /*****************************************************************************
391  功能描述  : 对数据进行解密
392  其    他  : 此函数如果返回错误,需要将netbuff释放掉,不需要再送到后面进行处理
393 *****************************************************************************/
hmac_wapi_decrypt_etc(hmac_wapi_stru * wapi,oal_netbuf_stru * pst_netbuf)394 OAL_STATIC osal_u32 hmac_wapi_decrypt_etc(hmac_wapi_stru *wapi, oal_netbuf_stru *pst_netbuf)
395 {
396     oal_netbuf_stru             *netbuff_des    = NULL;
397     osal_u8                   *key_ek         = NULL;
398     osal_u8                   *key_ck         = NULL;
399     osal_u8                    key_index;
400     osal_u16                   pdu_len;
401     osal_u8                    calc_mic[SMS4_MIC_LEN];
402     osal_u32                   wapi_result;
403 
404     mac_ieee80211_frame_stru    *pst_mac_hdr;
405     osal_u8                   *netbuff;
406     osal_u16                   netbuff_len;
407     osal_u8                   *wapi_hdr;
408     osal_u8                    mac_hdr_len;
409     osal_u8                   *pn;
410     osal_u8                   *pdu;
411     osal_u8                   *mic_data;        /* 按照协议,构造mic所需要的数据,见 wapi实施指南 图51 */
412     osal_u8                   *mic;
413     osal_u16                   mic_len;
414     mac_rx_ctl_stru             *rx_ctl;
415     mac_rx_ctl_stru             *rx_ctl_in;
416 
417     /************ 1. 解密前的数据准备,获取各头指针和内容长度 ************/
418     netbuff = OAL_NETBUF_DATA(pst_netbuf);        // for ut,del temprarily
419     netbuff_len = (osal_u16)OAL_NETBUF_LEN(pst_netbuf);
420 
421     /* 获取mac头 */
422     pst_mac_hdr = (mac_ieee80211_frame_stru *)netbuff;
423 
424     /* wapi的数据帧一般为QOS帧  */
425     rx_ctl_in = (mac_rx_ctl_stru *)OAL_NETBUF_CB(pst_netbuf);
426     mac_hdr_len = rx_ctl_in->mac_header_len;
427     wapi_hdr = (osal_u8 *)pst_mac_hdr + mac_hdr_len;
428     pn = wapi_hdr + SMS4_KEY_IDX + SMS4_WAPI_HDR_RESERVE;
429     pdu = pn + SMS4_PN_LEN;
430 
431     oam_warning_log1(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::mac_hdr_len %u!.}", mac_hdr_len);
432 
433     if (netbuff_len < (osal_u16)(mac_hdr_len + HMAC_WAPI_HDR_LEN + SMS4_MIC_LEN)) {
434         oam_error_log2(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::netbuff_len %u, machdr len %u err!.}",
435                        netbuff_len, mac_hdr_len);
436         oal_netbuf_free(pst_netbuf);
437         return OAL_FAIL;
438     }
439     pdu_len = netbuff_len - mac_hdr_len - HMAC_WAPI_HDR_LEN - SMS4_MIC_LEN;
440 
441     key_index = *wapi_hdr;
442 
443     if (key_index >= HMAC_WAPI_MAX_KEYID) {
444         oam_error_log1(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::key_index %u err!.}", key_index);
445         oal_netbuf_free(pst_netbuf);
446         return OAL_FAIL;
447     }
448 
449     if (hmac_wapi_is_wpihdr_valid_etc(wapi, wapi_hdr) != OAL_TRUE) {
450         oam_warning_log0(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::hmac_wapi_is_wpihdr_valid_etc err!.}");
451         oal_netbuf_free(pst_netbuf);
452         return OAL_FAIL;
453     }
454 
455     /************ 2. 准备新的netbuff,用来存放解密后的数据, 填写cb字段 ************/
456 #ifdef _PRE_LWIP_ZERO_COPY
457     netbuff_des = oal_pbuf_netbuf_alloc(WLAN_MEM_NETBUF_SIZE2);
458 #else
459     netbuff_des = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
460 #endif
461     if (netbuff_des == NULL) {
462         oal_netbuf_free(pst_netbuf);
463         return OAL_ERR_CODE_ALLOC_MEM_FAIL;
464     }
465 
466 #ifdef _PRE_LWIP_ZERO_COPY
467     skb_reserve(netbuff_des, PBUF_ZERO_COPY_RESERVE);
468 #endif
469 
470     /* 先拷贝mac头 */
471     oal_netbuf_init(netbuff_des, mac_hdr_len);
472 #if defined(_PRE_OS_VERSION_LINUX) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
473     oal_netbuf_copydata(pst_netbuf, 0, oal_netbuf_data(netbuff_des), mac_hdr_len, mac_hdr_len);
474 #elif defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
475     (osal_void)memcpy_s(oal_netbuf_data(netbuff_des), mac_hdr_len,
476         OAL_NETBUF_DATA(pst_netbuf), mac_hdr_len);
477 #endif
478 
479     /* 拷贝cb */
480     rx_ctl = (mac_rx_ctl_stru *)OAL_NETBUF_CB(netbuff_des);
481 #if defined(_PRE_OS_VERSION_LINUX) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
482     if (memcpy_s(rx_ctl, MAC_TX_CTL_SIZE, OAL_NETBUF_CB(pst_netbuf), MAC_TX_CTL_SIZE) != EOK) {
483         oam_error_log0(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::memcpy_s error}");
484     }
485 #elif defined(_PRE_OS_VERSION_LITEOS) && defined(_PRE_OS_VERSION) && (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
486     (osal_void)memcpy_s(rx_ctl, MAC_TX_CTL_SIZE, OAL_NETBUF_CB(pst_netbuf), MAC_TX_CTL_SIZE);
487 #endif
488 
489     /************ 3. 解密前的密钥准备和PN准备 ************/
490     key_ek = wapi->wapi_key[key_index].wpi_ek;
491     hmac_wpi_swap_pn_etc(pn, SMS4_PN_LEN);
492 
493     /******************** 4. 解密**************************/
494     wapi_result = hmac_wpi_decrypt_etc(pn,
495         pdu,
496         (pdu_len + SMS4_MIC_LEN),            /* 需要解密的数据长度 */
497         key_ek,
498         (oal_netbuf_data(netbuff_des) + mac_hdr_len));
499     if (wapi_result != OAL_SUCC) {
500         oal_netbuf_free(netbuff_des);
501         /* 返回之前注意入参netbuff是否在外面被释放 */
502         oal_netbuf_free(pst_netbuf);
503         return OAL_ERR_CODE_WAPI_DECRYPT_FAIL;
504     }
505 
506     /* mic作为校验数,不需要put */
507     oal_netbuf_put(netbuff_des, pdu_len);
508 
509     /************ 5. 计算mic,并进行校验 ************/
510     mic_data = hmac_wapi_mic_alloc_etc(hmac_wapi_is_qos_etc(pst_mac_hdr), pdu_len, &mic_len);
511     if (mic_data == OAL_PTR_NULL) {
512         oal_netbuf_free(netbuff_des);
513         /* 注意netbuff后续是否有释放处理 */
514         oal_netbuf_free(pst_netbuf);
515         return OAL_ERR_CODE_ALLOC_MEM_FAIL;
516     }
517 
518     /* 计算mic预备数据 */
519     hmac_wapi_calc_mic_data_etc(pst_mac_hdr, mac_hdr_len, key_index,
520         oal_netbuf_data(netbuff_des) + mac_hdr_len, pdu_len, mic_data, mic_len);
521     key_ck = wapi->wapi_key[key_index].wpi_ck;
522     wapi_result = hmac_wpi_pmac_etc(pn,
523         mic_data,
524         (mic_len >> 4), /* 4偏移值 */
525         key_ck,
526         (osal_u8 *)calc_mic);
527 
528     /* 计算完mic后,释放mic data */
529     hmac_wapi_mic_free_etc(mic_data);
530     if (wapi_result != OAL_SUCC) {
531         oal_netbuf_free(netbuff_des);
532         oal_netbuf_free(pst_netbuf);
533         return OAL_ERR_CODE_WAPI_MIC_CALC_FAIL;
534     }
535 
536     mic = oal_netbuf_data(netbuff_des) + mac_hdr_len + pdu_len;
537     if (osal_memcmp(mic, calc_mic, SMS4_MIC_LEN) != 0) {            /* 比较MIC */
538         oam_warning_log0(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::mic check fail!.}");
539         oal_netbuf_free(netbuff_des);
540         oal_netbuf_free(pst_netbuf);
541         return OAL_ERR_CODE_WAPI_MIC_CMP_FAIL;
542     }
543 
544     /* 返回前清protected */
545     (oal_netbuf_data(netbuff_des))[1] &= ~0x40;
546 
547     /* 填写cb */
548     rx_ctl->mac_header_len  = mac_hdr_len;
549     rx_ctl->frame_len = (osal_u16)OAL_NETBUF_LEN(netbuff_des);
550 
551     OAL_NETBUF_NEXT(netbuff_des) = OAL_NETBUF_NEXT(pst_netbuf);
552     OAL_NETBUF_NEXT(pst_netbuf) = netbuff_des;
553 
554     hmac_wapi_pn_update_etc(wapi->wapi_key[wapi->keyidx].pn_rx, wapi->pn_inc);
555 
556     oam_warning_log0(0, OAM_SF_ANY, "{hmac_wpi_decrypt_etc::OK!.}");
557     return OAL_SUCC;
558 }
559 
560 /*****************************************************************************
561  功能描述  : 对数据进行加密,处理完成之后,无论是否分片,
562             第一个netbuff为处理前,没有加密的netbuff,
563             后面挂的netbuff为加密过的netbuff,请注意!
564 *****************************************************************************/
hmac_wapi_encrypt_etc(hmac_wapi_stru * wapi,oal_netbuf_stru * netbuf)565 OAL_STATIC osal_u32 hmac_wapi_encrypt_etc(hmac_wapi_stru *wapi, oal_netbuf_stru  *netbuf)
566 {
567     mac_ieee80211_frame_stru        *mac_hdr;
568     osal_u8                        mac_hdr_len;
569     osal_u8                       *mic_data;
570     osal_u16                       pdu_len;
571     osal_u16                       mic_len;
572     osal_u8                        key_index;
573     osal_u8                       *key_ck;
574     osal_u8                       *key_ek;
575     osal_u8                        calc_mic[SMS4_MIC_LEN];
576     osal_u8                        pn_swap[SMS4_PN_LEN]; /* 保存变换后的pn,用来计算mic和加密 */
577     oal_netbuf_stru                 *netbuff_des;
578     osal_u8                       *wapi_hdr;
579     osal_u8                       *datain;
580     osal_u32                       result;
581     osal_u8                       *payload;
582     mac_tx_ctl_stru                 *tx_ctl;
583 
584     /************ 1. 加密前的数据准备,获取各头指针和内容长度 ************/
585     /* 获取mac头 */
586     tx_ctl = (mac_tx_ctl_stru *)OAL_NETBUF_CB(netbuf);
587     mac_hdr = mac_get_cb_frame_header_addr(tx_ctl);
588     mac_hdr_len = mac_get_cb_frame_header_length(tx_ctl);
589 
590     /* 设置加密位 注意,mac头涉及加密,所以需要在最开始设置 */
591     mac_set_protectedframe((osal_u8 *)mac_hdr);
592 
593     oam_warning_log2(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::mac_hdr_len %u! more==%u.}", mac_hdr_len,
594         mac_hdr->frame_control.more_frag);
595     pdu_len = mac_get_cb_mpdu_len(tx_ctl);
596 
597     /* payload的起始位置在snap头的llc处 */
598     payload = OAL_NETBUF_DATA(netbuf);
599 
600     /************ 2. 计算mic,wapi的数据帧一般为QOS帧  ************/
601     mic_data = hmac_wapi_mic_alloc_etc(hmac_wapi_is_qos_etc(mac_hdr), pdu_len, &mic_len);
602     if (mic_data == OAL_PTR_NULL) {
603         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::hmac_wapi_mic_alloc_etc err!");
604         return OAL_ERR_CODE_ALLOC_MEM_FAIL;
605     }
606 
607     /* 计算mic预备数据 */
608     key_index = wapi->keyidx;
609     hmac_wapi_calc_mic_data_etc(mac_hdr, mac_hdr_len, key_index, payload, pdu_len, mic_data, mic_len);
610     key_ck = wapi->wapi_key[key_index].wpi_ck;
611     if (memcpy_s(pn_swap, sizeof(pn_swap), wapi->wapi_key[key_index].pn_tx, SMS4_PN_LEN) != EOK) {
612         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s pn_tx error}");
613         return OAL_FAIL;
614     }
615     hmac_wpi_swap_pn_etc(pn_swap, SMS4_PN_LEN);
616     /* 计算mic */
617     result = hmac_wpi_pmac_etc((osal_u8 *)pn_swap, mic_data, (mic_len >> 4), key_ck, (osal_u8 *)calc_mic); /* 4偏移值 */
618 
619     hmac_wapi_mic_free_etc(mic_data);
620     if (result == OAL_FAIL) {
621         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::hmac_wpi_pmac_etc mic calc err!");
622         return OAL_ERR_CODE_WAPI_MIC_CALC_FAIL;
623     }
624 
625     /************ 3. 准备新的netbuff,用来存放加密后的数据, 填写cb,并准备加密前的数据 ************/
626     netbuff_des = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, WLAN_MEM_NETBUF_SIZE2, OAL_NETBUF_PRIORITY_MID);
627     if (netbuff_des == OAL_PTR_NULL) {
628         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::netbuff_des alloc err!");
629         return OAL_ERR_CODE_ALLOC_MEM_FAIL;
630     }
631 
632     /* 填写cb */
633     if (memcpy_s(OAL_NETBUF_CB(netbuff_des), MAC_TX_CTL_SIZE, OAL_NETBUF_CB(netbuf), MAC_TX_CTL_SIZE) != EOK) {
634         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s cb error}");
635         return OAL_FAIL;
636     }
637 
638     /* 先拷贝mac头,为了后续hcc处理,此处填写最大的空间 */
639     oal_netbuf_init(netbuff_des, MAC_80211_QOS_HTC_4ADDR_FRAME_LEN);
640     /* 跟其他host报文保持统一,将预留空间放在mac header之前,以qos data为例 |10字节空闲|26字节mac header|XX字节payload| */
641     if (memcpy_s(OAL_NETBUF_DATA(netbuff_des) + MAC_80211_QOS_HTC_4ADDR_FRAME_LEN - mac_hdr_len,
642         mac_hdr_len, mac_hdr, mac_hdr_len) != EOK) {
643         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s mac_hdr error}");
644         return OAL_FAIL;
645     }
646 
647     datain = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, pdu_len + SMS4_MIC_LEN, OAL_TRUE);
648     if (datain == OAL_PTR_NULL) {
649         oal_netbuf_free(netbuff_des);
650         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::datain alloc err!");
651         return OAL_ERR_CODE_ALLOC_MEM_FAIL;
652     }
653     if (memcpy_s(datain, pdu_len, payload, pdu_len) != EOK) {
654         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s payload error}");
655         return OAL_FAIL;
656     }
657     /* 拷贝mic */
658     if (memcpy_s(datain + pdu_len, SMS4_MIC_LEN, calc_mic, SMS4_MIC_LEN) != EOK) {
659         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s calc_mic error}");
660         return OAL_FAIL;
661     }
662 
663     key_ek = wapi->wapi_key[key_index].wpi_ek;
664     /************************ 4. 加密 ************************/
665     result = hmac_wpi_encrypt_etc(pn_swap, datain, pdu_len + SMS4_MIC_LEN, key_ek,
666         OAL_NETBUF_DATA(netbuff_des) + HMAC_WAPI_HDR_LEN + MAC_80211_QOS_HTC_4ADDR_FRAME_LEN);
667 
668     oal_mem_free(datain, OAL_TRUE);
669     if (result != OAL_SUCC) {
670         oal_netbuf_free(netbuff_des);
671         oam_error_log1(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::hmac_wpi_encrypt_etc err==%u!", result);
672         return OAL_ERR_CODE_WAPI_ENRYPT_FAIL;
673     }
674     /* 此处put完之后,netbuff的len为mac头+pdulen+sms4+wapi的长度 */
675     oal_netbuf_put(netbuff_des, pdu_len + SMS4_MIC_LEN + HMAC_WAPI_HDR_LEN);
676 
677     /***************** 5. 填写wapi头 *****************/
678     wapi_hdr = OAL_NETBUF_DATA(netbuff_des) + MAC_80211_QOS_HTC_4ADDR_FRAME_LEN;
679 
680     /* 填写WPI头 -- keyIndex */
681     *(wapi_hdr)  = key_index;
682     /* 保留位清零 */
683     *(wapi_hdr + SMS4_KEY_IDX)  = 0;
684     /* 填写PN */
685     if (memcpy_s((wapi_hdr + SMS4_KEY_IDX + SMS4_WAPI_HDR_RESERVE), SMS4_PN_LEN, wapi->wapi_key[key_index].pn_tx,
686         SMS4_PN_LEN) != EOK) {
687         oam_error_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::memcpy_s wapi_key pn_tx error}");
688         return OAL_FAIL;
689     }
690 
691     /* 再次填写cb */
692     tx_ctl = (mac_tx_ctl_stru *)OAL_NETBUF_CB(netbuff_des);
693     mac_get_cb_frame_header_addr(tx_ctl) = (mac_ieee80211_frame_stru *)((osal_u8 *)OAL_NETBUF_DATA(netbuff_des) +
694         MAC_80211_QOS_HTC_4ADDR_FRAME_LEN - mac_hdr_len);
695     /* netbuf 的data指针指向payload */
696     oal_netbuf_pull(netbuff_des, MAC_80211_QOS_HTC_4ADDR_FRAME_LEN);
697 
698     /* 不包括mac hdr */
699     mac_get_cb_mpdu_len(tx_ctl) = (osal_u16)(HMAC_WAPI_HDR_LEN + pdu_len + SMS4_MIC_LEN);
700     OAL_NETBUF_NEXT(netbuff_des) = OAL_NETBUF_NEXT(netbuf);
701     OAL_NETBUF_NEXT(netbuf) = netbuff_des;
702 
703     /* 更新pn */
704     hmac_wapi_pn_update_etc(wapi->wapi_key[wapi->keyidx].pn_tx, wapi->pn_inc);
705     oam_warning_log0(0, OAM_SF_ANY, "{hmac_wapi_encrypt_etc::hmac_wpi_encrypt_etc OK!");
706 
707     return OAL_SUCC;
708 }
709 
710 /*****************************************************************************
711  功能描述  : 将port重置
712 *****************************************************************************/
hmac_wapi_reset_port_etc(hmac_wapi_stru * wapi)713 OAL_STATIC osal_u32 hmac_wapi_reset_port_etc(hmac_wapi_stru *wapi)
714 {
715     wapi->port_valid = OAL_FALSE;
716     return OAL_SUCC;
717 }
718 
719 /*****************************************************************************
720  功能描述  : 去初始化wapi对象
721 *****************************************************************************/
hmac_wapi_deinit_etc(osal_u16 user_idx)722 OAL_STATIC osal_void hmac_wapi_deinit_etc(osal_u16 user_idx)
723 {
724     hmac_wapi_stru *wapi_user_info = hmac_wapi_get_user_info(user_idx);
725     if (wapi_user_info != OSAL_NULL) {
726         oal_mem_free(wapi_user_info, OAL_TRUE);
727         g_wapi_userinfo[user_idx] = OSAL_NULL;
728     }
729     return;
730 }
731 
hmac_wapi_del_user_exit(osal_void * notify_data)732 OAL_STATIC osal_bool hmac_wapi_del_user_exit(osal_void *notify_data)
733 {
734     hmac_vap_stru *hmac_vap = OSAL_NULL;
735     hmac_wapi_stru *wapi_multi_user_info = OSAL_NULL;
736     hmac_device_stru *hmac_device = OSAL_NULL;
737     hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
738 
739     hmac_vap = (hmac_vap_stru *)mac_res_get_hmac_vap(hmac_user->vap_id);
740     if (hmac_vap == OSAL_NULL) {
741         oam_warning_log1(0, 0, "{hmac_wapi_del_user_exit:vap[%d] is null.}", hmac_user->vap_id);
742         return OSAL_FALSE;
743     }
744 
745     hmac_wapi_deinit_etc(hmac_user->assoc_id);
746     /* STA模式下,清组播wapi加密端口 */
747     wapi_multi_user_info = hmac_wapi_get_user_info(hmac_vap->multi_user_idx);
748     if (wapi_multi_user_info == OSAL_NULL) {
749         oam_error_log2(0, OAM_SF_ANY, "vap_id[%d] {hmac_wapi_del_user_exit::hmac_wapi_get_user_info fail user_idx[%u]}",
750                        hmac_vap->vap_id, hmac_vap->multi_user_idx);
751         return OSAL_FALSE;
752     }
753     hmac_wapi_reset_port_etc(wapi_multi_user_info);
754     hmac_device = hmac_res_get_mac_dev_etc(hmac_user->device_id);
755     hmac_device->wapi = OAL_FALSE;
756     return OSAL_TRUE;
757 }
758 
759 /*****************************************************************************
760  功能描述  : 初始化wapi对象
761 *****************************************************************************/
hmac_wapi_init_etc(osal_u16 user_idx,osal_u8 pairwise)762 OAL_STATIC osal_u32 hmac_wapi_init_etc(osal_u16 user_idx, osal_u8 pairwise)
763 {
764     osal_u32 loop;
765     hmac_wapi_stru *wapi_user_info = hmac_wapi_get_user_info(user_idx);
766     if (wapi_user_info == OSAL_NULL) {
767         g_wapi_userinfo[user_idx] = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_wapi_stru), OAL_TRUE);
768         if (g_wapi_userinfo[user_idx] == OSAL_NULL) {
769             oam_error_log1(0, OAM_SF_ANY, "user_idx[%d] hmac_wapi_stru malloc null!", user_idx);
770             return OAL_FAIL;
771         }
772         wapi_user_info = g_wapi_userinfo[user_idx];
773     }
774     memset_s(wapi_user_info, OAL_SIZEOF(hmac_wapi_stru), 0, OAL_SIZEOF(hmac_wapi_stru));
775     if (pairwise == OAL_TRUE) {
776         wapi_user_info->pn_inc = WAPI_UCAST_INC;
777         wapi_user_info->wapi_is_pn_odd = hmac_wapi_is_pn_odd_ucast_etc;
778     } else {
779         wapi_user_info->pn_inc = WAPI_BCAST_INC;
780         wapi_user_info->wapi_is_pn_odd = hmac_wapi_is_pn_odd_bcast_etc;
781     }
782 
783     for (loop = 0; loop < HMAC_WAPI_MAX_KEYID; loop++) {
784         wapi_user_info->wapi_key[loop].key_en = OAL_FALSE;
785     }
786 
787     wapi_user_info->port_valid = OAL_FALSE;
788     wapi_user_info->wapi_decrypt = hmac_wapi_decrypt_etc;
789     wapi_user_info->wapi_encrypt = hmac_wapi_encrypt_etc;
790     wapi_user_info->wapi_netbuff_txhandle = hmac_wapi_netbuff_tx_handle_etc;
791     wapi_user_info->wapi_netbuff_rxhandle = hmac_wapi_netbuff_rx_handle_etc;
792     return OAL_SUCC;
793 }
794 
795 /*****************************************************************************
796  功能描述  : 获取用户的wapi对象指针
797 *****************************************************************************/
hmac_user_get_wapi_ptr_etc(hmac_vap_stru * hmac_vap,oal_bool_enum_uint8 pairwise,osal_u16 pairwise_idx)798 WIFI_TCM_TEXT OAL_STATIC hmac_wapi_stru *hmac_user_get_wapi_ptr_etc(hmac_vap_stru *hmac_vap,
799     oal_bool_enum_uint8 pairwise, osal_u16 pairwise_idx)
800 {
801     osal_u16 user_index;
802     hmac_wapi_stru *wapi_user_info;
803 
804     if (pairwise == OAL_TRUE) {
805         user_index = pairwise_idx;
806     } else {
807         user_index = hmac_vap->multi_user_idx;
808     }
809 
810     wapi_user_info = hmac_wapi_get_user_info(user_index);
811     return wapi_user_info;
812 }
813 
hmac_wapi_add_user_init(osal_void * notify_data)814 OAL_STATIC osal_bool hmac_wapi_add_user_init(osal_void *notify_data)
815 {
816     hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
817     hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(hmac_user->device_id);
818     hmac_wapi_init_etc(hmac_user->assoc_id, OAL_TRUE);
819     hmac_device->wapi = OAL_FALSE;
820     return OSAL_TRUE;
821 }
822 
hmac_wapi_rx_netbuf(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,hmac_wapi_stru * wapi,hmac_user_stru * hmac_user,mac_rx_ctl_stru ** rx_ctrl)823 OAL_STATIC oal_netbuf_stru *hmac_wapi_rx_netbuf(hmac_vap_stru *hmac_vap, oal_netbuf_stru *netbuf,
824     hmac_wapi_stru *wapi, hmac_user_stru *hmac_user, mac_rx_ctl_stru **rx_ctrl)
825 {
826     netbuf = wapi->wapi_netbuff_rxhandle(wapi, netbuf);
827     if (netbuf == OAL_PTR_NULL) {
828         oam_warning_log1(0, OAM_SF_RX,
829             "vap_id[%d] {hmac_rx_lan_frame_classify_wapi:: wapi decrypt FAIL!}", hmac_vap->vap_id);
830         hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, OAL_PTR_NULL);
831         hmac_user_stats_pkt_incr(hmac_user->rx_pkt_drop, 1);
832         return OAL_PTR_NULL;
833     }
834 
835     /* 重新获取该MPDU的控制信息 */
836     *rx_ctrl = (mac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
837     return netbuf;
838 }
839 
hmac_rx_lan_frame_classify_wapi(hmac_vap_stru * hmac_vap,oal_netbuf_stru * netbuf,const mac_ieee80211_frame_stru * frame_hdr,hmac_user_stru * hmac_user,mac_rx_ctl_stru ** rx_ctrl)840 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OAL_STATIC oal_netbuf_stru *hmac_rx_lan_frame_classify_wapi(hmac_vap_stru *hmac_vap,
841     oal_netbuf_stru *netbuf, const mac_ieee80211_frame_stru *frame_hdr,
842     hmac_user_stru *hmac_user, mac_rx_ctl_stru **rx_ctrl)
843 {
844     hmac_wapi_stru *wapi = OAL_PTR_NULL;
845     oal_bool_enum_uint8 is_mcast;
846     oal_bool_enum_uint8 pairwise = OAL_TRUE;
847 
848     is_mcast = ETHER_IS_MULTICAST(frame_hdr->address1);
849     if (is_mcast == OAL_TRUE) {
850         pairwise = OAL_FALSE;
851     }
852     wapi = hmac_user_get_wapi_ptr_etc(hmac_vap, pairwise, hmac_user->assoc_id);
853     if (wapi == OAL_PTR_NULL) {
854         oam_warning_log0(0, OAM_SF_WPA, "{hmac_rx_lan_frame_classify_wapi:: get wapi Err!.}");
855         hmac_user_stats_pkt_incr(hmac_user->rx_pkt_drop, 1);
856         hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, netbuf);
857         oal_netbuf_free(netbuf);
858         return OAL_PTR_NULL;
859     }
860     if ((wapi->port_valid != OAL_TRUE) || (wapi->wapi_netbuff_rxhandle == OAL_PTR_NULL)) {
861         return netbuf;
862     }
863     return hmac_wapi_rx_netbuf(hmac_vap, netbuf, wapi, hmac_user, rx_ctrl);
864 }
865 
hmac_wapi_tx_classify_special(hmac_vap_stru * hmac_vap,osal_u16 type,mac_tx_ctl_stru * tx_ctl,osal_u8 * tid)866 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OAL_STATIC osal_u32 hmac_wapi_tx_classify_special(hmac_vap_stru *hmac_vap,
867     osal_u16 type, mac_tx_ctl_stru *tx_ctl, osal_u8 *tid)
868 {
869     if (type == oal_host2net_short(ETHER_TYPE_WAI)) {
870         oam_info_log1(0, OAM_SF_TX, "vap_id[%d] {hmac_wapi_tx_classify_special::ETHER_TYPE_WAI.}", hmac_vap->vap_id);
871         hmac_tx_set_vip_tid(tx_ctl, WLAN_CB_FRAME_TYPE_DATA, MAC_DATA_WAPI, OAL_TRUE, tid);
872         return OSAL_TRUE;
873     }
874     return OSAL_FALSE;
875 }
876 
hmac_tx_lan_to_wlan_wapi(hmac_vap_stru * hmac_vap,oal_netbuf_stru ** netbuf)877 WIFI_TCM_TEXT OAL_STATIC osal_u32 hmac_tx_lan_to_wlan_wapi(hmac_vap_stru *hmac_vap, oal_netbuf_stru **netbuf)
878 {
879     hmac_wapi_stru *wapi = OAL_PTR_NULL;
880     mac_ieee80211_frame_stru *pst_mac_hdr = OAL_PTR_NULL;
881     oal_bool_enum_uint8 is_mcast;
882     oal_bool_enum_uint8 pairwise = OAL_TRUE;
883 
884     /* 获取wapi对象 组播/单播 */
885     pst_mac_hdr = mac_get_cb_frame_header_addr((mac_tx_ctl_stru *)oal_netbuf_cb(*netbuf));
886     is_mcast = ETHER_IS_MULTICAST(pst_mac_hdr->address1);
887     if (is_mcast == OAL_TRUE) {
888         pairwise = OAL_FALSE;
889     }
890     wapi = hmac_user_get_wapi_ptr_etc(hmac_vap, pairwise, hmac_vap->assoc_vap_id);
891     if (wapi == OAL_PTR_NULL) {
892         OAM_STAT_VAP_INCR(hmac_vap->vap_id, tx_abnormal_msdu_dropped, 1);
893         oam_warning_log1(0, OAM_SF_ANY,
894             "hmac_tx_lan_to_wlan_wapi:hmac_user_get_wapi_ptr_etc fail!assoc_id[%u]", hmac_vap->assoc_vap_id);
895         hmac_dft_print_drop_frame_info(THIS_FILE_ID, __LINE__, 1, *netbuf);
896         return OAL_ERR_CODE_PTR_NULL;
897     }
898 
899     if ((wapi->port_valid == OAL_TRUE) && (wapi->wapi_netbuff_txhandle != OAL_PTR_NULL)) {
900         *netbuf = wapi->wapi_netbuff_txhandle(wapi, *netbuf);
901     }
902 
903     return OAL_CONTINUE;
904 }
905 
906 /*****************************************************************************
907  功能描述  : 配置wapi key并且同步
908 *****************************************************************************/
hmac_config_wapi_add_key_etc(hmac_vap_stru * hmac_vap,mac_addkey_param_stru * payload_addkey_param)909 OAL_STATIC osal_u32 hmac_config_wapi_add_key_etc(hmac_vap_stru *hmac_vap, mac_addkey_param_stru *payload_addkey_param)
910 {
911     osal_u8                        key_index;
912     oal_bool_enum_uint8              pairwise;
913     osal_u8                       *mac_addr;
914     mac_key_params_stru             *key_param;
915     hmac_wapi_stru                  *wapi;
916     osal_u32                       ul_ret;
917     osal_u16                       user_index = 0;
918     hmac_device_stru                 *hmac_device;
919 
920     key_index = payload_addkey_param->key_index;
921     if (key_index >= HMAC_WAPI_MAX_KEYID) {
922         oam_error_log1(0, OAM_SF_WPA, "{hmac_config_wapi_add_key_etc::keyid==%u Err!.}", key_index);
923         return OAL_FAIL;
924     }
925 
926     pairwise  = payload_addkey_param->pairwise;
927     mac_addr = (osal_u8 *)payload_addkey_param->mac_addr;
928     key_param   = &payload_addkey_param->key;
929 
930     if (key_param->key_len != (WAPI_KEY_LEN * 2)) { /* 2倍长度 */
931         oam_error_log1(0, OAM_SF_WPA, "{hmac_config_wapi_add_key_etc:: key_len %u Err!.}", key_param->key_len);
932         return OAL_FAIL;
933     }
934 
935     if (pairwise) {
936         ul_ret = hmac_vap_find_user_by_macaddr_etc(hmac_vap, mac_addr, &user_index);
937         if (ul_ret != OAL_SUCC) {
938             oam_error_log2(0, OAM_SF_ANY,
939                 "vap_id[%d] {hmac_config_wapi_add_key_etc::hmac_vap_find_user_by_macaddr_etc failed. %u}",
940                 hmac_vap->vap_id, ul_ret);
941             return OAL_FAIL;
942         }
943     }
944 
945     wapi = hmac_user_get_wapi_ptr_etc(hmac_vap, pairwise, user_index);
946     if (wapi == OAL_PTR_NULL) {
947         oam_error_log0(0, OAM_SF_WPA, "{hmac_config_wapi_add_key_etc:: get wapi  Err!.}");
948         return OAL_FAIL;
949     }
950 
951     hmac_wapi_add_key_etc(wapi, key_index, key_param->key);
952 
953     hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
954     if (hmac_device == OAL_PTR_NULL) {
955         oam_error_log1(0, OAM_SF_CFG, "vap_id[%d] {hmac_config_wapi_add_key_etc::device null.}",
956             hmac_vap->vap_id);
957         return OAL_ERR_CODE_PTR_NULL;
958     }
959     hmac_device->wapi = OAL_TRUE;
960 
961     return OAL_SUCC;
962 }
963 
964 /*****************************************************************************
965  功能描述  : 保存wapi key并且同步
966 *****************************************************************************/
hmac_wapi_add_key_and_sync_etc(hmac_vap_stru * hmac_vap,osal_u32 type,mac_addkey_param_stru * payload_addkey_param)967 OAL_STATIC osal_u32 hmac_wapi_add_key_and_sync_etc(hmac_vap_stru *hmac_vap, osal_u32 type,
968     mac_addkey_param_stru *payload_addkey_param)
969 {
970     osal_u32 ret;
971 
972     if (type != WITP_WLAN_CIPHER_SUITE_SMS4) {
973         return OAL_CONTINUE;
974     }
975     oam_warning_log2(0, OAM_SF_WPA, "{hmac_wapi_add_key_and_sync_etc:: key idx==%u, pairwise==%u}",
976         payload_addkey_param->key_index, payload_addkey_param->pairwise);
977 
978     ret = hmac_config_wapi_add_key_etc(hmac_vap, payload_addkey_param);
979     if (ret != OAL_SUCC) {
980         oam_error_log2(0, OAM_SF_WPA,
981             "vap_id[%d] {hmac_wapi_add_key_and_sync_etc::hmac_config_wapi_add_key_etc fail[%d].}", hmac_vap->vap_id,
982             ret);
983         return ret;
984     }
985 
986     /* 关掉硬件的加解密功能 */
987     hal_disable_ce();
988 
989     return ret;
990 }
991 
992 /*****************************************************************************
993  功能描述  : 判断wapi设备是否关连
994 *****************************************************************************/
hmac_wapi_connected_etc(osal_u8 device_id)995 OAL_STATIC osal_u8  hmac_wapi_connected_etc(osal_u8 device_id)
996 {
997     osal_u8 vap_idx;
998     hmac_device_stru *hmac_device = OSAL_NULL;
999     hmac_vap_stru *hmac_vap = OSAL_NULL;
1000     hmac_wapi_stru *wapi_user_info = OSAL_NULL;
1001 
1002     hmac_device = hmac_res_get_mac_dev_etc(device_id);
1003     if (OAL_UNLIKELY(hmac_device == OAL_PTR_NULL)) {
1004         oam_error_log1(0, OAM_SF_UM, "{hmac_wapi_connected_etc::hmac_device null.id %u}", device_id);
1005         return OAL_FALSE;
1006     }
1007 
1008     for (vap_idx = 0; vap_idx < hmac_device->vap_num; vap_idx++) {
1009         hmac_vap = mac_res_get_hmac_vap(hmac_device->vap_id[vap_idx]);
1010         if (OAL_UNLIKELY(hmac_vap == OAL_PTR_NULL)) {
1011             oam_warning_log1(0, OAM_SF_CFG, "vap is null! vap id is %d", hmac_device->vap_id[vap_idx]);
1012             continue;
1013         }
1014 
1015         if (!is_sta(hmac_vap)) {
1016             continue;
1017         }
1018 
1019         wapi_user_info = hmac_wapi_get_user_info(hmac_vap->multi_user_idx);
1020         if ((wapi_user_info != OAL_PTR_NULL) && (wapi_user_info->port_valid == OAL_TRUE)) {
1021             return OAL_TRUE;
1022         }
1023     }
1024 
1025     return OAL_FALSE;
1026 }
1027 
hmac_11i_reset_wapi(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user)1028 OAL_STATIC osal_u32 hmac_11i_reset_wapi(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user)
1029 {
1030     hmac_device_stru *hmac_device = OSAL_NULL;
1031     hmac_wapi_stru *wapi_user_info = hmac_wapi_get_user_info(hmac_user->assoc_id);
1032 
1033     if (wapi_user_info == OSAL_NULL) {
1034         return OAL_ERR_CODE_PTR_NULL;
1035     }
1036 
1037     /* 11i的情况下,关掉wapi端口 */
1038     hmac_wapi_reset_port_etc(wapi_user_info);
1039     hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
1040     if (hmac_device == OSAL_NULL) {
1041         oam_error_log1(0, 0, "vap_id[%d] {hmac_config_11i_add_key_etc::device null.}", hmac_vap->vap_id);
1042         return OAL_ERR_CODE_PTR_NULL;
1043     }
1044     hmac_device->wapi = OAL_FALSE;
1045     return OAL_CONTINUE;
1046 }
1047 
hmac_wapi_update_legcy_only(const mac_bss_dscr_stru * bss_dscr,oal_bool_enum_uint8 * legcy_only)1048 OAL_STATIC osal_void hmac_wapi_update_legcy_only(const mac_bss_dscr_stru *bss_dscr, oal_bool_enum_uint8 *legcy_only)
1049 {
1050     if ((bss_dscr != OSAL_NULL) && (bss_dscr->wapi != 0)) {
1051         *legcy_only = OAL_TRUE;
1052     }
1053 }
1054 
hmac_wapi_ether_type_check(osal_u16 ether_type)1055 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OAL_STATIC osal_bool hmac_wapi_ether_type_check(osal_u16 ether_type)
1056 {
1057     return (oal_byteorder_host_to_net_uint16(ETHER_TYPE_WAI) != ether_type);
1058 }
1059 
hmac_wapi_disable(osal_u8 wapi)1060 OAL_STATIC osal_bool hmac_wapi_disable(osal_u8 wapi)
1061 {
1062     return (wapi != OAL_TRUE);
1063 }
1064 
hmac_wapi_get_ether_type(osal_u16 ether_type)1065 WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT OAL_STATIC osal_bool hmac_wapi_get_ether_type(osal_u16 ether_type)
1066 {
1067     return (ether_type == oal_host2net_short(ETHER_TYPE_WAI));
1068 }
1069 
hmac_wapi_connect_check_bss_dscr(mac_bss_dscr_stru * bss_dscr,hmac_vap_stru * hmac_vap,mac_conn_param_stru * connect_param)1070 OAL_STATIC osal_u32 hmac_wapi_connect_check_bss_dscr(mac_bss_dscr_stru *bss_dscr,
1071     hmac_vap_stru *hmac_vap, mac_conn_param_stru *connect_param)
1072 {
1073     bss_dscr->wapi = connect_param->wapi;
1074     if (bss_dscr->wapi != 0) {
1075         hmac_device_stru *hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
1076         if (hmac_device == OAL_PTR_NULL) {
1077             oam_error_log2(0, OAM_SF_CFG,
1078                 "vap_id[%d] {hmac_wapi_connect_check_bss_dscr::connect failed, mac_device null! device_id[%d]}",
1079                 hmac_vap->vap_id, hmac_vap->device_id);
1080             return OAL_ERR_CODE_MAC_DEVICE_NULL;
1081         }
1082 
1083         if (mac_device_is_p2p_connected_etc(hmac_device) == OAL_SUCC) {
1084             oam_warning_log1(0, OAM_SF_CFG,
1085                 "vap_id[%d] {hmac_wapi_connect_check_bss_dscr:: wapi connect failed for p2p having been connected!.}",
1086                 hmac_vap->vap_id);
1087             return OAL_FAIL;
1088         }
1089     }
1090     return OAL_CONTINUE;
1091 }
1092 
hmac_wapi_update_roam(hmac_vap_stru * hmac_vap,osal_u8 * roming_now)1093 OAL_STATIC osal_s32 hmac_wapi_update_roam(hmac_vap_stru *hmac_vap, osal_u8 *roming_now)
1094 {
1095     /* wapi下,将roam标志置为1,防止arp探测 */
1096     hmac_wapi_stru *wapi_user_info = hmac_wapi_get_user_info(hmac_vap->multi_user_idx);
1097     if (wapi_user_info == OAL_PTR_NULL) {
1098         return OAL_PTR_NULL;
1099     }
1100 
1101     if (wapi_user_info->port_valid == OAL_TRUE) {
1102         *roming_now = 1;
1103         return OAL_FAIL;
1104     }
1105     return OAL_SUCC;
1106 }
1107 
hmac_wapi_user_add_check(osal_u8 device_id)1108 OAL_STATIC osal_u32 hmac_wapi_user_add_check(osal_u8 device_id)
1109 {
1110     if (hmac_res_get_mac_dev_etc(device_id) == OAL_PTR_NULL) {
1111         oam_warning_log0(0, OAM_SF_UM, "{hmac_wapi_user_add_check::hmac_device null.}");
1112         return OAL_ERR_CODE_PTR_NULL;
1113     }
1114     return OAL_CONTINUE;
1115 }
1116 
hmac_wapi_update_connect_param(osal_u32 wpa_versions)1117 OAL_STATIC osal_u8 hmac_wapi_update_connect_param(osal_u32 wpa_versions)
1118 {
1119     if (wpa_versions == WITP_WAPI_VERSION) {
1120         oam_warning_log0(0, OAM_SF_ANY, "hmac_wapi_update_connect_param::crypt ver is wapi!");
1121         return OAL_TRUE;
1122     }
1123     return OAL_FALSE;
1124 }
1125 
hmac_wapi_init(osal_void)1126 osal_u32 hmac_wapi_init(osal_void)
1127 {
1128     osal_u16 user_id;
1129     for (user_id = 0; user_id < WLAN_USER_MAX_USER_LIMIT; user_id++) {
1130         g_wapi_userinfo[user_id] = OSAL_NULL;
1131     }
1132     /* 通知注册 */
1133     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_wapi_add_user_init);
1134     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_wapi_del_user_exit);
1135     /* 对外接口注册 */
1136     hmac_feature_hook_register(HMAC_FHOOK_WAPI_INIT, hmac_wapi_init_etc);
1137     hmac_feature_hook_register(HMAC_FHOOK_WAPI_RX_FRAME, hmac_rx_lan_frame_classify_wapi);
1138     hmac_feature_hook_register(HMAC_FHOOK_WAPI_TX_FRAME, hmac_wapi_tx_classify_special);
1139     hmac_feature_hook_register(HMAC_FHOOK_WAPI_TX_LAN2WLAN, hmac_tx_lan_to_wlan_wapi);
1140     hmac_feature_hook_register(HMAC_FHOOK_WAPI_RESET, hmac_11i_reset_wapi);
1141     hmac_feature_hook_register(HMAC_FHOOK_WAPI_ADD_KEY, hmac_wapi_add_key_and_sync_etc);
1142     hmac_feature_hook_register(HMAC_FHOOK_WAPI_UPDATE_LEGCY_ONLY, hmac_wapi_update_legcy_only);
1143     hmac_feature_hook_register(HMAC_FHOOK_WAPI_ETHER_TYPE_CHECK, hmac_wapi_ether_type_check);
1144     hmac_feature_hook_register(HMAC_FHOOK_WAPI_CONNECT_BSS_DSCR, hmac_wapi_connect_check_bss_dscr);
1145     hmac_feature_hook_register(HMAC_FHOOK_WAPI_DISABLE, hmac_wapi_disable);
1146     hmac_feature_hook_register(HMAC_FHOOK_WAPI_UPDATE_ROAM, hmac_wapi_update_roam);
1147     hmac_feature_hook_register(HMAC_FHOOK_WAPI_USER_ADD_CHECK, hmac_wapi_user_add_check);
1148     hmac_feature_hook_register(HMAC_FHOOK_WAPI_DEINIT, hmac_wapi_deinit_etc);
1149     hmac_feature_hook_register(HMAC_FHOOK_WAPI_GET_ETHER_TYPE, hmac_wapi_get_ether_type);
1150     hmac_feature_hook_register(HMAC_FHOOK_WAPI_CONNECT_CHECK, hmac_wapi_connected_etc);
1151     hmac_feature_hook_register(HMAC_FHOOK_WAPI_UPDATE_CONNECT_PARAM, hmac_wapi_update_connect_param);
1152     return OAL_SUCC;
1153 }
1154 
hmac_wapi_deinit(osal_void)1155 osal_void hmac_wapi_deinit(osal_void)
1156 {
1157     /* 通知去注册 */
1158     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_wapi_add_user_init);
1159     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_wapi_del_user_exit);
1160     /* 对外接口去注册 */
1161     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_INIT);
1162     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_RX_FRAME);
1163     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_TX_FRAME);
1164     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_TX_LAN2WLAN);
1165     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_RESET);
1166     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_ADD_KEY);
1167     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_UPDATE_LEGCY_ONLY);
1168     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_ETHER_TYPE_CHECK);
1169     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_CONNECT_BSS_DSCR);
1170     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_DISABLE);
1171     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_UPDATE_ROAM);
1172     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_USER_ADD_CHECK);
1173     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_DEINIT);
1174     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_GET_ETHER_TYPE);
1175     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_CONNECT_CHECK);
1176     hmac_feature_hook_unregister(HMAC_FHOOK_WAPI_UPDATE_CONNECT_PARAM);
1177     return;
1178 }
1179 
1180 #ifdef __cplusplus
1181 #if __cplusplus
1182 }
1183 #endif
1184 #endif
1185 
1186