xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/keyMgmtSta.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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