1 /** @file keyMgmtSta.c
2 *
3 * @brief This file defines key management API for sta
4 * Copyright (C) 2014-2017, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20 /******************************************************
21 Change log:
22 03/07/2014: Initial version
23 ******************************************************/
24
25 #include "wltypes.h"
26 #include "IEEE_types.h"
27 #include "hostsa_ext_def.h"
28 #include "authenticator.h"
29 #include "wl_macros.h"
30 #include "keyMgmtSta.h"
31 #include "pass_phrase.h"
32 #include "wlpd.h"
33 #include "KeyApiStaDefs.h"
34 #include "crypt_new.h"
35 #include "pmkCache.h"
36 #include "sha1.h"
37 #include "md5.h"
38 #include "rc4.h"
39 #include "aes_cmac.h"
40 #include "mrvl_sha256_crypto.h"
41
42 #include "keyMgmtSta_rom.h"
43 #include "tlv.h"
44
45 #define DEAUTH_DELAY_TIME_INTERVAL 40000 /* 40 ms */
46
47 #define PWK_MSG1_RETRIES 7
48
49 /* 10 seconds timeout for completing RSN key handshake */
50 //#define RSNSECUREDTIMEOUT 10000000
51 #define RSNSECUREDTIMEOUT MRVDRV_TIMER_10S
52
53 //static void SendMICFailReport_sta(cm_ConnectionInfo_t* connPtr,
54 // keyMgmtInfoSta_t* pKeyMgmtInfoSta,
55 // BOOLEAN isUnicast);
56 #if 0
57 static BufferReturnNotify_t keyMgmtKeyGroupTxDone(phostsa_private priv);
58 static BufferReturnNotify_t keyMgmtKeyPairwiseTxDone(phostsa_private priv);
59 static BufferReturnNotify_t keyMgmtKeyPairAndGroupTxDone(phostsa_private priv);
60 #endif
61 static void keyMgmtKeyGroupTxDone(phostsa_private priv);
62 static void keyMgmtKeyPairwiseTxDone(phostsa_private priv);
63 static void keyMgmtKeyPairAndGroupTxDone(phostsa_private priv);
64
65 static supplicantData_t keyMgmt_SuppData[MAX_SUPPLICANT_SESSIONS];
66
67 void FillKeyMaterialStruct(phostsa_private priv,
68 UINT16 key_len, UINT8 isPairwise, KeyData_t *pKey);
69 void FillGrpKeyMaterialStruct(phostsa_private priv,
70 UINT16 keyType,
71 UINT8 *pn,
72 UINT8 keyIdx, UINT8 keyLen, KeyData_t *pKey);
73 UINT16 keyMgmtFormatWpaRsnIe(phostsa_private priv,
74 UINT8 *pos,
75 IEEEtypes_MacAddr_t *pBssid,
76 IEEEtypes_MacAddr_t *pStaAddr,
77 UINT8 *pPmkid, BOOLEAN addPmkid);
78 t_u8 supplicantIsEnabled(void *priv);
79
80 void
allocSupplicantData(void * priv)81 allocSupplicantData(void *priv)
82 {
83 phostsa_private psapriv = (phostsa_private)priv;
84 int i = 0;
85
86 if (psapriv->suppData) {
87 return;
88 }
89 //if (pm_fns->bss_type == MLAN_BSS_TYPE_STA)
90 {
91
92 // int_sta = os_if_save_EnterCriticalSection();
93 for (i = 0; i < MAX_SUPPLICANT_SESSIONS; i++) {
94 if (keyMgmt_SuppData[i].inUse == FALSE) {
95 keyMgmt_SuppData[i].inUse = TRUE;
96 supplicantInit((void *)psapriv,
97 &keyMgmt_SuppData[i]);
98 psapriv->suppData =
99 (void *)&keyMgmt_SuppData[i];
100 break;
101 }
102 }
103 // os_if_save_ExitCriticalSection(int_sta);
104
105 // os_ASSERT(connPtr->suppData);
106 }
107
108 }
109
110 void
freeSupplicantData(void * priv)111 freeSupplicantData(void *priv)
112 {
113 phostsa_private psapriv = (phostsa_private)priv;
114 struct supplicantData *suppData = psapriv->suppData;
115
116 if (suppData != NULL) {
117 suppData->inUse = FALSE;
118 suppData = NULL;
119 }
120 }
121
122 mlan_status
initSupplicantTimer(void * priv)123 initSupplicantTimer(void *priv)
124 {
125 phostsa_private psapriv = (phostsa_private)priv;
126 hostsa_util_fns *util_fns = &psapriv->util_fns;
127 mlan_status ret = MLAN_STATUS_SUCCESS;
128
129 if (util_fns->moal_init_timer(util_fns->pmoal_handle,
130 &psapriv->suppData->keyMgmtInfoSta.
131 rsnTimer,
132 keyMgmtStaRsnSecuredTimeoutHandler,
133 psapriv) != MLAN_STATUS_SUCCESS) {
134 ret = MLAN_STATUS_FAILURE;
135 return ret;
136 }
137
138 return ret;
139 }
140
141 void
freeSupplicantTimer(void * priv)142 freeSupplicantTimer(void *priv)
143 {
144 phostsa_private psapriv = (phostsa_private)priv;
145 hostsa_util_fns *util_fns = &psapriv->util_fns;
146
147 if (psapriv->suppData->keyMgmtInfoSta.rsnTimer) {
148 util_fns->moal_free_timer(util_fns->pmoal_handle,
149 psapriv->suppData->keyMgmtInfoSta.
150 rsnTimer);
151 psapriv->suppData->keyMgmtInfoSta.rsnTimer = NULL;
152 }
153 }
154
155 //#if defined(PSK_SUPPLICANT) || defined (WPA_NONE)
156 void
keyMgmtSendDeauth2Peer(phostsa_private priv,UINT16 reason)157 keyMgmtSendDeauth2Peer(phostsa_private priv, UINT16 reason)
158 {
159 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
160
161 /* Assumes we are sending to AP */
162 //keyMgmtSendDeauth((cm_ConnectionInfo_t*)connPtr,
163 // &((cm_ConnectionInfo_t*)connPtr)->suppData->localBssid,
164 // reason);
165 #if 0
166 ret = wlan_prepare_cmd(priv,
167 HostCmd_CMD_802_11_DEAUTHENTICATE,
168 HostCmd_ACT_GEN_SET,
169 0, NULL, &priv->suppData->localBssid);
170
171 if (ret == MLAN_STATUS_SUCCESS)
172 wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
173 #endif
174 pm_fns->hostsa_StaSendDeauth(pm_fns->pmlan_private,
175 (t_u8 *)&priv->suppData->localBssid,
176 reason);
177 }
178
179 BOOLEAN
keyMgmtProcessMsgExt(phostsa_private priv,keyMgmtInfoSta_t * pKeyMgmtInfoSta,EAPOL_KeyMsg_t * pKeyMsg)180 keyMgmtProcessMsgExt(phostsa_private priv, keyMgmtInfoSta_t *pKeyMgmtInfoSta,
181 EAPOL_KeyMsg_t *pKeyMsg)
182 {
183 if (pKeyMsg->key_info.KeyType && pKeyMsg->key_info.KeyMIC) {
184 /* PWK Msg #3 processing */
185 #ifdef DOT11R
186 if (supplicantAkmWpa2Ft
187 (priv,
188 &pKeyMgmtInfoSta->connPtr->suppData->customMIB_RSNConfig.
189 AKM)) {
190 if (dot11r_process_pwk_msg3(pKeyMsg) == FALSE) {
191 return FALSE;
192 }
193 }
194 #endif
195
196 #ifdef CCX_MFP
197 if (ccx_mfp_process_pwk_msg3(pKeyMsg) == FALSE) {
198 return FALSE;
199 }
200 #endif
201 }
202
203 /*
204 ** KDE processing for Msg#3 and for any Group Key rotations
205 */
206 if (pKeyMsg->key_info.EncryptedKeyData) {
207 #ifdef DOT11W
208 KDE_t *pKde;
209
210 /* Parse IGTK for 11w */
211 pKde = parseKeyKDE_DataType(priv, pKeyMsg->key_data,
212 pKeyMsg->key_material_len,
213 KDE_DATA_TYPE_IGTK);
214 if (pKde) {
215 //Not install same iGtk
216 if (!memcmp(&priv->util_fns,
217 pKeyMgmtInfoSta->IGtk.Key,
218 (UINT8 *)(((IGtkKde_t *)pKde->data)->IGtk),
219 MIN(sizeof(pKeyMgmtInfoSta->IGtk.Key),
220 (pKde->length - 12)))) {
221 return TRUE;
222 } else {
223 keyMgmtSetIGtk(priv, pKeyMgmtInfoSta,
224 (IGtkKde_t *)pKde->data,
225 pKde->length);
226 }
227 #if 0
228 hostEventPrintHex(assocAgent_getConnPtr(),
229 "SetIGTK", keyMgmtGetIGtk(), 16);
230 #endif
231 }
232 #endif
233 }
234
235 return TRUE;
236 }
237
238 #ifdef WAR_ROM_BUG50312_SIMUL_INFRA_WFD
239 EAPOL_KeyMsg_t *
patch_ProcessRxEAPOL_GrpMsg1(phostsa_private priv,mlan_buffer * pmbuf,keyMgmtInfoSta_t * pKeyMgmtInfoSta)240 patch_ProcessRxEAPOL_GrpMsg1(phostsa_private priv, mlan_buffer *pmbuf,
241 keyMgmtInfoSta_t *pKeyMgmtInfoSta)
242 {
243 hostsa_util_fns *util_fns = &priv->util_fns;
244 EAPOL_KeyMsg_t *pKeyMsg;
245 KeyData_t GRKey;
246
247 pKeyMsg = GetKeyMsgNonceFromEAPOL(priv, pmbuf, pKeyMgmtInfoSta);
248 if (!pKeyMsg) {
249 return NULL;
250 }
251
252 KeyMgmtSta_ApplyKEK(priv, pKeyMsg,
253 &pKeyMgmtInfoSta->GRKey,
254 pKeyMgmtInfoSta->EAPOL_Encr_Key);
255
256 pKeyMgmtInfoSta->RSNDataTrafficEnabled = 1;
257 //microTimerStop(pKeyMgmtInfoSta->rsnTimer);
258 util_fns->moal_stop_timer(util_fns->pmoal_handle,
259 pKeyMgmtInfoSta->rsnTimer);
260 //pKeyMgmtInfoSta->rsnTimer = 0;
261
262 /* Decrypt the group key */
263 if (pKeyMsg->desc_type == 2) {
264 /* WPA2 */
265 /* handle it according to 802.11i GTK frame format */
266 parseKeyDataGTK(priv, pKeyMsg->key_data,
267 pKeyMsg->key_material_len, &GRKey);
268 /* Not install same GTK */
269 if (!memcmp
270 (util_fns, pKeyMgmtInfoSta->GRKey.Key, GRKey.Key,
271 TK_SIZE)) {
272 priv->gtk_installed = 1;
273 } else {
274 memcpy(util_fns, &pKeyMgmtInfoSta->GRKey, &GRKey,
275 sizeof(KeyData_t));
276 pKeyMgmtInfoSta->GRKey.TxIV16 = GRKey.TxIV16;
277 pKeyMgmtInfoSta->GRKey.TxIV32 = 0xFFFFFFFF;
278 priv->gtk_installed = 0;
279 }
280
281 if (keyMgmtProcessMsgExt(priv, pKeyMgmtInfoSta, pKeyMsg) ==
282 FALSE) {
283 return NULL;
284 }
285 } else {
286 /* WPA or Dynamic WEP */
287 if (!memcmp
288 (util_fns, pKeyMgmtInfoSta->GRKey.Key, pKeyMsg->key_data,
289 pKeyMsg->key_material_len)) {
290 priv->gtk_installed = 1;
291 } else {
292 memcpy(util_fns, pKeyMgmtInfoSta->GRKey.Key,
293 pKeyMsg->key_data, pKeyMsg->key_material_len);
294
295 pKeyMgmtInfoSta->GRKey.KeyIndex =
296 pKeyMsg->key_info.KeyIndex;
297 }
298 }
299
300 return pKeyMsg;
301 }
302 #endif
303
304 #ifdef WAR_ROM_BUG50312_SIMUL_INFRA_WFD
305 EAPOL_KeyMsg_t *
patch_ProcessRxEAPOL_PwkMsg3(phostsa_private priv,mlan_buffer * pmbuf,keyMgmtInfoSta_t * pKeyMgmtInfoSta)306 patch_ProcessRxEAPOL_PwkMsg3(phostsa_private priv, mlan_buffer *pmbuf,
307 keyMgmtInfoSta_t *pKeyMgmtInfoSta)
308 {
309 hostsa_util_fns *util_fns = &priv->util_fns;
310 EAPOL_KeyMsg_t *pKeyMsg;
311
312 pKeyMsg = GetKeyMsgNonceFromEAPOL(priv, pmbuf, pKeyMgmtInfoSta);
313 if (!pKeyMsg) {
314 return NULL;
315 }
316 pKeyMgmtInfoSta->newPWKey.TxIV16 = 1;
317 pKeyMgmtInfoSta->newPWKey.TxIV32 = 0;
318
319 /* look for group key once the pairwise has been plumbed */
320 if (pKeyMsg->key_info.EncryptedKeyData) {
321 /* I think the timer stop should be moved later on
322 in case ramHook_Process_CCX_MFP_11r returns
323 FALSE
324 */
325
326 // microTimerStop(pKeyMgmtInfoSta->rsnTimer);
327 util_fns->moal_stop_timer(util_fns->pmoal_handle,
328 pKeyMgmtInfoSta->rsnTimer);
329 // pKeyMgmtInfoSta->rsnTimer = 0;
330
331 KeyMgmtSta_ApplyKEK(priv, pKeyMsg,
332 &pKeyMgmtInfoSta->GRKey,
333 pKeyMgmtInfoSta->EAPOL_Encr_Key);
334
335 if (keyMgmtProcessMsgExt(priv, pKeyMgmtInfoSta, pKeyMsg) ==
336 FALSE) {
337 return NULL;
338 }
339
340 parseKeyDataGTK(priv, pKeyMsg->key_data,
341 pKeyMsg->key_material_len,
342 &pKeyMgmtInfoSta->GRKey);
343
344 }
345 return pKeyMsg;
346 }
347 #endif
348
349 /* This routine must be called after mlmeStaInit_UR
350 ** It assumes that parent session structures are initialized
351 ** (vmacEntry_ur and mlmeStaInfo_URepeater)
352 */
353 void
KeyMgmtInitSta(phostsa_private priv)354 KeyMgmtInitSta(phostsa_private priv)
355 {
356 KeyMgmtSta_InitSession(priv, &priv->suppData->keyMgmtInfoSta);
357 }
358
359 Status_e
GeneratePWKMsg2(phostsa_private priv,mlan_buffer * pmbuf,UINT8 * pSNonce,UINT8 * pEAPOLMICKey,UINT8 forceKeyDescVersion)360 GeneratePWKMsg2(phostsa_private priv, mlan_buffer *pmbuf,
361 UINT8 *pSNonce, UINT8 *pEAPOLMICKey, UINT8 forceKeyDescVersion)
362 {
363 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
364 EAPOL_KeyMsg_Tx_t *pTxEapol = MNULL;
365 UINT16 frameLen;
366 UINT16 packet_len = 0;
367 BOOLEAN rsnIeAdded = FALSE;
368 EAPOL_KeyMsg_t *pRxEapol =
369 (EAPOL_KeyMsg_t *)(pmbuf->pbuf + pmbuf->data_offset +
370 sizeof(ether_hdr_t));
371 struct supplicantData *suppData = priv->suppData;
372 pmlan_buffer newbuf = MNULL;
373 UINT8 intf_hr_len =
374 pm_fns->Hostsa_get_intf_hr_len(pm_fns->pmlan_private);
375
376 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
377
378 newbuf = pm_fns->hostsa_alloc_mlan_buffer(pm_fns->pmlan_adapter,
379 MLAN_TX_DATA_BUF_SIZE_2K, 0,
380 MOAL_MALLOC_BUFFER);
381 if (newbuf) {
382 newbuf->bss_index = pmbuf->bss_index;
383 newbuf->buf_type = pmbuf->buf_type;
384 newbuf->priority = pmbuf->priority;
385 newbuf->in_ts_sec = pmbuf->in_ts_sec;
386 newbuf->in_ts_usec = pmbuf->in_ts_usec;
387 newbuf->data_offset =
388 (sizeof(TxPD) + intf_hr_len + DMA_ALIGNMENT);
389 }
390
391 if (newbuf == NULL) {
392 PRINTM(MERROR, "GeneratePWKMsg2 newbuf=NULL\n");
393 return FAIL;
394 }
395
396 pTxEapol = (EAPOL_KeyMsg_Tx_t *)(newbuf->pbuf + newbuf->data_offset);
397 KeyMgmtSta_PrepareEAPOLFrame(priv, pTxEapol,
398 pRxEapol,
399 (t_u8 *)&suppData->localBssid,
400 (t_u8 *)&suppData->localStaAddr, pSNonce);
401
402 #ifdef DOT11R
403 if (dot11r_is_ft_akm(&connPtr->suppData->customMIB_RSNConfig.AKM)) {
404 dot11r_process_pwk_msg2(connPtr, &pTxEapol->keyMsg);
405 rsnIeAdded = TRUE;
406 }
407 #endif
408
409 if (!rsnIeAdded && (pTxEapol->keyMsg.desc_type != 1)) {
410 /* Add the RSN/WPA IE if not dynamic WEP */
411 pTxEapol->keyMsg.key_material_len
412 = keyMgmtFormatWpaRsnIe(priv,
413 (UINT8 *)&pTxEapol->keyMsg.
414 key_data, &suppData->localBssid,
415 &suppData->localStaAddr, NULL,
416 FALSE);
417 }
418 #ifdef CCX_MFP
419 ccx_mfp_process_pwk_msg2(&pTxEapol->keyMsg);
420 #endif
421
422 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(priv, pTxEapol,
423 pEAPOLMICKey,
424 EAPOL_PROTOCOL_V1,
425 forceKeyDescVersion);
426
427 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
428 UpdateEAPOLWcbLenAndTransmit(priv, newbuf, packet_len);
429
430 PRINTM(MMSG, "LEAVE: %s\n", __FUNCTION__);
431 return SUCCESS;
432 }
433
434 Status_e
GeneratePWKMsg4(phostsa_private priv,mlan_buffer * pmbuf,keyMgmtInfoSta_t * pKeyMgmtInfoSta,BOOLEAN groupKeyReceived)435 GeneratePWKMsg4(phostsa_private priv, mlan_buffer *pmbuf,
436 keyMgmtInfoSta_t *pKeyMgmtInfoSta, BOOLEAN groupKeyReceived)
437 {
438 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
439 struct supplicantData *suppData = priv->suppData;
440 EAPOL_KeyMsg_Tx_t *pTxEapol;
441 UINT16 frameLen;
442 UINT16 packet_len = 0;
443 EAPOL_KeyMsg_t *pRxEapol =
444 (EAPOL_KeyMsg_t *)(pmbuf->pbuf + pmbuf->data_offset +
445 sizeof(ether_hdr_t));
446 pmlan_buffer newbuf = MNULL;
447 UINT8 intf_hr_len =
448 pm_fns->Hostsa_get_intf_hr_len(pm_fns->pmlan_private);
449
450 PRINTM(MMSG, "Enter GeneratePWKMsg4\n");
451
452 newbuf = pm_fns->hostsa_alloc_mlan_buffer(pm_fns->pmlan_adapter,
453 MLAN_TX_DATA_BUF_SIZE_2K, 0,
454 MOAL_MALLOC_BUFFER);
455 if (newbuf) {
456 newbuf->bss_index = pmbuf->bss_index;
457 newbuf->buf_type = pmbuf->buf_type;
458 newbuf->priority = pmbuf->priority;
459 newbuf->in_ts_sec = pmbuf->in_ts_sec;
460 newbuf->in_ts_usec = pmbuf->in_ts_usec;
461 newbuf->data_offset =
462 (sizeof(TxPD) + intf_hr_len + DMA_ALIGNMENT);
463 }
464
465 if (newbuf == NULL) {
466 PRINTM(MERROR, "GeneratePWKMsg4 newbuf=NULL\n");
467 return FAIL;
468 }
469
470 pTxEapol = (EAPOL_KeyMsg_Tx_t *)(newbuf->pbuf + newbuf->data_offset);
471
472 KeyMgmtSta_PrepareEAPOLFrame(priv, pTxEapol,
473 pRxEapol,
474 (t_u8 *)&suppData->localBssid,
475 (t_u8 *)&suppData->localStaAddr, NULL);
476
477 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(priv, pTxEapol,
478 pKeyMgmtInfoSta->
479 EAPOL_MIC_Key,
480 EAPOL_PROTOCOL_V1, 0);
481
482 /* Set the BuffDesc free callback so the PSK supplicant can determine
483 ** if the 4th message was successfully received by the AP. Allows
484 ** the supplicant to hold off switching/setting the new key until
485 ** it is sure the AP has acknowledged the handshake completion
486 */
487 #if 0
488 if (pKeyMgmtInfoSta->RSNDataTrafficEnabled) {
489 pBufDesc->isCB = 1;
490 if (groupKeyReceived) {
491 pBufDesc->freeCallback = keyMgmtKeyPairAndGroupTxDone;
492 } else {
493 pBufDesc->freeCallback = keyMgmtKeyPairwiseTxDone;
494 }
495 } else {
496 #endif
497
498 if (groupKeyReceived) {
499 keyMgmtKeyPairAndGroupTxDone(priv);
500 } else {
501 keyMgmtKeyPairwiseTxDone(priv);
502 }
503 #if 0
504 }
505 #endif
506
507 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
508 UpdateEAPOLWcbLenAndTransmit(priv, newbuf, packet_len);
509
510 PRINTM(MMSG, "Leave GeneratePWKMsg4\n");
511 return SUCCESS;
512 }
513
514 Status_e
GenerateGrpMsg2(phostsa_private priv,mlan_buffer * pmbuf,keyMgmtInfoSta_t * pKeyMgmtInfoSta)515 GenerateGrpMsg2(phostsa_private priv, mlan_buffer *pmbuf,
516 keyMgmtInfoSta_t *pKeyMgmtInfoSta)
517 {
518 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
519 EAPOL_KeyMsg_t *pRxEapol =
520 (EAPOL_KeyMsg_t *)(pmbuf->pbuf + pmbuf->data_offset +
521 sizeof(ether_hdr_t));
522 EAPOL_KeyMsg_Tx_t *pTxEapol;
523 UINT16 frameLen;
524 UINT16 packet_len = 0;
525 struct supplicantData *suppData = priv->suppData;
526 pmlan_buffer newbuf = MNULL;
527 UINT8 intf_hr_len =
528 pm_fns->Hostsa_get_intf_hr_len(pm_fns->pmlan_private);
529
530 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
531
532 newbuf = pm_fns->hostsa_alloc_mlan_buffer(pm_fns->pmlan_adapter,
533 MLAN_TX_DATA_BUF_SIZE_2K, 0,
534 MOAL_MALLOC_BUFFER);
535 if (newbuf) {
536 newbuf->bss_index = pmbuf->bss_index;
537 newbuf->buf_type = pmbuf->buf_type;
538 newbuf->priority = pmbuf->priority;
539 newbuf->in_ts_sec = pmbuf->in_ts_sec;
540 newbuf->in_ts_usec = pmbuf->in_ts_usec;
541 newbuf->data_offset =
542 (sizeof(TxPD) + intf_hr_len + DMA_ALIGNMENT);
543 }
544
545 if (newbuf == NULL) {
546 PRINTM(MERROR, "GenerateGrpMsg2 newbuf=NULL\n");
547 return FAIL;
548 }
549
550 pTxEapol = (EAPOL_KeyMsg_Tx_t *)(newbuf->pbuf + newbuf->data_offset);
551
552 KeyMgmtSta_PrepareEAPOLFrame(priv, pTxEapol,
553 pRxEapol,
554 (t_u8 *)&suppData->localBssid,
555 (t_u8 *)&suppData->localStaAddr, NULL);
556
557 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(priv, pTxEapol,
558 pKeyMgmtInfoSta->
559 EAPOL_MIC_Key,
560 EAPOL_PROTOCOL_V1, 0);
561 // pBufDesc->isCB = 1;
562 // pBufDesc->freeCallback = keyMgmtKeyGroupTxDone;
563 keyMgmtKeyGroupTxDone(priv);
564
565 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
566 UpdateEAPOLWcbLenAndTransmit(priv, newbuf, packet_len);
567
568 PRINTM(MMSG, "LEAVE: %s\n", __FUNCTION__);
569 return SUCCESS;
570 }
571
572 BOOLEAN
KeyMgmtStaHsk_Recvd_PWKMsg1(phostsa_private priv,mlan_buffer * pmbuf,IEEEtypes_MacAddr_t * sa,IEEEtypes_MacAddr_t * da)573 KeyMgmtStaHsk_Recvd_PWKMsg1(phostsa_private priv, mlan_buffer *pmbuf,
574 IEEEtypes_MacAddr_t *sa, IEEEtypes_MacAddr_t *da)
575 {
576 EAPOL_KeyMsg_t *pKeyMsg = NULL;
577 struct supplicantData *suppData = priv->suppData;
578 keyMgmtInfoSta_t *pKeyMgmtInfoSta = &suppData->keyMgmtInfoSta;
579 UINT8 *pPmk;
580 BOOLEAN msgProcessed;
581 BOOLEAN genPwkMsg2;
582 BOOLEAN retval;
583 UINT32 uMaxRetry = 5; // MAX_SUPPLICANT_INIT_TIMEOUT
584
585 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
586
587 msgProcessed = FALSE;
588 genPwkMsg2 = TRUE;
589 retval = FALSE;
590
591 //#ifdef PSK_SUPPLICANT
592 /* Wait for supplicant data to be initialized, which will complete
593 * after set channel/DPD trainign is complete
594 */
595 while (uMaxRetry-- && (suppData->suppInitialized != TRUE)) {
596 // OSATaskSleep(1);
597 }
598 //#endif
599
600 pKeyMsg = GetKeyMsgNonceFromEAPOL(priv, pmbuf, pKeyMgmtInfoSta);
601 if (!pKeyMsg) {
602 PRINTM(MERROR, "KeyMgmtStaHsk_Recvd_PWKMsg1 pKeyMsg is NULL\n");
603 return FALSE;
604 }
605 #ifdef DOT11R
606 if (!msgProcessed &&
607 dot11r_is_ft_akm(&connPtr->suppData->customMIB_RSNConfig.AKM)) {
608 dot11r_process_pwk_msg1(connPtr,
609 sa,
610 da,
611 pKeyMgmtInfoSta->SNonce,
612 pKeyMgmtInfoSta->ANonce);
613
614 msgProcessed = TRUE;
615 retval = TRUE;
616 }
617 #endif
618 #ifdef PSK_SUPPLICANT_CCKM
619 if (!msgProcessed && ccx_is_cckm_enabled(connPtr)) {
620 retval = cckm_Recvd_PWKMsg1(connPtr,
621 sa,
622 da,
623 pEAPoLBufDesc,
624 pKeyMgmtInfoSta->SNonce,
625 (UINT8 *)connPtr->suppData->
626 hashSsId.SsId,
627 connPtr->suppData->hashSsId.Len);
628 genPwkMsg2 = FALSE;
629 msgProcessed = TRUE;
630 }
631 #endif
632
633 if (!msgProcessed
634 && supplicantAkmIsWpaWpa2(priv, &suppData->customMIB_RSNConfig.AKM))
635 {
636 if (supplicantAkmIsWpaWpa2Psk(priv,
637 &suppData->customMIB_RSNConfig.
638 AKM)) {
639 /* Selected AKM Suite is PSK based */
640 pPmk = pmkCacheFindPSK((void *)priv,
641 (UINT8 *)suppData->hashSsId.SsId,
642 suppData->hashSsId.Len);
643 } else {
644 pPmk = pmkCacheFindPMK(priv, &suppData->localBssid);
645 }
646
647 if (!pPmk) {
648 PRINTM(MERROR,
649 "KeyMgmtStaHsk_Recvd_PWKMsg1 pPmk is NULL\n");
650 return FALSE;
651 }
652
653 KeyMgmtSta_DeriveKeys(priv, pPmk,
654 (UINT8 *)da,
655 (UINT8 *)sa,
656 pKeyMgmtInfoSta->ANonce,
657 pKeyMgmtInfoSta->SNonce,
658 pKeyMgmtInfoSta->EAPOL_MIC_Key,
659 pKeyMgmtInfoSta->EAPOL_Encr_Key,
660 &pKeyMgmtInfoSta->newPWKey,
661 supplicantAkmUsesKdf(priv,
662 &suppData->
663 customMIB_RSNConfig.
664 AKM));
665
666 retval = TRUE;
667
668 /* PMKID checking not used by embedded supplicant.
669 ** Commenting out the code in case it needs to be
670 ** readded later.
671 */
672 #if 0
673 /* Need to check for PMKID response */
674 if (pKeyMsg->desc_type == 2) {
675 if (keyLen) {
676 KDE_t *pKde;
677
678 /* Parse PMKID though it's _not used_ now */
679 pKde = parseKeyKDE_DataType(pKeyMsg->key_data,
680 keyLen,
681 KDE_DATA_TYPE_PMKID);
682
683 if (pKde
684 && gcustomMIB_RSNConfig.pmkidValid
685 && memcmp(pKde->data,
686 gcustomMIB_RSNConfig.PMKID,
687 sizeof(gcustomMIB_RSNConfig.
688 PMKID))) {
689 /* PMKID could be invalid if generated based on an
690 ** old key. A new key should have been negotiated
691 ** We should regenerate PMKID and check it.
692 */
693 }
694 }
695 }
696 #endif
697 }
698
699 if (genPwkMsg2) {
700 /* construct Message 2 */
701 if (GeneratePWKMsg2(priv, pmbuf,
702 pKeyMgmtInfoSta->SNonce,
703 pKeyMgmtInfoSta->EAPOL_MIC_Key,
704 0) != SUCCESS) {
705 PRINTM(MERROR,
706 "KeyMgmtStaHsk_Recvd_PWKMsg1 GeneratePWKMsg2 Fail\n");
707 retval = FALSE;
708 }
709 }
710
711 if (retval == TRUE) {
712 #ifdef MIB_STATS
713 INC_MIB_STAT(connPtr, eapolSentFrmFwCnt);
714 #endif
715 updateApReplayCounter(priv, pKeyMgmtInfoSta,
716 (UINT8 *)pKeyMsg->replay_cnt);
717
718 pKeyMgmtInfoSta->RSNSecured = FALSE;
719 }
720
721 PRINTM(MMSG, "LEAVE: %s\n", __FUNCTION__);
722 return retval;
723 }
724
725 EAPOL_KeyMsg_t const *
KeyMgmtStaHsk_Recvd_PWKMsg3(phostsa_private priv,mlan_buffer * pmbuf)726 KeyMgmtStaHsk_Recvd_PWKMsg3(phostsa_private priv, mlan_buffer *pmbuf)
727 {
728 EAPOL_KeyMsg_t *pKeyMsg;
729 // cm_ConnectionInfo_t* connPtr = pEAPoLBufDesc->intf.connPtr;
730 struct supplicantData *suppData = priv->suppData;
731 keyMgmtInfoSta_t *pKeyMgmtInfoSta = &suppData->keyMgmtInfoSta;
732
733 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
734
735 #ifdef WAR_ROM_BUG50312_SIMUL_INFRA_WFD
736 pKeyMsg = patch_ProcessRxEAPOL_PwkMsg3(pEAPoLBufDesc, pKeyMgmtInfoSta);
737 #else
738 pKeyMsg = ProcessRxEAPOL_PwkMsg3(priv, pmbuf, pKeyMgmtInfoSta);
739 #endif
740 if (!pKeyMsg) {
741 PRINTM(MERROR, "KeyMgmtStaHsk_Recvd_PWKMsg3 pKeyMsg is NULL\n");
742 return NULL;
743 }
744
745 /* construct Message 4 */
746 if (GeneratePWKMsg4(priv, pmbuf,
747 pKeyMgmtInfoSta,
748 (pKeyMsg->desc_type == 2)) != SUCCESS) {
749 PRINTM(MERROR,
750 "KeyMgmtStaHsk_Recvd_PWKMsg3 GeneratePWKMsg4 Fail\n");
751 return pKeyMsg;
752 }
753 #ifdef MIB_STATS
754 INC_MIB_STAT(connPtr, eapolSentFrmFwCnt);
755 #endif
756
757 updateApReplayCounter(priv, pKeyMgmtInfoSta,
758 (UINT8 *)pKeyMsg->replay_cnt);
759
760 PRINTM(MMSG, "LEAVE: %s\n", __FUNCTION__);
761 return NULL;
762 }
763
764 EAPOL_KeyMsg_t const *
KeyMgmtStaHsk_Recvd_GrpMsg1(phostsa_private priv,mlan_buffer * pmbuf)765 KeyMgmtStaHsk_Recvd_GrpMsg1(phostsa_private priv, mlan_buffer *pmbuf)
766 {
767 EAPOL_KeyMsg_t *pKeyMsg;
768 struct supplicantData *suppData = priv->suppData;
769 keyMgmtInfoSta_t *pKeyMgmtInfoSta = &suppData->keyMgmtInfoSta;
770
771 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
772
773 #ifdef WAR_ROM_BUG50312_SIMUL_INFRA_WFD
774 pKeyMsg = patch_ProcessRxEAPOL_GrpMsg1(priv, pKeyMgmtInfoSta);
775 #else
776 pKeyMsg = ProcessRxEAPOL_GrpMsg1(priv, pmbuf, pKeyMgmtInfoSta);
777 #endif
778 if (!pKeyMsg) {
779 PRINTM(MERROR, "KeyMgmtStaHsk_Recvd_GrpMsg1 pKeyMsg is NULL\n");
780 return NULL;
781 }
782 /* construct Message Grp Msg2 */
783 if (GenerateGrpMsg2(priv, pmbuf, pKeyMgmtInfoSta) != SUCCESS) {
784 PRINTM(MERROR,
785 "KeyMgmtStaHsk_Recvd_GrpMsg1 GenerateGrpMsg2 Fail\n");
786 return NULL;
787 }
788 #ifdef MIB_STATS
789 INC_MIB_STAT(connPtr, eapolSentFrmFwCnt);
790 #endif
791
792 updateApReplayCounter(priv, pKeyMgmtInfoSta,
793 (UINT8 *)pKeyMsg->replay_cnt);
794
795 PRINTM(MMSG, "LEAVE: %s\n", __FUNCTION__);
796 return pKeyMsg;
797 }
798
799 void
ProcessKeyMgmtDataSta(phostsa_private priv,mlan_buffer * pmbuf,IEEEtypes_MacAddr_t * sa,IEEEtypes_MacAddr_t * da)800 ProcessKeyMgmtDataSta(phostsa_private priv, mlan_buffer *pmbuf,
801 IEEEtypes_MacAddr_t *sa, IEEEtypes_MacAddr_t *da)
802 {
803 UINT8 retry;
804 EAPOL_KeyMsg_t *pKeyMsg =
805 (EAPOL_KeyMsg_t *)(pmbuf->pbuf + pmbuf->data_offset +
806 sizeof(ether_hdr_t));
807
808 retry = 0;
809
810 if (pKeyMsg->key_info.KeyType) {
811 /* PWK */
812 if (pKeyMsg->key_info.KeyMIC) {
813 /* 3rd msg in seq */
814 KeyMgmtStaHsk_Recvd_PWKMsg3(priv, pmbuf);
815 } else {
816 while ((KeyMgmtStaHsk_Recvd_PWKMsg1(priv, pmbuf, sa, da)
817 == FALSE)
818 && (retry < PWK_MSG1_RETRIES)) {
819 /* Delay and retry Msg1 processing in case failure was
820 ** due to the host not having time to program a PMK
821 ** yet for 802.1x AKMPs
822 */
823 //hal_WaitInUs(100);
824 retry++;
825 }
826 //KeyMgmtStaHsk_Recvd_PWKMsg1(priv, pmbuf, sa, da);
827
828 }
829 } else {
830 /* GRP */
831 if (!KeyMgmtStaHsk_Recvd_GrpMsg1(priv, pmbuf)) {
832 #if defined(MEF_ENH) && defined(VISTA_802_11_DRIVER_INTERFACE)
833 hostsleep_initiate_wakeup_with_reason
834 (WOL_GRP_KEY_REFRESH_ERROR,
835 WOL_VACUOUS_PATTERN_ID);
836 #endif
837 }
838 }
839
840 }
841
842 #if 0
843 /*
844 ** This function send a MIC failure event to the AP
845 */
846 void
847 SendMICFailReport_sta(cm_ConnectionInfo_t * connPtr,
848 keyMgmtInfoSta_t *pKeyMgmtInfoSta, BOOLEAN isUnicast)
849 {
850 EAPOL_KeyMsg_Tx_t *pTxEapol;
851 UINT16 frameLen;
852 UINT32 int_sta;
853 BufferDesc_t *pBufDesc;
854
855 if (pKeyMgmtInfoSta->staCounterHi == 0xffffffff
856 && pKeyMgmtInfoSta->staCounterLo == 0xffffffff) {
857 KeyMgmtResetCounter(pKeyMgmtInfoSta);
858 return;
859 }
860
861 int_sta = os_if_save_EnterCriticalSection();
862
863 /* Since there is a MIC failure drop all packets in Tx queue. */
864 while ((pBufDesc = (BufferDesc_t *) getq(&wlan_data_q)) != NULL) {
865 /* Do nothing here. We are just dropping the packet
866 ** and releasing the queue.
867 */
868 mrvl_HandleTxDone(pBufDesc, 0);
869 }
870
871 os_if_save_ExitCriticalSection(int_sta);
872
873 pBufDesc = GetTxEAPOLBuffer(connPtr, &pTxEapol, NULL);
874
875 if (pBufDesc == NULL) {
876 return;
877 }
878 KeyMgmtSta_PrepareEAPOLMicErrFrame(pTxEapol,
879 isUnicast,
880 &connPtr->suppData->localBssid,
881 &connPtr->suppData->localStaAddr,
882 pKeyMgmtInfoSta);
883 SetEAPOLKeyDescTypeVersion(pTxEapol,
884 connPtr->suppData->customMIB_RSNConfig.
885 wpaType.wpa2,
886 supplicantAkmUsesKdf(&connPtr->suppData->
887 customMIB_RSNConfig.
888 AKM),
889 connPtr->suppData->customMIB_RSNConfig.
890 ucstCipher.ccmp);
891
892 if (pKeyMgmtInfoSta->staCounterLo++ == 0) {
893 pKeyMgmtInfoSta->staCounterHi++;
894 }
895
896 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(pTxEapol,
897 pKeyMgmtInfoSta->
898 EAPOL_MIC_Key,
899 EAPOL_PROTOCOL_V1, 0);
900
901 UpdateEAPOLWcbLenAndTransmit(pBufDesc, frameLen);
902 }
903 #endif
904
905 #ifdef WAR_ROM_BUG57216_QUIET_TIME_INTERVAL
906 /* This function assumes that argument state would be either
907 NO_MIC_FAILURE or FIRST_MIC_FAIL_IN_60_SEC
908 It must not be called with state othe than these two
909 */
910 #define MIC_ERROR_QUIET_TIME_INTERVAL 60000000 /* 60 sec */
911 #define MIC_ERROR_CHECK_TIME_INTERVAL 60000000
912
913 void
KeyMgmtSta_handleMICErr(MIC_Fail_State_e state,keyMgmtInfoSta_t * pKeyMgmtInfoSta,MicroTimerCallback_t callback,UINT8 flags)914 KeyMgmtSta_handleMICErr(MIC_Fail_State_e state,
915 keyMgmtInfoSta_t *pKeyMgmtInfoSta,
916 MicroTimerCallback_t callback, UINT8 flags)
917 {
918 UINT32 expiry;
919 UINT32 int_save = tx_interrupt_control(TX_INT_DISABLE);
920
921 if (state == NO_MIC_FAILURE) {
922 /* First MIC failure */
923 pKeyMgmtInfoSta->sta_MIC_Error.status =
924 FIRST_MIC_FAIL_IN_60_SEC;
925 expiry = MIC_ERROR_CHECK_TIME_INTERVAL;
926 } else {
927 /* Received 2 MIC failures within 60 sec. Do deauth from AP */
928 pKeyMgmtInfoSta->sta_MIC_Error.disableStaAsso = 1;
929 pKeyMgmtInfoSta->sta_MIC_Error.status =
930 SECOND_MIC_FAIL_IN_60_SEC;
931 pKeyMgmtInfoSta->apCounterHi = 0;
932 pKeyMgmtInfoSta->apCounterLo = 0;
933 expiry = MIC_ERROR_QUIET_TIME_INTERVAL;
934 }
935 tx_interrupt_control(int_save);
936 #if 0
937 microTimerStop(pKeyMgmtInfoSta->micTimer);
938
939 microTimerStart(callback,
940 (UINT32)pKeyMgmtInfoSta,
941 expiry, &pKeyMgmtInfoSta->micTimer, flags);
942 #endif
943 }
944 #endif
945
946 #if 0
947 void
948 supplicantMICCounterMeasureInvoke(cm_ConnectionInfo_t * connPtr,
949 BOOLEAN isUnicast)
950 {
951 MIC_Fail_State_e state;
952 keyMgmtInfoSta_t *pKeyMgmtInfoSta = &connPtr->suppData->keyMgmtInfoSta;
953
954 if (pKeyMgmtInfoSta->sta_MIC_Error.MICCounterMeasureEnabled) {
955 state = pKeyMgmtInfoSta->sta_MIC_Error.status;
956
957 /* Watchdog and clear any pending TX packets to ensure that
958 ** We are able to get a TX buffer
959 */
960 tx_watchdog_recovery();
961 SendMICFailReport_sta(connPtr, pKeyMgmtInfoSta, isUnicast);
962
963 switch (state) {
964 case NO_MIC_FAILURE:
965 /* Received 1st MIC failure */
966 /* Noneed to check if timer is active. It will not be active
967 ** cause this is the first state
968 */
969 KeyMgmtSta_handleMICErr(state,
970 pKeyMgmtInfoSta,
971 MicErrTimerExp_Sta,
972 MICRO_TIMER_FLAG_KILL_ON_PS_ENTRY);
973
974 connPtr->suppData->customMIB_RSNStats.
975 TKIPLocalMICFailures++;
976
977 break;
978
979 case FIRST_MIC_FAIL_IN_60_SEC:
980 /* Received 2 MIC failures within 60 sec. Do deauth from AP */
981 connPtr->suppData->customMIB_RSNStats.
982 TKIPCounterMeasuresInvoked++;
983
984 KeyMgmtSta_handleMICErr(state,
985 pKeyMgmtInfoSta,
986 MicErrTimerExp_Sta,
987 MICRO_TIMER_FLAG_KILL_ON_PS_ENTRY);
988
989 /* Is this really needed? */
990 pKeyMgmtInfoSta->connPtr = connPtr;
991
992 KeyMgmtSta_handleMICDeauthTimer(pKeyMgmtInfoSta,
993 DeauthDelayTimerExp_Sta,
994 DEAUTH_DELAY_TIME_INTERVAL,
995 MICRO_TIMER_FLAG_KILL_ON_PS_ENTRY);
996
997 break;
998
999 case SECOND_MIC_FAIL_IN_60_SEC:
1000 /*No need to do anything. Everything has been taken care of by
1001 ** the above state
1002 */
1003
1004 default:
1005 break;
1006 }
1007 }
1008 return;
1009 }
1010 #endif
1011 /*
1012 Start the key Management session
1013 */
1014 void
keyMgmtSta_StartSession(phostsa_private priv,IEEEtypes_MacAddr_t * pBssid,IEEEtypes_MacAddr_t * pStaAddr)1015 keyMgmtSta_StartSession(phostsa_private priv,
1016 IEEEtypes_MacAddr_t *pBssid,
1017 IEEEtypes_MacAddr_t *pStaAddr)
1018 {
1019 hostsa_util_fns *util_fns = &priv->util_fns;
1020 keyMgmtInfoSta_t *pKeyMgmtInfoSta = &priv->suppData->keyMgmtInfoSta;
1021
1022 //pKeyMgmtInfoSta->psapriv = priv;
1023
1024 memcpy(util_fns, &priv->suppData->localStaAddr,
1025 pStaAddr, sizeof(priv->suppData->localStaAddr));
1026 memcpy(util_fns, &priv->suppData->localBssid,
1027 pBssid, sizeof(priv->suppData->localBssid));
1028
1029 keyMgmtSta_StartSession_internal(priv, pKeyMgmtInfoSta,
1030 //keyMgmtStaRsnSecuredTimeoutHandler,
1031 RSNSECUREDTIMEOUT, 0); //MICRO_TIMER_FLAG_KILL_ON_PS_ENTRY);
1032
1033 }
1034
1035 void
supplicantClrEncryptKey(void * priv)1036 supplicantClrEncryptKey(void *priv)
1037 {
1038 phostsa_private psapriv = (phostsa_private)priv;
1039 hostsa_mlan_fns *pm_fns = NULL;
1040
1041 if (!psapriv)
1042 return;
1043
1044 pm_fns = &psapriv->mlan_fns;
1045 pm_fns->hostsa_clr_encrypt_key(psapriv->pmlan_private);
1046 }
1047
1048 UINT32
keyApi_UpdateKeyMaterial(void * priv,key_MgtMaterial_t * keyMgtData_p)1049 keyApi_UpdateKeyMaterial(void *priv, key_MgtMaterial_t *keyMgtData_p)
1050 {
1051 phostsa_private psapriv = (phostsa_private)priv;
1052 hostsa_util_fns *util_fns = &psapriv->util_fns;
1053 hostsa_mlan_fns *pm_fns = &psapriv->mlan_fns;
1054 //UINT8 wepKeyIndex;
1055 mlan_ds_encrypt_key encrypt_key;
1056 t_u8 bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1057
1058 memset(util_fns, &encrypt_key, 0, sizeof(mlan_ds_encrypt_key));
1059
1060 PRINTM(MMSG, "keyApi_UpdateKeyMaterial keyType=%x keyLen=%x\n",
1061 keyMgtData_p->keyType, keyMgtData_p->keyLen);
1062 switch (keyMgtData_p->keyType) {
1063 case KEY_TYPE_TKIP:
1064 case KEY_TYPE_AES:
1065 /* The Key Info definition for TKIP and AES is the same */
1066 if (keyMgtData_p->keyInfo & KEY_INFO_UNICAST) {
1067 /* Unicast Key */
1068 //SET_KEY_STATE_ENABLED(pwkey,
1069 // (keyMgtData_p->keyInfo
1070 // & KEY_INFO_ENABLED)? TRUE : FALSE);
1071 //pwkey->hdr.keyType = keyMgtData_p->keyType;
1072 //pwkey->hdr.keyDirection = KEY_DIRECTION_RXTX;
1073 //pwkey->hdr.keyLen = keyMgtData_p->keyLen;
1074
1075 //if (IS_KEY_STATE_ENABLED(pwkey))
1076 //{
1077 // ramHook_keyApiSta_setConnDataTrafficEnabled(connPtr, TRUE);
1078 // ramHook_keyApiSta_setConnCurPktTxEnabled(connPtr, TRUE);
1079 // SET_KEY_STATE_FORCE_EAPOL_UNENCRYPTED(pwkey, TRUE);
1080 // }
1081 encrypt_key.key_flags |= KEY_FLAG_SET_TX_KEY;
1082 encrypt_key.key_len = keyMgtData_p->keyLen;
1083 memcpy(util_fns, encrypt_key.mac_addr,
1084 psapriv->suppData->localBssid, MAC_ADDR_SIZE);
1085
1086 /* The Key Material is different */
1087 if (keyMgtData_p->keyLen &&
1088 (keyMgtData_p->keyType == KEY_TYPE_TKIP)) {
1089 /* Update key if included */
1090 memcpy(util_fns,
1091 (void *)encrypt_key.key_material,
1092 (const void *)keyMgtData_p->keyEncypt.
1093 TKIP.key, TK_SIZE);
1094 memcpy(util_fns,
1095 (void *)&encrypt_key.
1096 key_material[TK_SIZE],
1097 (const void *)keyMgtData_p->keyEncypt.
1098 TKIP.txMicKey, MIC_KEY_SIZE);
1099 memcpy(util_fns,
1100 (void *)&encrypt_key.
1101 key_material[TK_SIZE + MIC_KEY_SIZE],
1102 (const void *)keyMgtData_p->keyEncypt.
1103 TKIP.rxMicKey, MIC_KEY_SIZE);
1104 } else if (keyMgtData_p->keyLen &&
1105 (keyMgtData_p->keyType == KEY_TYPE_AES)) {
1106 /* Update key if included */
1107 memcpy(util_fns,
1108 (uint8 *)encrypt_key.key_material,
1109 (uint8 *)keyMgtData_p->keyEncypt.AES.key,
1110 TK_SIZE);
1111
1112 /* duplicate to group key,
1113 * for adhoc aes to use.
1114 */
1115 //if (!IS_KEY_STATE_ENABLED(gwkey))
1116 // {
1117 /* Multicast Key */
1118 // SET_KEY_STATE_ENABLED(gwkey,
1119 // (keyMgtData_p->keyInfo
1120 // & KEY_INFO_ENABLED) ? TRUE : FALSE);
1121 // gwkey->hdr.keyType = keyMgtData_p->keyType;
1122 // gwkey->hdr.keyDirection = KEY_DIRECTION_RXTX;
1123 // gwkey->hdr.keyLen = keyMgtData_p->keyLen;
1124 // if (IS_KEY_STATE_ENABLED(gwkey))
1125 // {
1126 // gwkey->ckd.tkip_aes.loReplayCounter16 = 0;
1127 // gwkey->ckd.tkip_aes.hiReplayCounter32 = 0xffffffff;
1128 // }
1129 // memcpy((uint8*)gwkey->ckd.tkip_aes.key,
1130 // (uint8*)keyMgtData_p->keyEncypt.AES.key,
1131 // TK_SIZE);
1132 // }
1133 }
1134 }
1135
1136 if (keyMgtData_p->keyInfo & KEY_INFO_MULTICAST) {
1137 /* Multicast Key */
1138 //SET_KEY_STATE_ENABLED(gwkey,
1139 // (keyMgtData_p->
1140 // keyInfo & KEY_INFO_ENABLED) ? TRUE :
1141 // FALSE);
1142 //gwkey->hdr.keyType = keyMgtData_p->keyType;
1143 //gwkey->hdr.keyDirection = KEY_DIRECTION_RXTX;
1144 //gwkey->hdr.keyLen = keyMgtData_p->keyLen;
1145 //if (IS_KEY_STATE_ENABLED(gwkey))
1146 //{
1147 // gwkey->ckd.tkip_aes.loReplayCounter16 = 0;
1148 // gwkey->ckd.tkip_aes.hiReplayCounter32 = 0xffffffff;
1149
1150 // if (!IS_KEY_STATE_ENABLED(pwkey))
1151 // {
1152 // gwkey->ckd.tkip_aes.txIV32 = 0x0;
1153 // gwkey->ckd.tkip_aes.txIV16 = 0x1;
1154 // ramHook_keyApiSta_setConnDataTrafficEnabled(connPtr, TRUE);
1155 // ramHook_keyApiSta_setConnCurPktTxEnabled(connPtr, TRUE);
1156 // }
1157 // }
1158 encrypt_key.key_flags |= KEY_FLAG_GROUP_KEY;
1159 encrypt_key.key_len = keyMgtData_p->keyLen;
1160 memcpy(util_fns, encrypt_key.mac_addr, bcast_addr,
1161 MAC_ADDR_SIZE);
1162
1163 if (keyMgtData_p->keyLen &&
1164 (keyMgtData_p->keyType == KEY_TYPE_TKIP)) {
1165 /* Update key if included */
1166 memcpy(util_fns,
1167 (void *)encrypt_key.key_material,
1168 (const void *)keyMgtData_p->keyEncypt.
1169 TKIP.key, TK_SIZE);
1170 memcpy(util_fns,
1171 (void *)&encrypt_key.
1172 key_material[TK_SIZE],
1173 (const void *)keyMgtData_p->keyEncypt.
1174 TKIP.txMicKey, MIC_KEY_SIZE);
1175 memcpy(util_fns,
1176 (void *)&encrypt_key.
1177 key_material[TK_SIZE + MIC_KEY_SIZE],
1178 (const void *)keyMgtData_p->keyEncypt.
1179 TKIP.rxMicKey, MIC_KEY_SIZE);
1180 } else if (keyMgtData_p->keyLen &&
1181 (keyMgtData_p->keyType == KEY_TYPE_AES)) {
1182 /* Update key if included */
1183 memcpy(util_fns,
1184 (uint8 *)encrypt_key.key_material,
1185 (uint8 *)keyMgtData_p->keyEncypt.AES.key,
1186 TK_SIZE);
1187 }
1188 }
1189 /**set pn 0*/
1190 memset(util_fns, encrypt_key.pn, 0, sizeof(encrypt_key.pn));
1191 /**key flag*/
1192 encrypt_key.key_flags |= KEY_FLAG_RX_SEQ_VALID;
1193
1194 //ramHook_keyApi_PalladiumHook1(connPtr);
1195 /**set command to fw update key*/
1196 pm_fns->hostsa_set_encrypt_key((void *)psapriv->pmlan_private,
1197 &encrypt_key);
1198
1199 break;
1200
1201 #ifndef WAR_ROM_BUG54733_PMF_SUPPORT
1202 case KEY_TYPE_AES_CMAC:
1203 if ( /*NULL != igwkey && */
1204 (keyMgtData_p->keyInfo & KEY_INFO_MULTICAST_IGTK)) {
1205 /* Multicast Key */
1206 //SET_KEY_STATE_ENABLED(igwkey,
1207 // (keyMgtData_p->keyInfo
1208 // & KEY_INFO_ENABLED) ? TRUE : FALSE);
1209 //igwkey->hdr.keyType = keyMgtData_p->keyType;
1210 //igwkey->hdr.keyDirection = KEY_DIRECTION_RXTX;
1211 //igwkey->hdr.keyLen = keyMgtData_p->keyLen;
1212 if (keyMgtData_p->keyLen) {
1213 /* Update IPN if included */
1214 //memcpy((UINT8 *)&igwkey->ckd.tkip_aes.loReplayCounter16,
1215 // (UINT8 *)&keyMgtData_p->keyEncypt.iGTK.ipn[0],
1216 // sizeof(igwkey->ckd.tkip_aes.loReplayCounter16));
1217
1218 //memcpy((UINT8 *)&igwkey->ckd.tkip_aes.hiReplayCounter32,
1219 // (UINT8 *)&keyMgtData_p->keyEncypt.iGTK.ipn[2],
1220 // sizeof(igwkey->ckd.tkip_aes.hiReplayCounter32));
1221
1222 /* Update key if included */
1223 //memcpy((UINT8 *)igwkey->ckd.tkip_aes.key,
1224 // (UINT8 *)keyMgtData_p->keyEncypt.iGTK.key,
1225 // CRYPTO_AES_CMAC_KEY_LEN);
1226 memcpy(util_fns,
1227 (uint8 *)encrypt_key.key_material,
1228 (UINT8 *)keyMgtData_p->keyEncypt.iGTK.
1229 key, CRYPTO_AES_CMAC_KEY_LEN);
1230 }
1231 /**set pn 0*/
1232 memset(util_fns, encrypt_key.pn, 0,
1233 sizeof(encrypt_key.pn));
1234 /**key flag*/
1235 encrypt_key.key_flags |= KEY_FLAG_RX_SEQ_VALID;
1236
1237 //ramHook_keyApi_PalladiumHook1(connPtr);
1238 /**set command to fw update key*/
1239 pm_fns->hostsa_set_encrypt_key(psapriv->pmlan_private,
1240 &encrypt_key);
1241 }
1242 break;
1243 #endif
1244 }
1245
1246 return 0;
1247 }
1248
1249 void
FillKeyMaterialStruct(phostsa_private priv,UINT16 key_len,UINT8 isPairwise,KeyData_t * pKey)1250 FillKeyMaterialStruct(phostsa_private priv,
1251 UINT16 key_len, UINT8 isPairwise, KeyData_t *pKey)
1252 {
1253 key_MgtMaterial_t keyMgtData;
1254
1255 #ifdef MIB_STATS
1256 if (isPairwise) {
1257 INC_MIB_STAT(connPtr, PTKSentFrmESUPPCnt);
1258 } else {
1259 INC_MIB_STAT(connPtr, GTKSentFrmESUPPCnt);
1260 }
1261 #endif
1262
1263 FillKeyMaterialStruct_internal(priv, &keyMgtData, key_len, isPairwise,
1264 pKey);
1265 keyApi_UpdateKeyMaterial(priv, &keyMgtData);
1266 }
1267
1268 void
FillGrpKeyMaterialStruct(phostsa_private priv,UINT16 keyType,UINT8 * pn,UINT8 keyIdx,UINT8 keyLen,KeyData_t * pKey)1269 FillGrpKeyMaterialStruct(phostsa_private priv,
1270 UINT16 keyType,
1271 UINT8 *pn, UINT8 keyIdx, UINT8 keyLen, KeyData_t *pKey)
1272 {
1273 hostsa_util_fns *util_fns = &priv->util_fns;
1274 key_MgtMaterial_t keyMgtData;
1275
1276 if (keyType == KDE_DATA_TYPE_IGTK) {
1277 memset(util_fns, (void *)&keyMgtData, 0x00, sizeof(keyMgtData));
1278
1279 keyMgtData.keyType = KEY_TYPE_AES_CMAC;
1280 keyMgtData.keyInfo = KEY_INFO_MULTICAST_IGTK | KEY_INFO_ENABLED;
1281 keyMgtData.keyLen = keyLen;
1282
1283 memcpy(util_fns, keyMgtData.keyEncypt.iGTK.ipn, pn,
1284 CRYPTO_AES_CMAC_IPN_LEN);
1285 memcpy(util_fns, keyMgtData.keyEncypt.iGTK.key, pKey->Key,
1286 keyLen);
1287 } else {
1288 FillKeyMaterialStruct_internal(priv, &keyMgtData, keyLen, FALSE,
1289 pKey);
1290 }
1291
1292 keyApi_UpdateKeyMaterial(priv, &keyMgtData);
1293 }
1294
1295 void
supplicantInitSession(void * priv,t_u8 * pSsid,t_u16 len,t_u8 * pBssid,t_u8 * pStaAddr)1296 supplicantInitSession(void *priv,
1297 t_u8 *pSsid, t_u16 len, t_u8 *pBssid, t_u8 *pStaAddr)
1298 {
1299 phostsa_private psapriv = (phostsa_private)priv;
1300 hostsa_util_fns *util_fns = &psapriv->util_fns;
1301
1302 if (supplicantIsEnabled((void *)psapriv)) {
1303 KeyMgmtInitSta(psapriv);
1304 memcpy(util_fns, (void *)psapriv->suppData->hashSsId.SsId,
1305 pSsid, len);
1306 psapriv->suppData->hashSsId.Len = len;
1307 keyMgmtSta_StartSession(psapriv, (IEEEtypes_MacAddr_t *)pBssid,
1308 (IEEEtypes_MacAddr_t *)pStaAddr);
1309 psapriv->suppData->suppInitialized = TRUE;
1310 psapriv->gtk_installed = 0;
1311 }
1312 }
1313
1314 UINT8
supplicantIsCounterMeasuresActive(phostsa_private priv)1315 supplicantIsCounterMeasuresActive(phostsa_private priv)
1316 {
1317 return priv->suppData->keyMgmtInfoSta.sta_MIC_Error.disableStaAsso;
1318 }
1319
1320 //#endif
1321
1322 void
init_customApp_mibs(phostsa_private priv,supplicantData_t * suppData)1323 init_customApp_mibs(phostsa_private priv, supplicantData_t *suppData)
1324 {
1325 hostsa_util_fns *util_fns = &priv->util_fns;
1326
1327 memset(util_fns, &suppData->customMIB_RSNStats,
1328 0x00, sizeof(suppData->customMIB_RSNStats));
1329 memset(util_fns, &suppData->customMIB_RSNConfig,
1330 0x00, sizeof(suppData->customMIB_RSNConfig));
1331 /* keep noRsn = 1 as default setting */
1332 suppData->customMIB_RSNConfig.wpaType.noRsn = 1;
1333
1334 }
1335
1336 SecurityMode_t
supplicantCurrentSecurityMode(phostsa_private priv)1337 supplicantCurrentSecurityMode(phostsa_private priv)
1338 {
1339 return (priv->suppData->customMIB_RSNConfig.wpaType);
1340 }
1341
1342 AkmSuite_t *
supplicantCurrentAkmSuite(phostsa_private priv)1343 supplicantCurrentAkmSuite(phostsa_private priv)
1344 {
1345 return &priv->suppData->customMIB_RSNConfig.AKM;
1346 }
1347
1348 //#pragma arm section code = ".wlandatapathcode"
1349 t_u8
supplicantIsEnabled(void * priv)1350 supplicantIsEnabled(void *priv)
1351 {
1352 phostsa_private psapriv = (phostsa_private)priv;
1353
1354 if (!psapriv || psapriv->suppData == NULL) {
1355 return 0;
1356 }
1357
1358 return (psapriv->suppData->customMIB_RSNConfig.RSNEnabled);
1359 }
1360
1361 //#pragma arm section code
1362
1363 void
supplicantDisable(void * priv)1364 supplicantDisable(void *priv)
1365 {
1366 phostsa_private psapriv = (phostsa_private)priv;
1367
1368 if (!supplicantIsEnabled((void *)psapriv)) {
1369 return;
1370 }
1371 psapriv->suppData->customMIB_RSNConfig.RSNEnabled = 0;
1372 init_customApp_mibs(psapriv, psapriv->suppData);
1373
1374 PRINTM(MMSG, "supplicantDisable RSNEnabled=%x\n",
1375 psapriv->suppData->customMIB_RSNConfig.RSNEnabled);
1376 }
1377
1378 void
supplicantQueryPassphraseAndEnable(void * priv,t_u8 * pbuf)1379 supplicantQueryPassphraseAndEnable(void *priv, t_u8 *pbuf)
1380 {
1381 phostsa_private psapriv = (phostsa_private)priv;
1382 pmkElement_t *pPMKElement = MNULL;
1383 mlan_ssid_bssid *ssid_bssid = (mlan_ssid_bssid *)pbuf;
1384 mlan_802_11_ssid *pssid = &ssid_bssid->ssid;
1385
1386 if (!psapriv || psapriv->suppData == NULL)
1387 return;
1388 if (!ssid_bssid)
1389 return;
1390 if (!pssid->ssid_len)
1391 return;
1392 /* extract the PSK from the cache entry */
1393 pPMKElement =
1394 pmkCacheFindPSKElement((void *)psapriv, pssid->ssid,
1395 pssid->ssid_len);
1396 if (pPMKElement)
1397 psapriv->suppData->customMIB_RSNConfig.RSNEnabled = 1;
1398 else
1399 psapriv->suppData->customMIB_RSNConfig.RSNEnabled = 0;
1400
1401 PRINTM(MMSG,
1402 "supplicantQueryPassphraseAndEnable RSNEnabled=%x ssid=%s\n",
1403 psapriv->suppData->customMIB_RSNConfig.RSNEnabled, pssid->ssid);
1404 }
1405
1406 void
supplicantSetAssocRsn(phostsa_private priv,SecurityMode_t wpaType,Cipher_t * pMcstCipher,Cipher_t * pUcstCipher,AkmSuite_t * pAkm,IEEEtypes_RSNCapability_t * pRsnCap,Cipher_t * pGrpMgmtCipher)1407 supplicantSetAssocRsn(phostsa_private priv,
1408 SecurityMode_t wpaType,
1409 Cipher_t *pMcstCipher,
1410 Cipher_t *pUcstCipher,
1411 AkmSuite_t *pAkm,
1412 IEEEtypes_RSNCapability_t *pRsnCap,
1413 Cipher_t *pGrpMgmtCipher)
1414 {
1415 hostsa_util_fns *util_fns = &priv->util_fns;
1416 IEEEtypes_RSNCapability_t rsnCap;
1417
1418 if (pRsnCap == NULL) {
1419 /* It is being added as an IOT workaround for APs that
1420 * do not properly handle association requests that omit
1421 * the RSN Capability field in the RSN IE
1422 */
1423 memset(util_fns, &rsnCap, 0x00, sizeof(rsnCap));
1424 pRsnCap = &rsnCap;
1425 }
1426
1427 supplicantSetAssocRsn_internal(priv,
1428 &priv->suppData->customMIB_RSNConfig,
1429 &priv->suppData->currParams,
1430 wpaType,
1431 pMcstCipher,
1432 pUcstCipher,
1433 pAkm, pRsnCap, pGrpMgmtCipher);
1434 }
1435
1436 UINT16
keyMgmtFormatWpaRsnIe(phostsa_private priv,UINT8 * pos,IEEEtypes_MacAddr_t * pBssid,IEEEtypes_MacAddr_t * pStaAddr,UINT8 * pPmkid,BOOLEAN addPmkid)1437 keyMgmtFormatWpaRsnIe(phostsa_private priv,
1438 UINT8 *pos,
1439 IEEEtypes_MacAddr_t *pBssid,
1440 IEEEtypes_MacAddr_t *pStaAddr,
1441 UINT8 *pPmkid, BOOLEAN addPmkid)
1442 {
1443 struct supplicantData *suppData = priv->suppData;
1444
1445 return keyMgmtFormatWpaRsnIe_internal(priv,
1446 &suppData->customMIB_RSNConfig,
1447 pos,
1448 pBssid,
1449 pStaAddr, pPmkid, addPmkid);
1450 }
1451
1452 static void
install_wpa_none_keys(phostsa_private priv,UINT8 type,UINT8 unicast)1453 install_wpa_none_keys(phostsa_private priv, UINT8 type, UINT8 unicast)
1454 {
1455 UINT8 *pPMK;
1456 key_MgtMaterial_t keyMgtData;
1457
1458 pPMK = pmkCacheFindPSK((void *)priv,
1459 (UINT8 *)priv->suppData->hashSsId.SsId,
1460 priv->suppData->hashSsId.Len);
1461 if (pPMK == NULL) {
1462 return;
1463 }
1464
1465 install_wpa_none_keys_internal(priv, &keyMgtData, pPMK, type, unicast);
1466
1467 keyApi_UpdateKeyMaterial(priv, &keyMgtData);
1468
1469 /* there's no timer or other to initialize */
1470 KeyMgmtInitSta(priv);
1471 priv->suppData->keyMgmtInfoSta.RSNSecured = TRUE;
1472 }
1473
1474 void
supplicantInstallWpaNoneKeys(phostsa_private priv)1475 supplicantInstallWpaNoneKeys(phostsa_private priv)
1476 {
1477 if (priv->suppData->customMIB_RSNConfig.RSNEnabled
1478 && priv->suppData->customMIB_RSNConfig.wpaType.wpaNone) {
1479 install_wpa_none_keys(priv,
1480 priv->suppData->customMIB_RSNConfig.
1481 mcstCipher.ccmp, 0);
1482 install_wpa_none_keys(priv,
1483 priv->suppData->customMIB_RSNConfig.
1484 mcstCipher.ccmp, 1);
1485 }
1486 }
1487
1488 void
supplicantSetProfile(phostsa_private priv,SecurityMode_t wpaType,Cipher_t mcstCipher,Cipher_t ucstCipher)1489 supplicantSetProfile(phostsa_private priv,
1490 SecurityMode_t wpaType,
1491 Cipher_t mcstCipher, Cipher_t ucstCipher)
1492 {
1493 priv->suppData->currParams.wpaType = wpaType;
1494 priv->suppData->currParams.mcstCipher = mcstCipher;
1495 priv->suppData->currParams.ucstCipher = ucstCipher;
1496 }
1497
1498 void
supplicantGetProfile(phostsa_private priv,SecurityMode_t * pWpaType,Cipher_t * pMcstCipher,Cipher_t * pUcstCipher)1499 supplicantGetProfile(phostsa_private priv,
1500 SecurityMode_t *pWpaType,
1501 Cipher_t *pMcstCipher, Cipher_t *pUcstCipher)
1502 {
1503 *pWpaType = priv->suppData->currParams.wpaType;
1504 *pMcstCipher = priv->suppData->currParams.mcstCipher;
1505 *pUcstCipher = priv->suppData->currParams.ucstCipher;
1506 }
1507
1508 void
supplicantGetProfileCurrent(phostsa_private priv,SecurityMode_t * pWpaType,Cipher_t * pMcstCipher,Cipher_t * pUcstCipher)1509 supplicantGetProfileCurrent(phostsa_private priv,
1510 SecurityMode_t *pWpaType,
1511 Cipher_t *pMcstCipher, Cipher_t *pUcstCipher)
1512 {
1513 *pWpaType = priv->suppData->customMIB_RSNConfig.wpaType;
1514 *pMcstCipher = priv->suppData->customMIB_RSNConfig.mcstCipher;
1515 *pUcstCipher = priv->suppData->customMIB_RSNConfig.ucstCipher;
1516 }
1517
1518 void
supplicantInit(void * priv,supplicantData_t * suppData)1519 supplicantInit(void *priv, supplicantData_t *suppData)
1520 {
1521 phostsa_private psapriv = (phostsa_private)priv;
1522 hostsa_util_fns *util_fns = &psapriv->util_fns;
1523
1524 init_customApp_mibs(priv, suppData);
1525
1526 memset(util_fns, &suppData->currParams, 0xff, sizeof(SecurityParams_t));
1527 memset(util_fns, &suppData->keyMgmtInfoSta, 0,
1528 sizeof(keyMgmtInfoSta_t));
1529 suppData->keyMgmtInfoSta.sta_MIC_Error.disableStaAsso = 0;
1530 suppData->keyMgmtInfoSta.sta_MIC_Error.MICCounterMeasureEnabled = 1;
1531 suppData->keyMgmtInfoSta.sta_MIC_Error.status = NO_MIC_FAILURE;
1532 KeyMgmtResetCounter(&suppData->keyMgmtInfoSta);
1533 }
1534
1535 void
supplicantStopSessionTimer(void * priv)1536 supplicantStopSessionTimer(void *priv)
1537 {
1538 phostsa_private psapriv = (phostsa_private)priv;
1539 hostsa_util_fns *util_fns = NULL;
1540
1541 if (!psapriv || psapriv->suppData == NULL) {
1542 return;
1543 }
1544
1545 util_fns = &psapriv->util_fns;
1546 if (psapriv->suppData->keyMgmtInfoSta.rsnTimer) {
1547 util_fns->moal_stop_timer(util_fns->pmoal_handle,
1548 psapriv->suppData->keyMgmtInfoSta.
1549 rsnTimer);
1550 //priv->suppData->keyMgmtInfoSta.rsnTimer = 0;
1551 }
1552 }
1553
1554 void
supplicantSmeResetNotification(phostsa_private priv)1555 supplicantSmeResetNotification(phostsa_private priv)
1556 {
1557 supplicantStopSessionTimer(priv);
1558 }
1559
1560 UINT16
keyMgmtGetKeySize(phostsa_private priv,UINT8 isPairwise)1561 keyMgmtGetKeySize(phostsa_private priv, UINT8 isPairwise)
1562 {
1563 return keyMgmtGetKeySize_internal(&priv->suppData->customMIB_RSNConfig,
1564 isPairwise);
1565 }
1566
1567 void
keyMgmtSetMICKey(phostsa_private priv,UINT8 * pKey)1568 keyMgmtSetMICKey(phostsa_private priv, UINT8 *pKey)
1569 {
1570 hostsa_util_fns *util_fns = &priv->util_fns;
1571
1572 memcpy(util_fns, priv->suppData->keyMgmtInfoSta.EAPOL_MIC_Key,
1573 pKey, sizeof(priv->suppData->keyMgmtInfoSta.EAPOL_MIC_Key));
1574 }
1575
1576 UINT8 *
keyMgmtGetMICKey(phostsa_private priv)1577 keyMgmtGetMICKey(phostsa_private priv)
1578 {
1579 return (priv->suppData->keyMgmtInfoSta.EAPOL_MIC_Key);
1580 }
1581
1582 void
keyMgmtSetEAPOLEncrKey(phostsa_private priv,UINT8 * pKey)1583 keyMgmtSetEAPOLEncrKey(phostsa_private priv, UINT8 *pKey)
1584 {
1585 hostsa_util_fns *util_fns = &priv->util_fns;
1586
1587 memcpy(util_fns, priv->suppData->keyMgmtInfoSta.EAPOL_Encr_Key,
1588 pKey, sizeof(priv->suppData->keyMgmtInfoSta.EAPOL_Encr_Key));
1589 }
1590
1591 void
keyMgmtSetTemporalKeyOnly(phostsa_private priv,UINT8 * pTk)1592 keyMgmtSetTemporalKeyOnly(phostsa_private priv, UINT8 *pTk)
1593 {
1594 hostsa_util_fns *util_fns = &priv->util_fns;
1595
1596 memcpy(util_fns, &priv->suppData->keyMgmtInfoSta.newPWKey.Key,
1597 pTk, sizeof(priv->suppData->keyMgmtInfoSta.newPWKey.Key));
1598 }
1599
1600 UINT8 *
keyMgmtGetEAPOLEncrKey(phostsa_private priv)1601 keyMgmtGetEAPOLEncrKey(phostsa_private priv)
1602 {
1603 return (priv->suppData->keyMgmtInfoSta.EAPOL_Encr_Key);
1604 }
1605
1606 void
keyMgmtSetPairwiseKey(phostsa_private priv,KeyData_t * pKey)1607 keyMgmtSetPairwiseKey(phostsa_private priv, KeyData_t *pKey)
1608 {
1609 hostsa_util_fns *util_fns = &priv->util_fns;
1610
1611 memcpy(util_fns, &priv->suppData->keyMgmtInfoSta.newPWKey,
1612 pKey, sizeof(priv->suppData->keyMgmtInfoSta.newPWKey));
1613 }
1614
1615 void
keyMgmtSetGroupKey(phostsa_private priv,KeyData_t * pKey)1616 keyMgmtSetGroupKey(phostsa_private priv, KeyData_t *pKey)
1617 {
1618 hostsa_util_fns *util_fns = &priv->util_fns;
1619
1620 memcpy(util_fns, &priv->suppData->keyMgmtInfoSta.GRKey,
1621 pKey, sizeof(priv->suppData->keyMgmtInfoSta.GRKey));
1622
1623 FillKeyMaterialStruct(priv,
1624 keyMgmtGetKeySize(priv, FALSE), FALSE, pKey);
1625 }
1626
1627 void
keyMgmtSetGtk(phostsa_private priv,IEEEtypes_GtkElement_t * pGtk,UINT8 * pKek)1628 keyMgmtSetGtk(phostsa_private priv, IEEEtypes_GtkElement_t * pGtk, UINT8 *pKek)
1629 {
1630 hostsa_util_fns *util_fns = &priv->util_fns;
1631 UINT8 encrKeyLen;
1632
1633 /* Determine the encrypted key field length from the IE length */
1634 encrKeyLen = pGtk->Len - (sizeof(pGtk->KeyInfo) +
1635 sizeof(pGtk->KeyLen) + sizeof(pGtk->RSC));
1636
1637 MRVL_AesUnWrap(pKek,
1638 2,
1639 encrKeyLen / 8 - 1,
1640 (UINT8 *)pGtk->Key, NULL, (UINT8 *)pGtk->Key);
1641
1642 memcpy(util_fns, &priv->suppData->keyMgmtInfoSta.GRKey.Key,
1643 (UINT8 *)pGtk->Key,
1644 sizeof(priv->suppData->keyMgmtInfoSta.GRKey.Key));
1645
1646 FillGrpKeyMaterialStruct(priv,
1647 KDE_DATA_TYPE_GTK,
1648 pGtk->RSC,
1649 pGtk->KeyInfo.KeyId,
1650 pGtk->KeyLen,
1651 &priv->suppData->keyMgmtInfoSta.GRKey);
1652 }
1653
1654 void
keyMgmtSetIGtk(phostsa_private priv,keyMgmtInfoSta_t * pKeyMgmtInfoSta,IGtkKde_t * pIGtkKde,UINT8 iGtkKdeLen)1655 keyMgmtSetIGtk(phostsa_private priv, keyMgmtInfoSta_t *pKeyMgmtInfoSta,
1656 IGtkKde_t *pIGtkKde, UINT8 iGtkKdeLen)
1657 {
1658 hostsa_util_fns *util_fns = &priv->util_fns;
1659 UINT8 iGtkLen;
1660
1661 iGtkLen = iGtkKdeLen - 12; /* OUI + dataType + keyId + IPN = 12 bytes */
1662
1663 memcpy(util_fns, &pKeyMgmtInfoSta->IGtk.Key,
1664 (UINT8 *)pIGtkKde->IGtk,
1665 MIN(sizeof(pKeyMgmtInfoSta->IGtk.Key), iGtkLen));
1666
1667 FillGrpKeyMaterialStruct(priv,
1668 KDE_DATA_TYPE_IGTK,
1669 pIGtkKde->IPN,
1670 pIGtkKde->keyId[0],
1671 iGtkLen, &pKeyMgmtInfoSta->IGtk);
1672
1673 }
1674
1675 UINT8 *
keyMgmtGetIGtk(phostsa_private priv)1676 keyMgmtGetIGtk(phostsa_private priv)
1677 {
1678 return (priv->suppData->keyMgmtInfoSta.IGtk.Key);
1679 }
1680
1681 void
keyMgmtPlumbPairwiseKey(phostsa_private priv)1682 keyMgmtPlumbPairwiseKey(phostsa_private priv)
1683 {
1684 hostsa_util_fns *util_fns = &priv->util_fns;
1685
1686 memcpy(util_fns, &priv->suppData->keyMgmtInfoSta.PWKey,
1687 &priv->suppData->keyMgmtInfoSta.newPWKey,
1688 sizeof(priv->suppData->keyMgmtInfoSta.PWKey));
1689
1690 FillKeyMaterialStruct(priv,
1691 keyMgmtGetKeySize(priv, TRUE),
1692 TRUE, &priv->suppData->keyMgmtInfoSta.PWKey);
1693 }
1694
1695 #if 0
1696 #pragma arm section code = ".wlandatapathcode"
1697 void
1698 keyMgmtSuccessfulDecryptNotify(cm_ConnectionInfo_t * connPtr,
1699 cipher_key_t *pRxCipherKey)
1700 {
1701 if (supplicantIsEnabled(connPtr)) {
1702 connPtr->suppData->keyMgmtInfoSta.pRxDecryptKey = pRxCipherKey;
1703
1704 if (connPtr->suppData->keyMgmtInfoSta.pRxDecryptKey &&
1705 (!connPtr->suppData->customMIB_RSNConfig.RSNEnabled ||
1706 (connPtr->suppData->customMIB_RSNConfig.RSNEnabled &&
1707 connPtr->suppData->keyMgmtInfoSta.pwkHandshakeComplete)))
1708 {
1709 SET_KEY_STATE_FORCE_EAPOL_UNENCRYPTED(connPtr->
1710 suppData->
1711 keyMgmtInfoSta.
1712 pRxDecryptKey,
1713 FALSE);
1714 }
1715 } else {
1716 if (pRxCipherKey &&
1717 (!connPtr->cmFlags.RSNEnabled ||
1718 (connPtr->cmFlags.RSNEnabled &&
1719 connPtr->cmFlags.gDataTrafficEnabled))) {
1720 SET_KEY_STATE_FORCE_EAPOL_UNENCRYPTED(pRxCipherKey,
1721 FALSE);
1722 }
1723 }
1724 }
1725
1726 #pragma arm section code
1727 #endif
1728 static void
keyMgmtKeyGroupTxDone(phostsa_private priv)1729 keyMgmtKeyGroupTxDone(phostsa_private priv)
1730 {
1731 if (priv->gtk_installed)
1732 return;
1733 /*
1734 ** if (!pBufDesc || (pBufDesc->rsvd & 0x00FF == 0))
1735 **
1736 ** Removed check to verify the 4th message was a success. If we
1737 ** miss the ACK from the 4th(WPA2)/2nd(WPA) message, but the AP
1738 ** received it, then it won't retry and we will be stuck waiting for
1739 ** a session timeout.
1740 **
1741 ** Could add back later if we retry the message in case of TX failure.
1742 */
1743 FillKeyMaterialStruct(priv,
1744 keyMgmtGetKeySize(priv, FALSE),
1745 FALSE, &priv->suppData->keyMgmtInfoSta.GRKey);
1746
1747 priv->suppData->keyMgmtInfoSta.RSNDataTrafficEnabled = TRUE;
1748
1749 if (priv->suppData->keyMgmtInfoSta.RSNSecured == FALSE) {
1750 priv->suppData->keyMgmtInfoSta.RSNSecured = TRUE;
1751
1752 keyMgmtControlledPortOpen(priv);
1753 }
1754 #ifdef MULTI_CH_SW
1755 chmgr_UnlockCh(connPtr, 0);
1756 #endif
1757
1758 //return NULL;
1759 }
1760
1761 static void
keyMgmtKeyPairwiseTxDone(phostsa_private priv)1762 keyMgmtKeyPairwiseTxDone(phostsa_private priv)
1763 {
1764 if (!priv->suppData->keyMgmtInfoSta.pwkHandshakeComplete) {
1765 /*
1766 ** if (!pBufDesc || (pBufDesc->rsvd & 0x00FF == 0))
1767 **
1768 ** Removed check to verify the 4th message was a success. If we
1769 ** miss the ACK from the 4th(WPA2) message, but the AP
1770 ** received it, then it won't retry and we will be stuck waiting for
1771 ** a session timeout.
1772 **
1773 ** Could add back later if we retry the message in case of TX failure.
1774 */
1775 keyMgmtPlumbPairwiseKey(priv);
1776
1777 priv->suppData->keyMgmtInfoSta.pwkHandshakeComplete = TRUE;
1778
1779 if (priv->suppData->keyMgmtInfoSta.pRxDecryptKey &&
1780 priv->suppData->keyMgmtInfoSta.pwkHandshakeComplete) {
1781 SET_KEY_STATE_FORCE_EAPOL_UNENCRYPTED(priv->suppData->
1782 keyMgmtInfoSta.
1783 pRxDecryptKey,
1784 FALSE);
1785 }
1786 }
1787 }
1788
1789 static
1790 void
keyMgmtKeyPairAndGroupTxDone(phostsa_private priv)1791 keyMgmtKeyPairAndGroupTxDone(phostsa_private priv)
1792 {
1793 if (!priv->suppData->keyMgmtInfoSta.pwkHandshakeComplete) {
1794 keyMgmtKeyPairwiseTxDone(priv);
1795 keyMgmtKeyGroupTxDone(priv);
1796 }
1797 }
1798
1799 void
keyMgmtControlledPortOpen(phostsa_private priv)1800 keyMgmtControlledPortOpen(phostsa_private priv)
1801 {
1802 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
1803
1804 supplicantStopSessionTimer((void *)priv);
1805
1806 pm_fns->Hostsa_StaControlledPortOpen(pm_fns->pmlan_private);
1807 }
1808
1809 #ifdef WAR_ROM_BUG42707_RSN_IE_LEN_CHECK
1810
1811 BOOLEAN
patch_supplicantParseRsnIe(phostsa_private priv,IEEEtypes_RSNElement_t * pRsnIe,SecurityMode_t * pWpaTypeOut,Cipher_t * pMcstCipherOut,Cipher_t * pUcstCipherOut,AkmSuite_t * pAkmListOut,UINT8 akmOutMax,IEEEtypes_RSNCapability_t * pRsnCapOut,Cipher_t * pGrpMgmtCipherOut)1812 patch_supplicantParseRsnIe(phostsa_private priv, IEEEtypes_RSNElement_t *pRsnIe,
1813 SecurityMode_t *pWpaTypeOut,
1814 Cipher_t *pMcstCipherOut,
1815 Cipher_t *pUcstCipherOut,
1816 AkmSuite_t *pAkmListOut,
1817 UINT8 akmOutMax,
1818 IEEEtypes_RSNCapability_t *pRsnCapOut,
1819 Cipher_t *pGrpMgmtCipherOut)
1820 {
1821 hostsa_util_fns *util_fns = &priv->util_fns;
1822 UINT8 *pIeData;
1823 UINT8 *pIeEnd;
1824 UINT8 *pGrpKeyCipher;
1825 UINT16 pwsKeyCnt;
1826 UINT8 *pPwsKeyCipherList;
1827 UINT16 authKeyCnt;
1828 UINT8 *pAuthKeyList;
1829
1830 IEEEtypes_RSNCapability_t *pRsnCap;
1831
1832 UINT16 *pPMKIDCnt;
1833
1834 UINT8 *pGrpMgmtCipher;
1835
1836 memset(util_fns, pWpaTypeOut, 0x00, sizeof(SecurityMode_t));
1837
1838 pWpaTypeOut->wpa2 = 1;
1839
1840 /* Set the start and end of the IE data */
1841 pIeData = (UINT8 *)&pRsnIe->Ver;
1842 pIeEnd = pIeData + pRsnIe->Len;
1843
1844 /* Skip past the version field */
1845 pIeData += sizeof(pRsnIe->Ver);
1846
1847 /* Parse the group key cipher list */
1848 pGrpKeyCipher = pIeData;
1849 pIeData += sizeof(pRsnIe->GrpKeyCipher);
1850 supplicantParseMcstCipher(priv, pMcstCipherOut, pGrpKeyCipher);
1851
1852 /* Parse the pairwise key cipher list */
1853 memcpy(util_fns, &pwsKeyCnt, pIeData, sizeof(pwsKeyCnt));
1854 pIeData += sizeof(pRsnIe->PwsKeyCnt);
1855
1856 pPwsKeyCipherList = pIeData;
1857 pIeData += pwsKeyCnt * sizeof(pRsnIe->PwsKeyCipherList);
1858 supplicantParseUcstCipher(priv, pUcstCipherOut, pwsKeyCnt,
1859 pPwsKeyCipherList);
1860
1861 /* Parse and return the AKM list */
1862 memcpy(util_fns, &authKeyCnt, pIeData, sizeof(authKeyCnt));
1863 pIeData += sizeof(pRsnIe->AuthKeyCnt);
1864
1865 pAuthKeyList = pIeData;
1866 pIeData += authKeyCnt * sizeof(pRsnIe->AuthKeyList);
1867 memset(util_fns, pAkmListOut, 0x00, akmOutMax * sizeof(AkmSuite_t));
1868 memcpy(util_fns, pAkmListOut,
1869 pAuthKeyList,
1870 MIN(authKeyCnt, akmOutMax) * sizeof(pRsnIe->AuthKeyList));
1871
1872 /* Check if the RSN Capability is included */
1873 if (pIeData < pIeEnd) {
1874 pRsnCap = (IEEEtypes_RSNCapability_t *)pIeData;
1875 pIeData += sizeof(pRsnIe->RsnCap);
1876
1877 if (pRsnCapOut) {
1878 memcpy(util_fns, pRsnCapOut, pRsnCap,
1879 sizeof(IEEEtypes_RSNCapability_t));
1880 }
1881 }
1882
1883 /* Check if the PMKID count is included */
1884 if (pIeData < pIeEnd) {
1885 pPMKIDCnt = (UINT16 *)pIeData;
1886 pIeData += sizeof(pRsnIe->PMKIDCnt);
1887
1888 /* Check if the PMKID List is included */
1889 if (pIeData < pIeEnd) {
1890 /* pPMKIDList = pIeData; <-- Currently not used in parsing */
1891 pIeData += *pPMKIDCnt * sizeof(pRsnIe->PMKIDList);
1892 }
1893 }
1894
1895 /* Check if the Group Mgmt Cipher is included */
1896 if (pIeData < pIeEnd) {
1897 pGrpMgmtCipher = pIeData;
1898
1899 if (pGrpMgmtCipherOut) {
1900 memcpy(util_fns, pGrpMgmtCipherOut,
1901 pGrpMgmtCipher, sizeof(pRsnIe->GrpMgmtCipher));
1902 }
1903 }
1904
1905 return TRUE;
1906 }
1907
1908 #endif
1909
1910 //#pragma arm section code = ".init"
1911 void
keyMgmtSta_RomInit(void)1912 keyMgmtSta_RomInit(void)
1913 {
1914 //#if defined(PSK_SUPPLICANT) || defined (WPA_NONE)
1915 //ramHook_keyMgmtProcessMsgExt = keyMgmtProcessMsgExt;
1916 //ramHook_keyMgmtSendDeauth = keyMgmtSendDeauth2Peer;
1917 //#endif
1918
1919 #ifdef WAR_ROM_BUG42707_RSN_IE_LEN_CHECK
1920 supplicantParseRsnIe_hook = patch_supplicantParseRsnIe;
1921 #endif
1922
1923 }
1924
1925 //#pragma arm section code
1926
1927 #if defined(BTAMP)
1928 UINT8 *
parseKeyDataField(cm_ConnectionInfo_t * connPtr,UINT8 * pKey,UINT16 len)1929 parseKeyDataField(cm_ConnectionInfo_t * connPtr, UINT8 *pKey, UINT16 len)
1930 {
1931 keyMgmtInfoSta_t *pKeyMgmtInfoSta;
1932 KDE_t *pKde;
1933
1934 pKeyMgmtInfoSta = &connPtr->suppData->keyMgmtInfoSta;
1935
1936 /* parse KDE GTK */
1937 pKde = parseKeyDataGTK(pKey, len, &pKeyMgmtInfoSta->GRKey);
1938
1939 /* Parse PMKID though it's _not used_ now */
1940
1941 pKde = parseKeyKDE_DataType(pKey, len, KDE_DATA_TYPE_PMKID);
1942
1943 if (pKde) {
1944 /* PMKID KDE */
1945 return (UINT8 *)pKde->data;
1946 }
1947
1948 return NULL;
1949 }
1950
1951 /* Add RSN IE to a frame body */
1952 UINT16
btampAddRsnIe(cm_ConnectionInfo_t * connPtr,IEEEtypes_RSNElement_t * pRsnIe)1953 btampAddRsnIe(cm_ConnectionInfo_t * connPtr, IEEEtypes_RSNElement_t *pRsnIe)
1954 {
1955 const uint8 wpa2_psk[4] = { 0x00, 0x0f, 0xac, 0x02 }; /* WPA2 PSK */
1956 UINT16 ieSize;
1957 IEEEtypes_RSNCapability_t rsncap;
1958 SecurityMode_t securityMode;
1959 Cipher_t mcstWpa2;
1960 Cipher_t ucstWpa2;
1961 AkmSuite_t *pAkmWpa2;
1962
1963 memset(util_fns, &securityMode, 0x00, sizeof(securityMode));
1964 memset(util_fns, &mcstWpa2, 0x00, sizeof(mcstWpa2));
1965 memset(util_fns, &ucstWpa2, 0x00, sizeof(ucstWpa2));
1966 memset(util_fns, &rsncap, 0, sizeof(rsncap));
1967
1968 mcstWpa2.ccmp = 1;
1969 ucstWpa2.ccmp = 1;
1970 securityMode.wpa2 = 1;
1971
1972 pAkmWpa2 = (AkmSuite_t *)wpa2_psk;
1973
1974 supplicantSetProfile(connPtr, securityMode, mcstWpa2, ucstWpa2);
1975
1976 supplicantSetAssocRsn(connPtr, securityMode, &mcstWpa2, &ucstWpa2,
1977 pAkmWpa2, &rsncap, NULL);
1978
1979 ieSize = keyMgmtFormatWpaRsnIe(connPtr,
1980 (UINT8 *)pRsnIe,
1981 NULL, NULL, NULL, FALSE);
1982 return ieSize;
1983 }
1984 #endif
1985 #if 0
1986 void
1987 supplicantParseAndFormatRsnIe(phostsa_private priv,
1988 IEEEtypes_RSNElement_t *pRsnIe,
1989 SecurityMode_t *pWpaTypeOut,
1990 Cipher_t *pMcstCipherOut,
1991 Cipher_t *pUcstCipherOut, AkmSuite_t *pAkmListOut,
1992 UINT8 akmOutMax,
1993 IEEEtypes_RSNCapability_t *pRsnCapOut,
1994 Cipher_t *pGrpMgmtCipherOut)
1995 {
1996 hostsa_util_fns *util_fns = &priv->util_fns;
1997 UINT8 *pIeData;
1998 UINT8 *pIeEnd;
1999 UINT8 *pGrpKeyCipher;
2000 UINT16 pwsKeyCnt;
2001 UINT8 *pPwsKeyCipherList;
2002 UINT16 authKeyCnt;
2003 UINT8 *pAuthKeyList;
2004
2005 IEEEtypes_RSNCapability_t *pRsnCap;
2006
2007 UINT16 *pPMKIDCnt;
2008
2009 UINT8 *pGrpMgmtCipher;
2010
2011 //longl add
2012 UINT8 *pos = NULL;
2013 UINT8 cp_size = 0;
2014 #if 0
2015 #if !defined(REMOVE_PATCH_HOOKS)
2016 if (supplicantParseRsnIe_hook(pRsnIe,
2017 pWpaTypeOut,
2018 pMcstCipherOut,
2019 pUcstCipherOut,
2020 pAkmListOut,
2021 akmOutMax,
2022 pRsnCapOut, pGrpMgmtCipherOut)) {
2023 return;
2024 }
2025 #endif
2026 #endif
2027 memset(util_fns, pWpaTypeOut, 0x00, sizeof(SecurityMode_t));
2028 memset(util_fns, (UINT8 *)priv->suppData->wpa_rsn_ie, 0x00,
2029 MAX_IE_SIZE);
2030 pos = (UINT8 *)priv->suppData->wpa_rsn_ie;
2031
2032 pWpaTypeOut->wpa2 = 1;
2033
2034 /* Set the start and end of the IE data */
2035 pIeData = (UINT8 *)&pRsnIe->Ver;
2036 pIeEnd = pIeData + pRsnIe->Len;
2037
2038 /* Skip past the version field */
2039 pIeData += sizeof(pRsnIe->Ver);
2040
2041 /* Parse the group key cipher list */
2042 pGrpKeyCipher = pIeData;
2043 pIeData += sizeof(pRsnIe->GrpKeyCipher);
2044 supplicantParseMcstCipher(priv, pMcstCipherOut, pGrpKeyCipher);
2045
2046 cp_size = pIeData - (UINT8 *)pRsnIe;
2047 memcpy(util_fns, pos, (UINT8 *)pRsnIe, cp_size);
2048 pos += cp_size;
2049
2050 /* Parse the pairwise key cipher list */
2051 memcpy(util_fns, &pwsKeyCnt, pIeData, sizeof(pwsKeyCnt));
2052 pIeData += sizeof(pRsnIe->PwsKeyCnt);
2053
2054 if (pwsKeyCnt > 0) {
2055 (*(UINT16 *)pos) = (UINT16)1;
2056 pos += sizeof(UINT16);
2057 }
2058
2059 pPwsKeyCipherList = pIeData;
2060 pIeData += pwsKeyCnt * sizeof(pRsnIe->PwsKeyCipherList);
2061 supplicantParseUcstCipher(priv, pUcstCipherOut, pwsKeyCnt,
2062 pPwsKeyCipherList);
2063
2064 if (pUcstCipherOut->ccmp == 1) {
2065 memcpy(util_fns, pos, wpa2_oui04, sizeof(wpa2_oui04));
2066 pos += sizeof(wpa2_oui04);
2067 } else if (pUcstCipherOut->tkip == 1) {
2068 memcpy(util_fns, pos, wpa2_oui02, sizeof(wpa2_oui02));
2069 pos += sizeof(wpa2_oui02);
2070 }
2071 if ((pUcstCipherOut->ccmp == 1) && (pUcstCipherOut->tkip == 1))
2072 pUcstCipherOut->tkip = 0;
2073
2074 cp_size = pIeEnd - pIeData;
2075 memcpy(util_fns, pos, pIeData, cp_size);
2076 pos += cp_size;
2077 ((IEEEtypes_RSNElement_t *)(priv->suppData->wpa_rsn_ie))->Len =
2078 pos - (UINT8 *)priv->suppData->wpa_rsn_ie -
2079 sizeof(IEEEtypes_InfoElementHdr_t);
2080
2081 /* Parse and return the AKM list */
2082 memcpy(util_fns, &authKeyCnt, pIeData, sizeof(authKeyCnt));
2083 pIeData += sizeof(pRsnIe->AuthKeyCnt);
2084
2085 pAuthKeyList = pIeData;
2086 pIeData += authKeyCnt * sizeof(pRsnIe->AuthKeyList);
2087 memset(util_fns, pAkmListOut, 0x00, akmOutMax * sizeof(AkmSuite_t));
2088 memcpy(util_fns, pAkmListOut,
2089 pAuthKeyList,
2090 MIN(authKeyCnt, akmOutMax) * sizeof(pRsnIe->AuthKeyList));
2091
2092 DBG_HEXDUMP(MCMD_D, " pAuthKeyList",
2093 (t_u8 *)pAuthKeyList, MIN(authKeyCnt,
2094 akmOutMax) *
2095 sizeof(pRsnIe->AuthKeyList));
2096 DBG_HEXDUMP(MCMD_D, " pAuthKeyList", (t_u8 *)pAkmListOut,
2097 MIN(authKeyCnt, akmOutMax) * sizeof(pRsnIe->AuthKeyList));
2098 /* Check if the RSN Capability is included */
2099 if (pIeData < pIeEnd) {
2100 pRsnCap = (IEEEtypes_RSNCapability_t *)pIeData;
2101 pIeData += sizeof(pRsnIe->RsnCap);
2102
2103 if (pRsnCapOut) {
2104 memcpy(util_fns, pRsnCapOut, pRsnCap,
2105 sizeof(IEEEtypes_RSNCapability_t));
2106 }
2107 }
2108
2109 /* Check if the PMKID count is included */
2110 if (pIeData < pIeEnd) {
2111 pPMKIDCnt = (UINT16 *)pIeData;
2112 pIeData += sizeof(pRsnIe->PMKIDCnt);
2113
2114 /* Check if the PMKID List is included */
2115 if (pIeData < pIeEnd) {
2116 /* pPMKIDList = pIeData; <-- Currently not used in parsing */
2117 pIeData += *pPMKIDCnt * sizeof(pRsnIe->PMKIDList);
2118 }
2119 }
2120
2121 /* Check if the Group Mgmt Cipher is included */
2122 if (pIeData < pIeEnd) {
2123 pGrpMgmtCipher = pIeData;
2124
2125 if (pGrpMgmtCipherOut) {
2126 memcpy(util_fns, pGrpMgmtCipherOut,
2127 pGrpMgmtCipher, sizeof(pRsnIe->GrpMgmtCipher));
2128 }
2129 }
2130 }
2131
2132 void
2133 supplicantParseAndFormatWpaIe(phostsa_private priv, IEEEtypes_WPAElement_t *pIe,
2134 SecurityMode_t *pWpaType,
2135 Cipher_t *pMcstCipher,
2136 Cipher_t *pUcstCipher,
2137 AkmSuite_t *pAkmList, UINT8 akmOutMax)
2138 {
2139 hostsa_util_fns *util_fns = &priv->util_fns;
2140 IEEEtypes_WPAElement_t *pTemp = pIe;
2141 int count;
2142 int akmCount = akmOutMax;
2143 AkmSuite_t *pAkm = pAkmList;
2144 UINT8 *pos = NULL;
2145 UINT8 cp_size = 0;
2146 UINT8 *pIeEnd =
2147 (UINT8 *)pIe + sizeof(IEEEtypes_InfoElementHdr_t) + pIe->Len;
2148
2149 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
2150
2151 memset(util_fns, pMcstCipher, 0x00, sizeof(Cipher_t));
2152 memset(util_fns, pUcstCipher, 0x00, sizeof(Cipher_t));
2153 memset(util_fns, pAkmList, 0x00, akmOutMax * sizeof(AkmSuite_t));
2154 memset(util_fns, pWpaType, 0x00, sizeof(SecurityMode_t));
2155 memset(util_fns, (UINT8 *)priv->suppData->wpa_rsn_ie, 0x00,
2156 MAX_IE_SIZE);
2157 pos = (UINT8 *)priv->suppData->wpa_rsn_ie;
2158
2159 pWpaType->wpa = 1;
2160
2161 /* record the AP's multicast cipher */
2162 if (!memcmp
2163 (util_fns, (char *)pTemp->GrpKeyCipher, wpa_oui02,
2164 sizeof(wpa_oui02))) {
2165 /* WPA TKIP */
2166 pMcstCipher->tkip = 1;
2167 } else if (!memcmp
2168 (util_fns, (char *)pTemp->GrpKeyCipher, wpa_oui04,
2169 sizeof(wpa_oui04))) {
2170 /* WPA AES */
2171 pMcstCipher->ccmp = 1;
2172 } else if (!memcmp
2173 (util_fns, (char *)pTemp->GrpKeyCipher, wpa_oui01,
2174 sizeof(wpa_oui01))) {
2175 /* WPA WEP 40 */
2176 pMcstCipher->wep40 = 1;
2177 } else if (!memcmp
2178 (util_fns, (char *)pTemp->GrpKeyCipher, wpa_oui05,
2179 sizeof(wpa_oui05))) {
2180 /* WPA WEP 104 */
2181 pMcstCipher->wep104 = 1;
2182 }
2183
2184 cp_size = (UINT8 *)(&pTemp->PwsKeyCnt) - (UINT8 *)pIe;
2185 memcpy(util_fns, pos, (UINT8 *)pIe, cp_size);
2186 pos += cp_size;
2187
2188 count = pTemp->PwsKeyCnt;
2189
2190 if (count > 0) {
2191 (*(UINT16 *)pos) = (UINT16)1;
2192 pos += sizeof(UINT16);
2193 }
2194
2195 while (count) {
2196 /* record the AP's unicast cipher */
2197 if (!memcmp(util_fns, (char *)pTemp->PwsKeyCipherList,
2198 wpa_oui02, sizeof(wpa_oui02))) {
2199 /* WPA TKIP */
2200 pUcstCipher->tkip = 1;
2201 } else if (!memcmp(util_fns, (char *)pTemp->PwsKeyCipherList,
2202 wpa_oui04, sizeof(wpa_oui04))) {
2203 /* WPA AES */
2204 pUcstCipher->ccmp = 1;
2205 }
2206 count--;
2207
2208 if (count) {
2209 pTemp = (IEEEtypes_WPAElement_t *)((UINT8 *)pTemp +
2210 sizeof(pTemp->
2211 PwsKeyCipherList));
2212 }
2213 }
2214
2215 if (pUcstCipher->ccmp == 1) {
2216 memcpy(util_fns, pos, wpa_oui04, sizeof(wpa_oui04));
2217 pos += sizeof(wpa_oui04);
2218 } else if (pUcstCipher->tkip == 1) {
2219 memcpy(util_fns, pos, wpa_oui02, sizeof(wpa_oui02));
2220 pos += sizeof(wpa_oui02);
2221 }
2222 if ((pUcstCipher->ccmp == 1) && (pUcstCipher->tkip == 1))
2223 pUcstCipher->tkip = 0;
2224
2225 cp_size = pIeEnd - (UINT8 *)(&pTemp->AuthKeyCnt);
2226 memcpy(util_fns, pos, &pTemp->AuthKeyCnt, cp_size);
2227 pos += cp_size;
2228 ((IEEEtypes_RSNElement_t *)(priv->suppData->wpa_rsn_ie))->Len =
2229 pos - (UINT8 *)priv->suppData->wpa_rsn_ie -
2230 sizeof(IEEEtypes_InfoElementHdr_t);
2231
2232 count = pTemp->AuthKeyCnt;
2233
2234 while (count) {
2235 if (akmCount) {
2236 /* Store the AKM */
2237 memcpy(util_fns, pAkm,
2238 (char *)pTemp->AuthKeyList,
2239 sizeof(pTemp->AuthKeyList));
2240 pAkm++;
2241 akmCount--;
2242 }
2243
2244 count--;
2245
2246 if (count) {
2247 pTemp = (IEEEtypes_WPAElement_t *)((UINT8 *)pTemp
2248 +
2249 sizeof(pTemp->
2250 AuthKeyList));
2251 }
2252 }
2253
2254 if (!memcmp(util_fns, pAkmList, wpa_oui_none, sizeof(wpa_oui_none))) {
2255 pWpaType->wpaNone = 1;
2256 }
2257
2258 }
2259 #endif
2260
2261 void *
processRsnWpaInfo(void * priv,void * prsnwpa_ie)2262 processRsnWpaInfo(void *priv, void *prsnwpa_ie)
2263 {
2264 phostsa_private psapriv = (phostsa_private)priv;
2265 hostsa_util_fns *util_fns = &psapriv->util_fns;
2266 Cipher_t mcstCipher;
2267 Cipher_t ucstCipher;
2268 SecurityMode_t wpaType;
2269 AkmSuite_t akmList[AKM_SUITE_MAX];
2270 IEEEtypes_RSNCapability_t rsnCap;
2271 t_u8 type = ((IEEEtypes_InfoElementHdr_t *)prsnwpa_ie)->ElementId;
2272
2273 if (supplicantIsEnabled((void *)psapriv)) {
2274
2275 memset(util_fns, &wpaType, 0x00, sizeof(wpaType));
2276
2277 if (type == ELEM_ID_RSN || type == ELEM_ID_VENDOR_SPECIFIC) {
2278 if (type == ELEM_ID_RSN) {
2279 supplicantParseRsnIe(psapriv,
2280 (IEEEtypes_RSNElement_t *)
2281 prsnwpa_ie, &wpaType,
2282 &mcstCipher, &ucstCipher,
2283 akmList,
2284 NELEMENTS(akmList),
2285 &rsnCap, NULL);
2286 } else if (type == ELEM_ID_VENDOR_SPECIFIC) {
2287 supplicantParseWpaIe(psapriv,
2288 (IEEEtypes_WPAElement_t *)
2289 prsnwpa_ie, &wpaType,
2290 &mcstCipher, &ucstCipher,
2291 akmList,
2292 NELEMENTS(akmList));
2293 }
2294
2295 if (wpaType.wpa2 || wpaType.wpa) {
2296 memset(util_fns, &rsnCap, 0x00, sizeof(rsnCap));
2297
2298 supplicantSetProfile(psapriv, wpaType,
2299 mcstCipher, ucstCipher);
2300
2301 supplicantSetAssocRsn(psapriv,
2302 wpaType,
2303 &mcstCipher,
2304 &ucstCipher,
2305 akmList, &rsnCap, NULL);
2306
2307 memset(util_fns,
2308 (UINT8 *)psapriv->suppData->wpa_rsn_ie,
2309 0x00, MAX_IE_SIZE);
2310 if (keyMgmtFormatWpaRsnIe
2311 (psapriv,
2312 (UINT8 *)&psapriv->suppData->wpa_rsn_ie,
2313 &psapriv->suppData->localBssid,
2314 &psapriv->suppData->localStaAddr, NULL,
2315 FALSE))
2316 return (void *)(psapriv->suppData->
2317 wpa_rsn_ie);
2318 }
2319 }
2320
2321 }
2322 return NULL;
2323 }
2324
2325 t_u8
supplicantFormatRsnWpaTlv(void * priv,void * rsn_wpa_ie,void * rsn_ie_tlv)2326 supplicantFormatRsnWpaTlv(void *priv, void *rsn_wpa_ie, void *rsn_ie_tlv)
2327 {
2328 phostsa_private psapriv = (phostsa_private)priv;
2329 hostsa_util_fns *util_fns = &psapriv->util_fns;
2330 void *supp_rsn_wpa_ie = NULL;
2331 MrvlIEGeneric_t *prsn_ie = (MrvlIEGeneric_t *)rsn_ie_tlv;
2332 t_u8 total_len = 0;
2333
2334 if (rsn_wpa_ie) {
2335 supp_rsn_wpa_ie =
2336 processRsnWpaInfo((void *)psapriv, rsn_wpa_ie);
2337 if (!supp_rsn_wpa_ie)
2338 return total_len;
2339
2340 /* WPA_IE or RSN_IE */
2341 prsn_ie->IEParam.Type =
2342 (t_u16)(((IEEEtypes_InfoElementHdr_t *)
2343 supp_rsn_wpa_ie)->ElementId);
2344 prsn_ie->IEParam.Type = prsn_ie->IEParam.Type & 0x00FF;
2345 prsn_ie->IEParam.Type = wlan_cpu_to_le16(prsn_ie->IEParam.Type);
2346 prsn_ie->IEParam.Length =
2347 (t_u16)(((IEEEtypes_InfoElementHdr_t *)
2348 supp_rsn_wpa_ie)->Len);
2349 prsn_ie->IEParam.Length = prsn_ie->IEParam.Length & 0x00FF;
2350 if (prsn_ie->IEParam.Length <= MAX_IE_SIZE) {
2351 memcpy(util_fns, rsn_ie_tlv + sizeof(prsn_ie->IEParam),
2352 (t_u8 *)supp_rsn_wpa_ie +
2353 sizeof(IEEEtypes_InfoElementHdr_t),
2354 prsn_ie->IEParam.Length);
2355 } else
2356 return total_len;
2357
2358 HEXDUMP("ASSOC_CMD: RSN IE", (t_u8 *)rsn_ie_tlv,
2359 sizeof(prsn_ie->IEParam) + prsn_ie->IEParam.Length);
2360 total_len += sizeof(prsn_ie->IEParam) + prsn_ie->IEParam.Length;
2361 prsn_ie->IEParam.Length =
2362 wlan_cpu_to_le16(prsn_ie->IEParam.Length);
2363 }
2364 return total_len;
2365 }
2366