1 /** @file keyMgntAP.c
2 *
3 * @brief This file defined the eapol paket process and key management for authenticator
4 *
5 * Copyright (C) 2014-2017, Marvell International Ltd.
6 *
7 * This software file (the "File") is distributed by Marvell International
8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9 * (the "License"). You may use, redistribute and/or modify this File in
10 * accordance with the terms and conditions of the License, a copy of which
11 * is available by writing to the Free Software Foundation, Inc.,
12 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14 *
15 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18 * this warranty disclaimer.
19 */
20
21 /******************************************************
22 Change log:
23 03/07/2014: Initial version
24 ******************************************************/
25 //Authenticator related function definitions
26 #include "wltypes.h"
27 #include "IEEE_types.h"
28
29 #include "hostsa_ext_def.h"
30 #include "authenticator.h"
31
32 #include "wl_macros.h"
33 #include "wlpd.h"
34 #include "pass_phrase.h"
35 #include "sha1.h"
36 #include "crypt_new.h"
37 #include "parser.h"
38 #include "keyCommonDef.h"
39 #include "keyMgmtStaTypes.h"
40 #include "AssocAp_srv_rom.h"
41 #include "pmkCache.h"
42 #include "keyMgmtApTypes.h"
43 #include "keyMgmtAp.h"
44 #include "rc4.h"
45 #include "authenticator_api.h"
46
47 //////////////////////
48 // STATIC FUNCTIONS
49 //////////////////////
50
51 //#ifdef AUTHENTICATOR
52 ////////////////////////
53 // FORWARD DECLARATIONS
54 ////////////////////////
55 Status_e GeneratePWKMsg3(hostsa_private *priv, cm_Connection *connPtr);
56 Status_e GenerateGrpMsg1(hostsa_private *priv, cm_Connection *connPtr);
57 Status_e GenerateApEapolMsg(hostsa_private *priv,
58 t_void *pconnPtr, keyMgmtState_e msgState);
59
60 static void
handleFailedHSK(t_void * priv,t_void * pconnPtr,IEEEtypes_ReasonCode_t reason)61 handleFailedHSK(t_void *priv, t_void *pconnPtr, IEEEtypes_ReasonCode_t reason)
62 {
63 phostsa_private psapriv = (phostsa_private)priv;
64 hostsa_mlan_fns *pm_fns = &psapriv->mlan_fns;
65 cm_Connection *connPtr = (cm_Connection *)pconnPtr;
66
67 KeyMgmtStopHskTimer(connPtr);
68 pm_fns->hostsa_SendDeauth(pm_fns->pmlan_private, connPtr->mac_addr,
69 (t_u16)reason);
70 }
71
72 static void
incrementReplayCounter(apKeyMgmtInfoSta_t * pKeyMgmtInfo)73 incrementReplayCounter(apKeyMgmtInfoSta_t *pKeyMgmtInfo)
74 {
75 if (++pKeyMgmtInfo->counterLo == 0) {
76 pKeyMgmtInfo->counterHi++;
77 }
78 }
79
80 int
isValidReplayCount(t_void * priv,apKeyMgmtInfoSta_t * pKeyMgmtInfo,UINT8 * pRxReplayCount)81 isValidReplayCount(t_void *priv, apKeyMgmtInfoSta_t *pKeyMgmtInfo,
82 UINT8 *pRxReplayCount)
83 {
84 phostsa_private psapriv = (phostsa_private)priv;
85 hostsa_util_fns *util_fns = &psapriv->util_fns;
86 UINT32 rxCounterHi;
87 UINT32 rxCounterLo;
88
89 memcpy(util_fns, &rxCounterHi, pRxReplayCount, 4);
90 memcpy(util_fns, &rxCounterLo, pRxReplayCount + 4, 4);
91
92 if ((pKeyMgmtInfo->counterHi == WORD_SWAP(rxCounterHi)) &&
93 (pKeyMgmtInfo->counterLo == WORD_SWAP(rxCounterLo))) {
94 return 1;
95 }
96 return 0;
97 }
98
99 void
KeyMgmtSendGrpKeyMsgToAllSta(hostsa_private * priv)100 KeyMgmtSendGrpKeyMsgToAllSta(hostsa_private *priv)
101 {
102 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
103 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
104 cm_Connection *connPtr = MNULL;
105 t_void *sta_node = MNULL;
106
107 ENTER();
108
109 pm_fns->Hostsa_find_connection(priv->pmlan_private, (t_void *)&connPtr,
110 &sta_node);
111
112 while (connPtr != MNULL) {
113 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
114
115 if (pKeyMgmtInfo->rom.keyMgmtState == HSK_END) {
116 GenerateApEapolMsg(priv, connPtr,
117 GRP_REKEY_MSG1_PENDING);
118 } else if ((pKeyMgmtInfo->rom.keyMgmtState == WAITING_4_GRPMSG2)
119 || (pKeyMgmtInfo->rom.staSecType.wpa2 &&
120 (pKeyMgmtInfo->rom.keyMgmtState ==
121 WAITING_4_MSG4)) ||
122 (pKeyMgmtInfo->rom.keyMgmtState ==
123 WAITING_4_GRP_REKEY_MSG2)) {
124 // TODO:How to handle group rekey if either Groupwise handshake
125 // Group rekey is already in progress for this STA?
126 }
127
128 pm_fns->Hostsa_find_next_connection(priv->pmlan_private,
129 (t_void *)&connPtr,
130 &sta_node);
131 }
132
133 LEAVE();
134 }
135
136 UINT32
keyApi_ApUpdateKeyMaterial(void * priv,cm_Connection * connPtr,BOOLEAN updateGrpKey)137 keyApi_ApUpdateKeyMaterial(void *priv, cm_Connection *connPtr,
138 BOOLEAN updateGrpKey)
139 {
140 phostsa_private psapriv = (phostsa_private)priv;
141 hostsa_util_fns *util_fns = &psapriv->util_fns;
142 hostsa_mlan_fns *pm_fns = &psapriv->mlan_fns;
143 BssConfig_t *pBssConfig = MNULL;
144 KeyData_t *pKeyData = MNULL;
145 //cipher_key_buf_t *pCipherKeyBuf;
146 Cipher_t *pCipher = MNULL;
147 //KeyData_t pwsKeyData;
148 mlan_ds_encrypt_key encrypt_key;
149 t_u8 bcast_addr[MAC_ADDR_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
150 apInfo_t *pApInfo = &psapriv->apinfo;
151
152 pBssConfig = &pApInfo->bssConfig;
153
154 if (pBssConfig->SecType.wpa || pBssConfig->SecType.wpa2) {
155 memset(util_fns, &encrypt_key, 0, sizeof(mlan_ds_encrypt_key));
156
157 //connPtr->cmFlags.RSNEnabled = TRUE;
158 if (updateGrpKey == TRUE) {
159 pKeyData = &pApInfo->bssData.grpKeyData;
160 pCipher = &pBssConfig->RsnConfig.mcstCipher;
161 } else if (connPtr) {
162 /* pCipherKeyBuf = connPtr->pwTxRxCipherKeyBuf;
163 memcpy((void*)&pwsKeyData,
164 (void*)&pCipherKeyBuf->cipher_key.ckd.hskData.pwsKeyData,
165 sizeof(KeyData_t)); */
166 pKeyData = &connPtr->hskData.pwsKeyData;
167 pCipher =
168 &connPtr->staData.keyMgmtInfo.rom.staUcstCipher;
169 }
170
171 if (updateGrpKey == TRUE) {
172 memcpy(util_fns, encrypt_key.mac_addr, bcast_addr,
173 MAC_ADDR_SIZE);
174 encrypt_key.key_flags |= KEY_FLAG_GROUP_KEY;
175 } else if (connPtr) {
176 memcpy(util_fns, encrypt_key.mac_addr,
177 connPtr->mac_addr, MAC_ADDR_SIZE);
178 encrypt_key.key_flags |= KEY_FLAG_SET_TX_KEY;
179 }
180
181 if (!pKeyData || !pCipher) {
182 PRINTM(MERROR, "Invalid KeyData or Cipher pointer!\n");
183 return 1;
184 }
185
186 if (pCipher->ccmp) {
187 /**AES*/
188 encrypt_key.key_len = TK_SIZE;
189 memcpy(util_fns, encrypt_key.key_material,
190 pKeyData->Key, TK_SIZE);
191 } else if (pCipher->tkip) {
192 /**TKIP*/
193 encrypt_key.key_len =
194 TK_SIZE + MIC_KEY_SIZE + MIC_KEY_SIZE;
195 memcpy(util_fns, encrypt_key.key_material,
196 pKeyData->Key, TK_SIZE);
197 memcpy(util_fns, &encrypt_key.key_material[TK_SIZE],
198 pKeyData->TxMICKey, MIC_KEY_SIZE);
199 memcpy(util_fns,
200 &encrypt_key.key_material[TK_SIZE +
201 MIC_KEY_SIZE],
202 pKeyData->RxMICKey, MIC_KEY_SIZE);
203 }
204 /**set pn 0*/
205 memset(util_fns, encrypt_key.pn, 0, PN_SIZE);
206
207 /**key flag*/
208 encrypt_key.key_flags |= KEY_FLAG_RX_SEQ_VALID;
209 /**key index*/
210 encrypt_key.key_index = pKeyData->KeyIndex;
211 /**set command to fw update key*/
212 pm_fns->hostsa_set_encrypt_key(psapriv->pmlan_private,
213 &encrypt_key);
214
215 }
216
217 return 0;
218 }
219
220 void
GenerateGTK(void * priv)221 GenerateGTK(void *priv)
222 {
223 phostsa_private psapriv = (phostsa_private)priv;
224 apInfo_t *pApInfo = &psapriv->apinfo;
225 BssData_t *pBssData = MNULL;
226
227 pBssData = &pApInfo->bssData;
228
229 GenerateGTK_internal(psapriv, &pBssData->grpKeyData,
230 pBssData->GNonce, psapriv->curr_addr);
231 }
232
233 void
ReInitGTK(t_void * priv)234 ReInitGTK(t_void *priv)
235 {
236 phostsa_private psapriv = (phostsa_private)priv;
237 apInfo_t *pApInfo = &psapriv->apinfo;
238 BssData_t *pBssData;
239
240 pBssData = &pApInfo->bssData;
241
242 /*
243 Disabled for interop
244 Not all clients like this
245 pBssData->grpKeyData.KeyIndex = (pBssData->grpKeyData.KeyIndex & 3) + 1;
246 */
247
248 ROM_InitGTK(psapriv, &pBssData->grpKeyData,
249 pBssData->GNonce, psapriv->curr_addr);
250
251 keyApi_ApUpdateKeyMaterial(priv, MNULL, MTRUE);
252 }
253
254 void
KeyMgmtGrpRekeyCountUpdate(t_void * context)255 KeyMgmtGrpRekeyCountUpdate(t_void *context)
256 {
257 phostsa_private psapriv = (phostsa_private)context;
258 apInfo_t *pApInfo = &psapriv->apinfo;
259 hostsa_util_fns *putil_fns = &psapriv->util_fns;
260
261 ENTER();
262
263 if (psapriv->GrpRekeyTimerIsSet &&
264 pApInfo->bssData.grpRekeyCntRemaining) {
265 //Periodic group rekey is configured.
266 pApInfo->bssData.grpRekeyCntRemaining--;
267 if (!pApInfo->bssData.grpRekeyCntRemaining) {
268 //Group rekey timeout hit.
269 pApInfo->bssData.grpRekeyCntRemaining
270 = pApInfo->bssData.grpRekeyCntConfigured;
271
272 ReInitGTK((t_void *)psapriv);
273
274 KeyMgmtSendGrpKeyMsgToAllSta(psapriv);
275 }
276
277 /**start Group rekey timer*/
278 putil_fns->moal_start_timer(putil_fns->pmoal_handle,
279 psapriv->GrpRekeytimer,
280 MFALSE, MRVDRV_TIMER_60S);
281 }
282
283 LEAVE();
284 }
285
286 void
KeyMgmtInit(void * priv)287 KeyMgmtInit(void *priv)
288 {
289 phostsa_private psapriv = (phostsa_private)priv;
290 apInfo_t *pApInfo = &psapriv->apinfo;
291 UINT8 *pPassPhrase;
292 UINT8 *pPskValue;
293 UINT8 passPhraseLen;
294
295 pPassPhrase = pApInfo->bssConfig.RsnConfig.PSKPassPhrase;
296 pPskValue = pApInfo->bssConfig.RsnConfig.PSKValue;
297 passPhraseLen = pApInfo->bssConfig.RsnConfig.PSKPassPhraseLen;
298
299 ROM_InitGTK(psapriv, &pApInfo->bssData.grpKeyData,
300 pApInfo->bssData.GNonce, psapriv->curr_addr);
301
302 if (pApInfo->bssData.updatePassPhrase == MTRUE) {
303 pmkCacheGeneratePSK(priv, pApInfo->bssConfig.SsId,
304 pApInfo->bssConfig.SsIdLen,
305 (char *)pPassPhrase, pPskValue);
306
307 pApInfo->bssData.updatePassPhrase = MFALSE;
308 }
309 }
310
311 void
KeyMgmtHskTimeout(t_void * context)312 KeyMgmtHskTimeout(t_void *context)
313 {
314 cm_Connection *connPtr = (cm_Connection *)context;
315 phostsa_private priv = (phostsa_private)connPtr->priv;
316 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
317 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
318 apRsnConfig_t *pRsnConfig;
319 IEEEtypes_ReasonCode_t reason;
320 BOOLEAN maxRetriesDone = MFALSE;
321 apInfo_t *pApInfo = &priv->apinfo;
322
323 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
324
325 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
326 pRsnConfig = &pApInfo->bssConfig.RsnConfig;
327
328 connPtr->timer_is_set = 0;
329 /* Assume when this function gets called pKeyMgmtInfo->keyMgmtState
330 ** will not be in HSK_NOT_STARTED or HSK_END
331 */
332 if (pKeyMgmtInfo->rom.keyMgmtState <= WAITING_4_MSG4) {
333 if (pKeyMgmtInfo->numHskTries >= pRsnConfig->MaxPwsHskRetries) {
334 maxRetriesDone = MTRUE;
335 reason = IEEEtypes_REASON_4WAY_HANDSHK_TIMEOUT;
336 }
337 } else {
338 if (pKeyMgmtInfo->numHskTries >= pRsnConfig->MaxGrpHskRetries) {
339 maxRetriesDone = MTRUE;
340 reason = IEEEtypes_REASON_GRP_KEY_UPD_TIMEOUT;
341 }
342 }
343
344 if (maxRetriesDone) {
345 // Some STAs do not respond to PWK Msg1 if the EAPOL Proto Version is 1
346 // in 802.1X header, hence switch to v2 after all attempts with v1 fail
347 // for PWK Msg1. Set the HskTimeoutCtn to 1 to get the same "retries"
348 // as with v1.
349 if (((WAITING_4_MSG2 == pKeyMgmtInfo->rom.keyMgmtState)
350 || (MSG1_PENDING == pKeyMgmtInfo->rom.keyMgmtState))
351 && (EAPOL_PROTOCOL_V1 == pKeyMgmtInfo->EAPOLProtoVersion)) {
352 pKeyMgmtInfo->numHskTries = 1;
353 pKeyMgmtInfo->EAPOLProtoVersion = EAPOL_PROTOCOL_V2;
354 GenerateApEapolMsg(priv, connPtr,
355 pKeyMgmtInfo->rom.keyMgmtState);
356 } else {
357 pm_fns->hostsa_SendDeauth(priv->pmlan_private,
358 connPtr->mac_addr,
359 (t_u16)reason);
360 pKeyMgmtInfo->rom.keyMgmtState = HSK_END;
361 }
362 } else {
363 GenerateApEapolMsg(priv, connPtr,
364 pKeyMgmtInfo->rom.keyMgmtState);
365 }
366
367 return;
368 }
369
370 void
KeyMgmtStartHskTimer(void * context)371 KeyMgmtStartHskTimer(void *context)
372 {
373 cm_Connection *connPtr = (cm_Connection *)context;
374 phostsa_private psapriv = (phostsa_private)(connPtr->priv);
375 hostsa_util_fns *util_fns = &psapriv->util_fns;
376 apInfo_t *pApInfo = MNULL;
377 UINT32 timeoutInms;
378 apRsnConfig_t *pRsnConfig;
379
380 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
381
382 pApInfo = &psapriv->apinfo;
383 pRsnConfig = &pApInfo->bssConfig.RsnConfig;
384 if ((connPtr->staData.keyMgmtInfo.rom.keyMgmtState >= MSG1_PENDING)
385 && (connPtr->staData.keyMgmtInfo.rom.keyMgmtState <=
386 WAITING_4_MSG4)) {
387 timeoutInms = pRsnConfig->PwsHskTimeOut;
388 } else if ((connPtr->staData.keyMgmtInfo.rom.keyMgmtState >=
389 GRPMSG1_PENDING)
390 && (connPtr->staData.keyMgmtInfo.rom.keyMgmtState <=
391 WAITING_4_GRP_REKEY_MSG2)) {
392 timeoutInms = pRsnConfig->GrpHskTimeOut;
393 } else {
394 //EAPOL HSK is not in progress. No need to start HSK timer
395 return;
396 }
397
398 // Retry happen, increase timeout to at least 1 sec
399 if (connPtr->staData.keyMgmtInfo.numHskTries > 0) {
400 timeoutInms = MAX(AP_RETRY_EAPOL_HSK_TIMEOUT, timeoutInms);
401 }
402
403 /* if STA is in PS1 then we are using max(STA_PS_EAPOL_HSK_TIMEOUT,
404 * HSKtimeout)for timeout instead of configured timeout value
405 */
406 /* if(PWR_MODE_PWR_SAVE == connPtr->staData.pwrSaveInfo.mode)
407 {
408 timeoutInms = MAX(STA_PS_EAPOL_HSK_TIMEOUT, timeoutInms);
409 }
410 */
411 util_fns->moal_start_timer(util_fns->pmoal_handle,
412 connPtr->HskTimer, MFALSE, timeoutInms);
413 connPtr->timer_is_set = 1;
414 }
415
416 void
KeyMgmtStopHskTimer(t_void * pconnPtr)417 KeyMgmtStopHskTimer(t_void *pconnPtr)
418 {
419 cm_Connection *connPtr = (cm_Connection *)pconnPtr;
420 phostsa_private priv = (phostsa_private)connPtr->priv;
421 hostsa_util_fns *util_fns = &priv->util_fns;
422
423 util_fns->moal_stop_timer(util_fns->pmoal_handle, connPtr->HskTimer);
424
425 connPtr->timer_is_set = 0;
426 }
427
428 void
PrepDefaultEapolMsg(phostsa_private priv,cm_Connection * connPtr,EAPOL_KeyMsg_Tx_t ** pTxEapolPtr,pmlan_buffer pmbuf)429 PrepDefaultEapolMsg(phostsa_private priv, cm_Connection *connPtr,
430 EAPOL_KeyMsg_Tx_t **pTxEapolPtr, pmlan_buffer pmbuf)
431 {
432 hostsa_util_fns *util_fns = &priv->util_fns;
433 apInfo_t *pApInfo = &priv->apinfo;
434 EAPOL_KeyMsg_Tx_t *tx_eapol_ptr;
435 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
436 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
437 UINT8 intf_hr_len =
438 pm_fns->Hostsa_get_intf_hr_len(pm_fns->pmlan_private);
439 #define UAP_EAPOL_PRIORITY 7 /* Voice */
440
441 ENTER();
442
443 pmbuf->priority = UAP_EAPOL_PRIORITY;
444 pmbuf->buf_type = MLAN_BUF_TYPE_DATA;
445 pmbuf->data_offset = (sizeof(UapTxPD) + intf_hr_len + DMA_ALIGNMENT);
446 tx_eapol_ptr =
447 (EAPOL_KeyMsg_Tx_t *)((UINT8 *)pmbuf->pbuf +
448 pmbuf->data_offset);
449 memset(util_fns, (UINT8 *)tx_eapol_ptr, 0x00,
450 sizeof(EAPOL_KeyMsg_Tx_t));
451
452 formEAPOLEthHdr(priv, tx_eapol_ptr, connPtr->mac_addr, priv->curr_addr);
453
454 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
455
456 SetEAPOLKeyDescTypeVersion(tx_eapol_ptr,
457 pKeyMgmtInfo->rom.staSecType.wpa2,
458 MFALSE,
459 (pKeyMgmtInfo->rom.staUcstCipher.ccmp ||
460 pApInfo->bssConfig.RsnConfig.mcstCipher.
461 ccmp));
462
463 *pTxEapolPtr = tx_eapol_ptr;
464
465 LEAVE();
466 }
467
468 Status_e
GeneratePWKMsg1(hostsa_private * priv,cm_Connection * connPtr)469 GeneratePWKMsg1(hostsa_private *priv, cm_Connection *connPtr)
470 {
471 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
472 EAPOL_KeyMsg_Tx_t *tx_eapol_ptr;
473 UINT16 frameLen = 0, packet_len = 0;
474 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
475 UINT32 replay_cnt[2];
476 eapolHskData_t *pHskData;
477 pmlan_buffer pmbuf = MNULL;
478
479 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
480
481 pmbuf = pm_fns->hostsa_alloc_mlan_buffer(priv->pmlan_adapter,
482 MLAN_TX_DATA_BUF_SIZE_2K, 0,
483 MOAL_MALLOC_BUFFER);
484 if (pmbuf == NULL) {
485 PRINTM(MERROR, "allocate buffer fail for eapol \n");
486 return FAIL;
487 }
488
489 PrepDefaultEapolMsg(priv, connPtr, &tx_eapol_ptr, pmbuf);
490
491 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
492 pHskData = &connPtr->hskData;
493
494 incrementReplayCounter(pKeyMgmtInfo);
495 replay_cnt[0] = pKeyMgmtInfo->counterHi;
496 replay_cnt[1] = pKeyMgmtInfo->counterLo;
497
498 supplicantGenerateRand(priv, pHskData->ANonce, NONCE_SIZE);
499
500 PopulateKeyMsg(priv, tx_eapol_ptr,
501 &pKeyMgmtInfo->rom.staUcstCipher,
502 PAIRWISE_KEY_MSG, replay_cnt, pHskData->ANonce);
503
504 frameLen = EAPOL_KeyMsg_Len - sizeof(Hdr_8021x_t)
505 - sizeof(tx_eapol_ptr->keyMsg.key_data)
506 + tx_eapol_ptr->keyMsg.key_material_len; //key_mtr_len is 0 here
507
508 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
509
510 tx_eapol_ptr->keyMsg.hdr_8021x.protocol_ver
511 = pKeyMgmtInfo->EAPOLProtoVersion;
512 tx_eapol_ptr->keyMsg.hdr_8021x.pckt_type
513 = IEEE_8021X_PACKET_TYPE_EAPOL_KEY;
514 tx_eapol_ptr->keyMsg.hdr_8021x.pckt_body_len = htons(frameLen);
515
516 UpdateEAPOLWcbLenAndTransmit(priv, pmbuf, packet_len);
517 return SUCCESS;
518 }
519
520 // returns 0 on success, or error code
521 Status_e
ProcessPWKMsg2(hostsa_private * priv,cm_Connection * connPtr,t_u8 * pbuf,t_u32 len)522 ProcessPWKMsg2(hostsa_private *priv,
523 cm_Connection *connPtr, t_u8 *pbuf, t_u32 len)
524 {
525 EAPOL_KeyMsg_t *rx_eapol_ptr;
526 UINT8 *PMK;
527 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
528 BssConfig_t *pBssConfig = NULL;
529 IEPointers_t iePointers;
530 UINT32 ieLen;
531 UINT8 *pIe = NULL;
532 apInfo_t *pApInfo = &priv->apinfo;
533 Cipher_t wpaUcastCipher;
534 Cipher_t wpa2UcastCipher;
535 eapolHskData_t *pHskData = &connPtr->hskData;
536
537 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
538 rx_eapol_ptr = (EAPOL_KeyMsg_t *)(pbuf + ETHII_HEADER_LEN);
539
540 pBssConfig = &pApInfo->bssConfig;
541 // compare the RSN IE from assoc req to current
542 pIe = (UINT8 *)rx_eapol_ptr->key_data;
543 ieLen = pIe[1] + sizeof(IEEEtypes_InfoElementHdr_t);
544 GetIEPointers((void *)priv, pIe, ieLen, &iePointers);
545 wpaUcastCipher = pBssConfig->RsnConfig.wpaUcstCipher;
546 wpa2UcastCipher = pBssConfig->RsnConfig.wpa2UcstCipher;
547 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
548
549 if (assocSrvAp_checkRsnWpa(connPtr, &pKeyMgmtInfo->rom,
550 wpaUcastCipher,
551 wpa2UcastCipher,
552 pBssConfig->RsnConfig.mcstCipher,
553 pBssConfig->RsnConfig.AuthKey,
554 &pKeyMgmtInfo->rom.staSecType,
555 iePointers.pRsn,
556 iePointers.pWpa, TRUE) == FAIL) {
557 handleFailedHSK(priv, connPtr, IEEEtypes_REASON_IE_4WAY_DIFF);
558 return FAIL;
559 }
560
561 PMK = pApInfo->bssConfig.RsnConfig.PSKValue;
562
563 KeyMgmtAp_DerivePTK(priv, PMK,
564 connPtr->mac_addr,
565 priv->curr_addr,
566 pHskData->ANonce,
567 rx_eapol_ptr->key_nonce,
568 pKeyMgmtInfo->EAPOL_MIC_Key,
569 pKeyMgmtInfo->EAPOL_Encr_Key,
570 &pHskData->pwsKeyData, MFALSE);
571
572 if (!IsEAPOL_MICValid(priv, rx_eapol_ptr, pKeyMgmtInfo->EAPOL_MIC_Key)) {
573 return FAIL;
574 }
575
576 KeyMgmtStopHskTimer(connPtr);
577 connPtr->staData.keyMgmtInfo.numHskTries = 0;
578
579 return GenerateApEapolMsg(priv, connPtr, MSG3_PENDING);
580 }
581
582 Status_e
GeneratePWKMsg3(hostsa_private * priv,cm_Connection * connPtr)583 GeneratePWKMsg3(hostsa_private *priv, cm_Connection *connPtr)
584 {
585 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
586 EAPOL_KeyMsg_Tx_t *tx_eapol_ptr;
587 UINT16 frameLen = 0, packet_len = 0;
588 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
589 apInfo_t *pApInfo = &priv->apinfo;
590 BssConfig_t *pBssConfig = MNULL;
591 UINT32 replay_cnt[2];
592 eapolHskData_t *pHskData;
593 pmlan_buffer pmbuf = MNULL;
594
595 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
596
597 pmbuf = pm_fns->hostsa_alloc_mlan_buffer(priv->pmlan_adapter,
598 MLAN_TX_DATA_BUF_SIZE_2K, 0,
599 MOAL_MALLOC_BUFFER);
600 if (pmbuf == NULL) {
601 PRINTM(MERROR, "allocate buffer fail for eapol \n");
602 return FAIL;
603 }
604
605 PrepDefaultEapolMsg(priv, connPtr, &tx_eapol_ptr, pmbuf);
606
607 pBssConfig = &pApInfo->bssConfig;
608
609 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
610 pHskData = &connPtr->hskData;
611
612 incrementReplayCounter(pKeyMgmtInfo);
613
614 replay_cnt[0] = pKeyMgmtInfo->counterHi;
615 replay_cnt[1] = pKeyMgmtInfo->counterLo;
616
617 PopulateKeyMsg(priv, tx_eapol_ptr,
618 &pKeyMgmtInfo->rom.staUcstCipher,
619 ((PAIRWISE_KEY_MSG | SECURE_HANDSHAKE_FLAG) |
620 ((pKeyMgmtInfo->rom.staSecType.
621 wpa2) ? WPA2_HANDSHAKE : 0)), replay_cnt,
622 pHskData->ANonce);
623
624 /*if (pKeyMgmtInfo->staSecType.wpa2)
625 {
626 // Netgear WAG511 and USB55 cards don't like this field set to
627 // anything other than zero. Hence hard code this value to zero
628 // in all outbound EAPOL frames...
629 // The client is now vulnerable to replay attacks from the point
630 // it receives EAP-message3 till reception of first management
631 // frame from uAP.
632
633 tx_eapol_ptr->keyMsg.key_RSC[0] =
634 pApInfo->bssConfig.grpKeyData.TxIV16 & 0x00FF;
635 tx_eapol_ptr->keyMsg.key_RSC[1] =
636 (pApInfo->bssConfig.grpKeyData.TxIV16 >> 8) & 0x00FF;
637 memcpy((void*)(tx_eapol_ptr->keyMsg.key_RSC + 2),
638 &pApInfo->bssData.grpKeyData.TxIV32, 4);
639 } */
640 /*
641 pBcnFrame = (dot11MgtFrame_t *)BML_DATA_PTR(connPtr->pBcnBufferDesc);
642 if (pKeyMgmtInfo->rom.staSecType.wpa)
643 {
644 pWpaIE = syncSrv_ParseAttrib(pBcnFrame,
645 ELEM_ID_VENDOR_SPECIFIC,
646 IEEE_MSG_BEACON,
647 (UINT8 *)wpa_oui01,
648 sizeof(wpa_oui01));
649 }
650 else if (pKeyMgmtInfo->rom.staSecType.wpa2)
651 {
652 pWpa2IE = syncSrv_ParseAttrib(pBcnFrame,
653 ELEM_ID_RSN,
654 IEEE_MSG_BEACON,
655 NULL,
656 0);
657 }*/
658 if (!KeyData_UpdateKeyMaterial(priv, tx_eapol_ptr,
659 &pKeyMgmtInfo->rom.staSecType,
660 pBssConfig->wpa_ie,
661 pBssConfig->rsn_ie)) {
662 /* We have WPA/WPA2 enabled but no corresponding IE */
663 pm_fns->hostsa_free_mlan_buffer(pm_fns->pmlan_adapter, pmbuf);
664 return FAIL;
665 }
666
667 if (pKeyMgmtInfo->rom.staSecType.wpa2) { // WPA2
668 prepareKDE(priv, tx_eapol_ptr,
669 &pApInfo->bssData.grpKeyData,
670 &pApInfo->bssConfig.RsnConfig.mcstCipher);
671
672 if (!Encrypt_keyData((t_void *)priv, tx_eapol_ptr,
673 pKeyMgmtInfo->EAPOL_Encr_Key,
674 &pKeyMgmtInfo->rom.staUcstCipher))
675 {
676 pm_fns->hostsa_free_mlan_buffer(pm_fns->pmlan_adapter,
677 pmbuf);
678 return FAIL;
679 }
680 }
681
682 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(priv,
683 tx_eapol_ptr,
684 pKeyMgmtInfo->
685 EAPOL_MIC_Key,
686 pKeyMgmtInfo->
687 EAPOLProtoVersion,
688 tx_eapol_ptr->keyMsg.
689 key_info.
690 KeyDescriptorVersion);
691
692 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
693 UpdateEAPOLWcbLenAndTransmit(priv, pmbuf, packet_len);
694 return SUCCESS;
695 }
696
697 Status_e
ProcessPWKMsg4(hostsa_private * priv,cm_Connection * connPtr,t_u8 * pbuf,t_u32 len)698 ProcessPWKMsg4(hostsa_private *priv,
699 cm_Connection *connPtr, t_u8 *pbuf, t_u32 len)
700 {
701 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
702 EAPOL_KeyMsg_t *rx_eapol_ptr;
703 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
704 eapolHskData_t *pHskData = &connPtr->hskData;
705
706 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
707 rx_eapol_ptr = (EAPOL_KeyMsg_t *)(pbuf + ETHII_HEADER_LEN);
708 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
709
710 if (!IsEAPOL_MICValid(priv, rx_eapol_ptr, pKeyMgmtInfo->EAPOL_MIC_Key)) {
711 return FAIL;
712 }
713 pHskData->pwsKeyData.TxIV16 = 0x0001;
714 pHskData->pwsKeyData.TxIV32 = 0;
715
716 if (keyApi_ApUpdateKeyMaterial(priv, connPtr, FALSE)) {
717 handleFailedHSK(priv, connPtr, IEEEtypes_REASON_UNSPEC);
718 return FAIL;
719 }
720
721 KeyMgmtStopHskTimer(connPtr);
722 connPtr->staData.keyMgmtInfo.numHskTries = 0;
723 if (pKeyMgmtInfo->rom.staSecType.wpa2) {
724 pm_fns->Hostsa_sendEventRsnConnect(priv->pmlan_private,
725 connPtr->mac_addr);
726 pKeyMgmtInfo->rom.keyMgmtState = HSK_END;
727 } else {
728 return GenerateApEapolMsg(priv, connPtr, GRPMSG1_PENDING);
729 }
730
731 return SUCCESS;
732 }
733
734 Status_e
GenerateGrpMsg1(hostsa_private * priv,cm_Connection * connPtr)735 GenerateGrpMsg1(hostsa_private *priv, cm_Connection *connPtr)
736 {
737 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
738 EAPOL_KeyMsg_Tx_t *tx_eapol_ptr;
739 UINT16 frameLen = 0, packet_len = 0;
740 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
741 apInfo_t *pApInfo = &priv->apinfo;
742 UINT32 replay_cnt[2];
743 pmlan_buffer pmbuf = MNULL;
744
745 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
746
747 pmbuf = pm_fns->hostsa_alloc_mlan_buffer(priv->pmlan_adapter,
748 MLAN_TX_DATA_BUF_SIZE_2K, 0,
749 MOAL_MALLOC_BUFFER);
750 if (pmbuf == NULL) {
751 PRINTM(MERROR, "allocate buffer fail for eapol \n");
752 return FAIL;
753 }
754
755 PrepDefaultEapolMsg(priv, connPtr, &tx_eapol_ptr, pmbuf);
756
757 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
758
759 incrementReplayCounter(pKeyMgmtInfo);
760
761 replay_cnt[0] = pKeyMgmtInfo->counterHi;
762 replay_cnt[1] = pKeyMgmtInfo->counterLo;
763
764 PopulateKeyMsg(priv, tx_eapol_ptr,
765 &pApInfo->bssConfig.RsnConfig.mcstCipher,
766 (SECURE_HANDSHAKE_FLAG |
767 ((pKeyMgmtInfo->rom.staSecType.
768 wpa2) ? WPA2_HANDSHAKE : 0)), replay_cnt,
769 pApInfo->bssData.GNonce);
770
771 KeyData_AddKey(priv,
772 tx_eapol_ptr,
773 &pKeyMgmtInfo->rom.staSecType,
774 &pApInfo->bssData.grpKeyData,
775 &pApInfo->bssConfig.RsnConfig.mcstCipher);
776 if (!Encrypt_keyData(priv, tx_eapol_ptr,
777 pKeyMgmtInfo->EAPOL_Encr_Key,
778 &pKeyMgmtInfo->rom.staUcstCipher))
779 {
780 // nothing here.
781 }
782
783 frameLen = KeyMgmtSta_PopulateEAPOLLengthMic(priv,
784 tx_eapol_ptr,
785 pKeyMgmtInfo->
786 EAPOL_MIC_Key,
787 pKeyMgmtInfo->
788 EAPOLProtoVersion,
789 tx_eapol_ptr->keyMsg.
790 key_info.
791 KeyDescriptorVersion);
792
793 packet_len = frameLen + sizeof(Hdr_8021x_t) + sizeof(ether_hdr_t);
794
795 UpdateEAPOLWcbLenAndTransmit(priv, pmbuf, packet_len);
796 return SUCCESS;
797 }
798
799 Status_e
ProcessGrpMsg2(hostsa_private * priv,cm_Connection * connPtr,t_u8 * pbuf,t_u32 len)800 ProcessGrpMsg2(hostsa_private *priv,
801 cm_Connection *connPtr, t_u8 *pbuf, t_u32 len)
802 {
803 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
804 EAPOL_KeyMsg_t *rx_eapol_ptr;
805 apKeyMgmtInfoSta_t *pKeyMgmtInfo;
806
807 PRINTM(MMSG, "ENTER: %s\n", __FUNCTION__);
808
809 rx_eapol_ptr = (EAPOL_KeyMsg_t *)(pbuf + ETHII_HEADER_LEN);
810
811 pKeyMgmtInfo = &connPtr->staData.keyMgmtInfo;
812
813 if (!IsEAPOL_MICValid(priv, rx_eapol_ptr, pKeyMgmtInfo->EAPOL_MIC_Key)) {
814 handleFailedHSK(priv, connPtr, IEEEtypes_REASON_IE_4WAY_DIFF);
815 return FAIL;
816 }
817 KeyMgmtStopHskTimer(connPtr);
818 connPtr->staData.keyMgmtInfo.numHskTries = 0;
819
820 if (WAITING_4_GRPMSG2 == pKeyMgmtInfo->rom.keyMgmtState) {
821 /* sendEventRsnConnect(connPtr, pKeyMgmtInfo); */
822 pm_fns->Hostsa_sendEventRsnConnect(priv->pmlan_private,
823 connPtr->mac_addr);
824 }
825
826 pKeyMgmtInfo->rom.keyMgmtState = HSK_END;
827
828 return SUCCESS;
829 }
830
831 Status_e
GenerateApEapolMsg(hostsa_private * priv,t_void * pconnPtr,keyMgmtState_e msgState)832 GenerateApEapolMsg(hostsa_private *priv,
833 t_void *pconnPtr, keyMgmtState_e msgState)
834 {
835 cm_Connection *connPtr = (cm_Connection *)pconnPtr;
836 Status_e status;
837 // OSASysContext prevContext;
838
839 if (connPtr->timer_is_set) {
840 KeyMgmtStopHskTimer((t_void *)connPtr);
841 }
842 /* If msgState is any waiting_** state,
843 ** it will decrease to corresponding **_pending state.
844 */
845 /* Note: it will reduce the if checks
846 */
847 if ((msgState & 0x1) == 0) {
848 msgState--;
849 }
850 connPtr->staData.keyMgmtInfo.rom.keyMgmtState = msgState;
851
852 if (msgState == MSG1_PENDING) {
853 status = GeneratePWKMsg1(priv, connPtr);
854 } else if (msgState == MSG3_PENDING) {
855 status = GeneratePWKMsg3(priv, connPtr);
856 } else if ((msgState == GRPMSG1_PENDING)
857 || (msgState == GRP_REKEY_MSG1_PENDING)) {
858 status = GenerateGrpMsg1(priv, connPtr);
859 } else {
860 //This should not happen
861 return FAIL;
862 }
863 if (SUCCESS == status) {
864 connPtr->staData.keyMgmtInfo.rom.keyMgmtState++;
865 }
866
867 if (SUCCESS == status) {
868 connPtr->staData.keyMgmtInfo.numHskTries++;
869 /* we are starting the timer irrespective of whether the msg generation is
870 sucessful or not. This is because, if the msg generation fails because
871 of buffer unavailabilty then we can re-try the msg after the timeout
872 period. */
873 if (!connPtr->timer_is_set)
874 KeyMgmtStartHskTimer(connPtr);
875 }
876
877 return status;
878 }
879
880 //#endif // AUTHENTICATOR
881
882 void
ApMicErrTimerExpCb(t_void * context)883 ApMicErrTimerExpCb(t_void *context)
884 {
885 cm_Connection *connPtr = (cm_Connection *)context;
886 phostsa_private priv;
887 // UINT32 int_save;
888 apInfo_t *pApInfo;
889
890 if (connPtr == NULL) {
891 //no AP connection. Do nothing, just return
892 return;
893 }
894 priv = (phostsa_private)connPtr->priv;
895 if (!priv)
896 return;
897 pApInfo = &priv->apinfo;
898
899 switch (connPtr->staData.apMicError.status) {
900 case FIRST_MIC_FAIL_IN_60_SEC:
901 connPtr->staData.apMicError.status = NO_MIC_FAILURE;
902 break;
903 case SECOND_MIC_FAIL_IN_60_SEC:
904 if ((pApInfo->bssConfig.RsnConfig.mcstCipher.tkip) &&
905 IsAuthenticatorEnabled(priv)) {
906 // re-enable the group re-key timer
907 pApInfo->bssData.grpRekeyCntRemaining
908 = pApInfo->bssData.grpRekeyCntConfigured;
909 }
910 connPtr->staData.apMicError.status = NO_MIC_FAILURE;
911 connPtr->staData.apMicError.disableStaAsso = 0;
912
913 break;
914 default:
915 break;
916 }
917 }
918
919 void
ApMicCounterMeasureInvoke(t_void * pconnPtr)920 ApMicCounterMeasureInvoke(t_void *pconnPtr)
921 {
922 cm_Connection *connPtr = (cm_Connection *)pconnPtr;
923 phostsa_private priv = (phostsa_private)connPtr->priv;
924 hostsa_mlan_fns *pm_fns = &priv->mlan_fns;
925 hostsa_util_fns *util_fns = &priv->util_fns;
926 apInfo_t *pApInfo = &priv->apinfo;
927
928 if (connPtr->staData.apMicError.MICCounterMeasureEnabled) {
929 switch (connPtr->staData.apMicError.status) {
930 case NO_MIC_FAILURE:
931 util_fns->moal_start_timer(util_fns->pmoal_handle,
932 connPtr->staData.apMicTimer,
933 MFALSE, MRVDRV_TIMER_60S);
934 connPtr->staData.apMicError.status =
935 FIRST_MIC_FAIL_IN_60_SEC;
936 break;
937
938 case FIRST_MIC_FAIL_IN_60_SEC:
939 connPtr->staData.apMicError.disableStaAsso = 1;
940 connPtr->staData.apMicError.status =
941 SECOND_MIC_FAIL_IN_60_SEC;
942 //start timer for 60 seconds
943 util_fns->moal_stop_timer(util_fns->pmoal_handle,
944 connPtr->staData.apMicTimer);
945 util_fns->moal_start_timer(util_fns->pmoal_handle,
946 connPtr->staData.apMicTimer,
947 MFALSE, MRVDRV_TIMER_60S);
948
949 /* smeAPStateMgr_sendSmeMsg(connPtr, MlmeApBcastDisassoc); */
950 pm_fns->Hostsa_DisAssocAllSta(priv->pmlan_private,
951 IEEEtypes_REASON_MIC_FAILURE);
952 // if current GTK is tkip
953 if ((pApInfo->bssConfig.RsnConfig.mcstCipher.tkip) &&
954 IsAuthenticatorEnabled(priv)) {
955 //Disable periodic group rekey and re-init GTK.
956 priv->GrpRekeyTimerIsSet = MFALSE;
957 pApInfo->bssData.grpRekeyCntRemaining = 0;
958 ReInitGTK(priv);
959 }
960 break;
961
962 default:
963 break;
964 }
965 }
966 return;
967 }
968