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