2  *************************************************************************
 
   4  * 5F., No.36, Taiyuan St., Jhubei City,
 
   8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
 
  10  * This program is free software; you can redistribute it and/or modify  *
 
  11  * it under the terms of the GNU General Public License as published by  *
 
  12  * the Free Software Foundation; either version 2 of the License, or     *
 
  13  * (at your option) any later version.                                   *
 
  15  * This program is distributed in the hope that it will be useful,       *
 
  16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
  17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
  18  * GNU General Public License for more details.                          *
 
  20  * You should have received a copy of the GNU General Public License     *
 
  21  * along with this program; if not, write to the                         *
 
  22  * Free Software Foundation, Inc.,                                       *
 
  23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
  25  *************************************************************************
 
  34         --------        ----------              ----------------------------------------------
 
  35         Jan     Lee             03-07-22                Initial
 
  36         Paul Lin        03-11-28                Modify for supplicant
 
  38 #include "../rt_config.h"
 
  41 #define         WPA2RSNIE       0x30
 
  43 //extern UCHAR BIT8[];
 
  44 UCHAR   CipherWpaPskTkip[] = {
 
  46                 0x00, 0x50, 0xf2, 0x01, // oui
 
  47                 0x01, 0x00,                             // Version
 
  48                 0x00, 0x50, 0xf2, 0x02, // Multicast
 
  49                 0x01, 0x00,                             // Number of unicast
 
  50                 0x00, 0x50, 0xf2, 0x02, // unicast
 
  51                 0x01, 0x00,                             // number of authentication method
 
  52                 0x00, 0x50, 0xf2, 0x02  // authentication
 
  54 UCHAR   CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
 
  56 UCHAR   CipherWpaPskAes[] = {
 
  58                 0x00, 0x50, 0xf2, 0x01, // oui
 
  59                 0x01, 0x00,                             // Version
 
  60                 0x00, 0x50, 0xf2, 0x04, // Multicast
 
  61                 0x01, 0x00,                             // Number of unicast
 
  62                 0x00, 0x50, 0xf2, 0x04, // unicast
 
  63                 0x01, 0x00,                             // number of authentication method
 
  64                 0x00, 0x50, 0xf2, 0x02  // authentication
 
  66 UCHAR   CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
 
  68 UCHAR   CipherSuiteCiscoCCKM[] = {
 
  70                 0x00, 0x50, 0xf2, 0x01, // oui
 
  71                 0x01, 0x00,                             // Version
 
  72                 0x00, 0x40, 0x96, 0x01, // Multicast
 
  73                 0x01, 0x00,                             // Number of uicast
 
  74                 0x00, 0x40, 0x96, 0x01, // unicast
 
  75                 0x01, 0x00,                             // number of authentication method
 
  76                 0x00, 0x40, 0x96, 0x00  // Authentication
 
  78 UCHAR   CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
 
  80 UCHAR   CipherSuiteCiscoCCKM24[] = {
 
  82                 0x00, 0x50, 0xf2, 0x01, // oui
 
  83                 0x01, 0x00,                             // Version
 
  84                 0x00, 0x40, 0x96, 0x01, // Multicast
 
  85                 0x01, 0x00,                             // Number of uicast
 
  86                 0x00, 0x40, 0x96, 0x01, // unicast
 
  87                 0x01, 0x00,                             // number of authentication method
 
  88                 0x00, 0x40, 0x96, 0x00,
 
  89                 0x28, 0x00// Authentication
 
  92 UCHAR   CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
 
  94 UCHAR   CipherSuiteCCXTkip[] = {
 
  96                 0x00, 0x50, 0xf2, 0x01, // oui
 
  97                 0x01, 0x00,                             // Version
 
  98                 0x00, 0x50, 0xf2, 0x02, // Multicast
 
  99                 0x01, 0x00,                             // Number of unicast
 
 100                 0x00, 0x50, 0xf2, 0x02, // unicast
 
 101                 0x01, 0x00,                             // number of authentication method
 
 102                 0x00, 0x50, 0xf2, 0x01  // authentication
 
 104 UCHAR   CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
 
 106 UCHAR   CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
 
 107 UCHAR   LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
 
 109 UCHAR   EAPOL_FRAME[] = {0x88, 0x8E};
 
 112         IN  PRTMP_ADAPTER   pAd,
 
 117 void inc_byte_array(UCHAR *counter, int len);
 
 120         ========================================================================
 
 123                 Classify WPA EAP message type
 
 126                 EAPType         Value of EAP message type
 
 127                 MsgType         Internal Message definition for MLME state machine
 
 130                 TRUE            Found appropriate message type
 
 131                 FALSE           No appropriate message type
 
 133         IRQL = DISPATCH_LEVEL
 
 136                 All these constants are defined in wpa.h
 
 137                 For supplicant, there is only EAPOL Key message avaliable
 
 139         ========================================================================
 
 141 BOOLEAN WpaMsgTypeSubst(
 
 148                         *MsgType = MT2_EAPPacket;
 
 151                         *MsgType = MT2_EAPOLStart;
 
 154                         *MsgType = MT2_EAPOLLogoff;
 
 157                         *MsgType = MT2_EAPOLKey;
 
 160                         *MsgType = MT2_EAPOLASFAlert;
 
 169         ==========================================================================
 
 171                 association     state machine init,     including state transition and timer init
 
 173                 S -     pointer to the association state machine
 
 174         ==========================================================================
 
 176 VOID WpaPskStateMachineInit(
 
 177         IN      PRTMP_ADAPTER   pAd,
 
 179         OUT     STATE_MACHINE_FUNC Trans[])
 
 181         StateMachineInit(S,     Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
 
 182         StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
 
 186         ==========================================================================
 
 188                 This is state machine function.
 
 189                 When receiving EAPOL packets which is  for 802.1x key management.
 
 190                 Use     both in WPA, and WPAPSK case.
 
 191                 In this function, further dispatch to different functions according     to the received packet.  3 categories are :
 
 192                   1.  normal 4-way pairwisekey and 2-way groupkey handshake
 
 193                   2.  MIC error (Countermeasures attack)  report packet from STA.
 
 194                   3.  Request for pairwise/group key update     from STA
 
 196         ==========================================================================
 
 198 VOID WpaEAPOLKeyAction(
 
 199         IN      PRTMP_ADAPTER   pAd,
 
 200         IN      MLME_QUEUE_ELEM *Elem)
 
 203         INT             MsgType = EAPOL_MSG_INVALID;
 
 204         PKEY_DESCRIPTER pKeyDesc;
 
 205         PHEADER_802_11  pHeader; //red
 
 206         UCHAR           ZeroReplay[LEN_KEY_DESC_REPLAY];
 
 208         KEY_INFO                peerKeyInfo;
 
 210         DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
 
 212         // Get 802.11 header first
 
 213         pHeader = (PHEADER_802_11) Elem->Msg;
 
 215         // Get EAPoL-Key Descriptor
 
 216         pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
 
 218         NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
 
 219         NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
 
 221         *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
 
 224         // 1. Check EAPOL frame version and type
 
 225         EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
 
 227     if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
 
 229         DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
 
 233         // First validate replay counter, only accept message with larger replay counter
 
 234         // Let equal pass, some AP start with all zero replay counter
 
 235         NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
 
 237         if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
 
 238                 (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
 
 240                 DBGPRINT(RT_DEBUG_ERROR, ("   ReplayCounter not match   \n"));
 
 244         // Process WPA2PSK frame
 
 245         if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
 
 247                 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
 
 248                         (peerKeyInfo.EKD_DL == 0) &&
 
 249                         (peerKeyInfo.KeyAck == 1) &&
 
 250                         (peerKeyInfo.KeyMic == 0) &&
 
 251                         (peerKeyInfo.Secure == 0) &&
 
 252                         (peerKeyInfo.Error == 0) &&
 
 253                         (peerKeyInfo.Request == 0))
 
 255                         MsgType = EAPOL_PAIR_MSG_1;
 
 256                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
 
 257                 } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
 
 258                         (peerKeyInfo.EKD_DL  == 1) &&
 
 259                         (peerKeyInfo.KeyAck == 1) &&
 
 260                         (peerKeyInfo.KeyMic == 1) &&
 
 261                         (peerKeyInfo.Secure == 1) &&
 
 262                         (peerKeyInfo.Error == 0) &&
 
 263                         (peerKeyInfo.Request == 0))
 
 265                         MsgType = EAPOL_PAIR_MSG_3;
 
 266                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
 
 267                 } else if((peerKeyInfo.KeyType == GROUPKEY) &&
 
 268                         (peerKeyInfo.EKD_DL == 1) &&
 
 269                         (peerKeyInfo.KeyAck == 1) &&
 
 270                         (peerKeyInfo.KeyMic == 1) &&
 
 271                         (peerKeyInfo.Secure == 1) &&
 
 272                         (peerKeyInfo.Error == 0) &&
 
 273                         (peerKeyInfo.Request == 0))
 
 275                         MsgType = EAPOL_GROUP_MSG_1;
 
 276                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
 
 279                 // We will assume link is up (assoc suceess and port not secured).
 
 280                 // All state has to be able to process message from previous state
 
 281                 switch(pAd->StaCfg.WpaState)
 
 284                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 286                                 Wpa2PairMsg1Action(pAd, Elem);
 
 287                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 292                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 294                                 Wpa2PairMsg1Action(pAd, Elem);
 
 295                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 297                         else if(MsgType == EAPOL_PAIR_MSG_3)
 
 299                                 Wpa2PairMsg3Action(pAd, Elem);
 
 300                                 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
 
 304                 case SS_WAIT_GROUP:             // When doing group key exchange
 
 305                 case SS_FINISH:                 // This happened when update group key
 
 306                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 308                             // Reset port secured variable
 
 309                                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 310                                 Wpa2PairMsg1Action(pAd, Elem);
 
 311                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 313                         else if(MsgType == EAPOL_PAIR_MSG_3)
 
 315                             // Reset port secured variable
 
 316                                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 317                                 Wpa2PairMsg3Action(pAd, Elem);
 
 318                                 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
 
 320                         else if(MsgType == EAPOL_GROUP_MSG_1)
 
 322                                 WpaGroupMsg1Action(pAd, Elem);
 
 323                                 pAd->StaCfg.WpaState = SS_FINISH;
 
 331         // Process WPAPSK Frame
 
 332         // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
 
 333         else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
 
 335                 if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
 
 336                         (peerKeyInfo.KeyIndex == 0) &&
 
 337                         (peerKeyInfo.KeyAck == 1) &&
 
 338                         (peerKeyInfo.KeyMic == 0) &&
 
 339                         (peerKeyInfo.Secure == 0) &&
 
 340                         (peerKeyInfo.Error == 0) &&
 
 341                         (peerKeyInfo.Request == 0))
 
 343                         MsgType = EAPOL_PAIR_MSG_1;
 
 344                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
 
 346                 else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
 
 347                         (peerKeyInfo.KeyIndex == 0) &&
 
 348                         (peerKeyInfo.KeyAck == 1) &&
 
 349                         (peerKeyInfo.KeyMic == 1) &&
 
 350                         (peerKeyInfo.Secure == 0) &&
 
 351                         (peerKeyInfo.Error == 0) &&
 
 352                         (peerKeyInfo.Request == 0))
 
 354                         MsgType = EAPOL_PAIR_MSG_3;
 
 355                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
 
 357                 else if((peerKeyInfo.KeyType == GROUPKEY) &&
 
 358                         (peerKeyInfo.KeyIndex != 0) &&
 
 359                         (peerKeyInfo.KeyAck == 1) &&
 
 360                         (peerKeyInfo.KeyMic == 1) &&
 
 361                         (peerKeyInfo.Secure == 1) &&
 
 362                         (peerKeyInfo.Error == 0) &&
 
 363                         (peerKeyInfo.Request == 0))
 
 365                         MsgType = EAPOL_GROUP_MSG_1;
 
 366                         DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
 
 369                 // We will assume link is up (assoc suceess and port not secured).
 
 370                 // All state has to be able to process message from previous state
 
 371                 switch(pAd->StaCfg.WpaState)
 
 374                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 376                                 WpaPairMsg1Action(pAd, Elem);
 
 377                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 382                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 384                                 WpaPairMsg1Action(pAd, Elem);
 
 385                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 387                         else if(MsgType == EAPOL_PAIR_MSG_3)
 
 389                                 WpaPairMsg3Action(pAd, Elem);
 
 390                                 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
 
 394                 case SS_WAIT_GROUP:             // When doing group key exchange
 
 395                 case SS_FINISH:                 // This happened when update group key
 
 396                         if(MsgType == EAPOL_PAIR_MSG_1)
 
 398                                 WpaPairMsg1Action(pAd, Elem);
 
 399                                 pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
 
 400                                 // Reset port secured variable
 
 401                                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 403                         else if(MsgType == EAPOL_PAIR_MSG_3)
 
 405                                 WpaPairMsg3Action(pAd, Elem);
 
 406                                 pAd->StaCfg.WpaState = SS_WAIT_GROUP;
 
 407                                 // Reset port secured variable
 
 408                                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 410                         else if(MsgType == EAPOL_GROUP_MSG_1)
 
 412                                 WpaGroupMsg1Action(pAd, Elem);
 
 413                                 pAd->StaCfg.WpaState = SS_FINISH;
 
 422         DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
 
 426         ========================================================================
 
 429                 Process Pairwise key 4-way handshaking
 
 432                 pAd     Pointer to our adapter
 
 440         ========================================================================
 
 442 VOID    WpaPairMsg1Action(
 
 443         IN  PRTMP_ADAPTER   pAd,
 
 444         IN  MLME_QUEUE_ELEM *Elem)
 
 446         PHEADER_802_11      pHeader;
 
 447         UCHAR                           *mpool, *PTK, *digest;
 
 448         PUCHAR              pOutBuffer = NULL;
 
 449         UCHAR               Header802_3[14];
 
 455         DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
 
 457         // allocate memory pool
 
 458         os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
 
 464         PTK = (UCHAR *) ROUND_UP(mpool, 4);
 
 466         digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
 
 468         pHeader = (PHEADER_802_11) Elem->Msg;
 
 470         // Process message 1 from authenticator
 
 471         pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
 
 473         // 1. Save Replay counter, it will use to verify message 3 and construct message 2
 
 474         NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 477         NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
 
 479         // Generate random SNonce
 
 480         GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
 
 482         // Calc PTK(ANonce, SNonce)
 
 486                 pAd->CommonCfg.Bssid,
 
 492         // Save key to PTK entry
 
 493         NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
 
 495         // init 802.3 header and Fill Packet
 
 496         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
 498         // Zero Message 2 body
 
 499         NdisZeroMemory(&Packet, sizeof(Packet));
 
 500         Packet.ProVer   = EAPOL_VER;
 
 501         Packet.ProType  = EAPOLKey;
 
 503         // Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
 
 505         Packet.KeyDesc.Type = WPA1_KEY_DESC;
 
 506         // 1. Key descriptor version and appropriate RSN IE
 
 507         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
 509                 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
 
 513                 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
 
 516         // fill in Data Material and its length
 
 517         Packet.KeyDesc.KeyData[0] = IE_WPA;
 
 518         Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
 
 519         Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
 
 520         NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
 
 522         // Update packet length after decide Key data payload
 
 523         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
 
 526         Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
 
 527         Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
 
 528         // 2. Key Type PeerKey
 
 529         Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
 
 531         // 3. KeyMic field presented
 
 532         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
 534         //Convert to little-endian format.
 
 535         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
 539         NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
 
 541         // 5. Key Replay Count
 
 542         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 544         // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
 
 545         // Out buffer for transmitting message 2
 
 546         MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
 
 547         if(pOutBuffer == NULL)
 
 549                 os_free_mem(pAd, mpool);
 
 552         // Prepare EAPOL frame for MIC calculation
 
 553         // Be careful, only EAPOL frame is counted for MIC calculation
 
 554         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
 
 555                 Packet.Body_Len[1] + 4,    &Packet,
 
 558         // 6. Prepare and Fill MIC value
 
 559         NdisZeroMemory(Mic, sizeof(Mic));
 
 560         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
 563                 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
 
 564                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
 568                 hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
 570         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
 572         //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
 
 574                 MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
 
 575                                                 LENGTH_802_3,                           &Header802_3,
 
 576                                                 Packet.Body_Len[1] + 4,    &Packet,
 
 580         // 5. Copy frame to Tx ring and send Msg 2 to authenticator
 
 581         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
 
 583         MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
 
 584         os_free_mem(pAd, (PUCHAR)mpool);
 
 586         DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
 
 589 VOID Wpa2PairMsg1Action(
 
 590         IN  PRTMP_ADAPTER   pAd,
 
 591         IN  MLME_QUEUE_ELEM *Elem)
 
 593         PHEADER_802_11      pHeader;
 
 594         UCHAR                           *mpool, *PTK, *digest;
 
 595         PUCHAR              pOutBuffer = NULL;
 
 596         UCHAR               Header802_3[14];
 
 602         DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
 
 604         // allocate memory pool
 
 605         os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
 
 611         PTK = (UCHAR *) ROUND_UP(mpool, 4);
 
 613         digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
 
 615         pHeader = (PHEADER_802_11) Elem->Msg;
 
 617         // Process message 1 from authenticator
 
 618                 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
 
 620         // 1. Save Replay counter, it will use to verify message 3 and construct message 2
 
 621         NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 624         NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
 
 626         // Generate random SNonce
 
 627         GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
 
 629         if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
 
 634         // Calc PTK(ANonce, SNonce)
 
 638                 pAd->CommonCfg.Bssid,
 
 644         // Save key to PTK entry
 
 645         NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
 
 647         // init 802.3 header and Fill Packet
 
 648         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
 650         // Zero message 2 body
 
 651         NdisZeroMemory(&Packet, sizeof(Packet));
 
 652         Packet.ProVer   = EAPOL_VER;
 
 653         Packet.ProType  = EAPOLKey;
 
 655         // Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
 
 657         Packet.KeyDesc.Type = WPA2_KEY_DESC;
 
 659         // 1. Key descriptor version and appropriate RSN IE
 
 660         if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
 662                 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
 
 666                 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
 
 669         // fill in Data Material and its length
 
 670         Packet.KeyDesc.KeyData[0] = IE_WPA2;
 
 671         Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
 
 672         Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
 
 673         NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
 
 675         // Update packet length after decide Key data payload
 
 676         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
 
 678         // 2. Key Type PeerKey
 
 679         Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
 
 681         // 3. KeyMic field presented
 
 682         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
 685         Packet.KeyDesc.KeyLength[0] = 0;
 
 686         Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
 
 689         NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
 
 691         // 5. Key Replay Count
 
 692         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 694         // Convert to little-endian format.
 
 695         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
 697         // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
 
 698         // Out buffer for transmitting message 2
 
 699         MlmeAllocateMemory(pAd,  (PUCHAR *)&pOutBuffer);  // allocate memory
 
 700         if(pOutBuffer == NULL)
 
 702                 os_free_mem(pAd, mpool);
 
 706         // Prepare EAPOL frame for MIC calculation
 
 707         // Be careful, only EAPOL frame is counted for MIC calculation
 
 708         MakeOutgoingFrame(pOutBuffer,        &FrameLen,
 
 709                 Packet.Body_Len[1] + 4, &Packet,
 
 712         // 6. Prepare and Fill MIC value
 
 713         NdisZeroMemory(Mic, sizeof(Mic));
 
 714         if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
 717                 HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
 
 718                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
 722                 hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
 724         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
 727         // Make  Transmitting frame
 
 728         MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
 
 729                                                 LENGTH_802_3,                   &Header802_3,
 
 730                                                 Packet.Body_Len[1] + 4, &Packet,
 
 734         // 5. Copy frame to Tx ring
 
 735         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
 
 737         MlmeFreeMemory(pAd, pOutBuffer);
 
 738         os_free_mem(pAd, mpool);
 
 740         DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
 
 745         ========================================================================
 
 748                 Process Pairwise key 4-way handshaking
 
 751                 pAd     Pointer to our adapter
 
 759         ========================================================================
 
 761 VOID    WpaPairMsg3Action(
 
 762         IN      PRTMP_ADAPTER   pAd,
 
 763         IN      MLME_QUEUE_ELEM *Elem)
 
 766         PHEADER_802_11      pHeader;
 
 767         PUCHAR                  pOutBuffer = NULL;
 
 768         UCHAR               Header802_3[14];
 
 772         UCHAR                   Mic[16], OldMic[16];
 
 773         MAC_TABLE_ENTRY         *pEntry = NULL;
 
 775         KEY_INFO                        peerKeyInfo;
 
 777         DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
 
 779         // Record 802.11 header & the received EAPOL packet Msg3
 
 780         pHeader = (PHEADER_802_11) Elem->Msg;
 
 781         pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
 
 783         NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
 
 784         NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
 
 786         *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
 
 789         // 1. Verify cipher type match
 
 790         if (pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
 
 794         else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
 
 800         //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
 
 801         if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
 
 803                 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
 
 804                 hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
 
 805                 hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
 
 809                 DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
 
 812         // 2. Check MIC value
 
 813         // Save the MIC and replace with zero
 
 814         NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
 815         NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
 816         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
 821                 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
 822                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
 826                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
 
 829         if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
 
 831                 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
 
 835                 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
 
 837         // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
 
 838         if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
 
 841         // Update new replay counter
 
 842         NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 844         // 4. Double check ANonce
 
 845         if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
 
 848         // init 802.3 header and Fill Packet
 
 849         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
 851         // Zero Message 4 body
 
 852         NdisZeroMemory(&Packet, sizeof(Packet));
 
 853         Packet.ProVer   = EAPOL_VER;
 
 854         Packet.ProType  = EAPOLKey;
 
 855         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;                // No data field
 
 858         // Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
 
 860         Packet.KeyDesc.Type = WPA1_KEY_DESC;
 
 862         // Key descriptor version and appropriate RSN IE
 
 863         Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
 
 866         Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
 
 867         Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
 
 870         Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
 
 872         // KeyMic field presented
 
 873         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
 875         // In Msg3,  KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
 
 876         // Station sends Msg4  KeyInfo.secure should be the same as that in Msg.3
 
 877         Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
 
 879         // Convert to little-endian format.
 
 880         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
 883         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
 885         // Out buffer for transmitting message 4
 
 886         MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
 
 887         if(pOutBuffer == NULL)
 
 890         // Prepare EAPOL frame for MIC calculation
 
 891         // Be careful, only EAPOL frame is counted for MIC calculation
 
 892         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
 
 893                 Packet.Body_Len[1] + 4,    &Packet,
 
 896         // Prepare and Fill MIC value
 
 897         NdisZeroMemory(Mic, sizeof(Mic));
 
 898         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
 903                 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
 904                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
 908                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
 910         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
 913         // Prepare pair-wise key information into shared key table
 
 914         NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
 
 915         pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
 
 916     NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
 
 917         NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
 
 918         NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
 
 920         // Decide its ChiperAlg
 
 921         if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
 
 922                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
 
 923         else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
 
 924                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
 
 926                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
 
 928         // Update these related information to MAC_TABLE_ENTRY
 
 929         pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
 930         NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
 
 931         NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
 
 932         NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
 
 933         pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
 
 935         // Update pairwise key information to ASIC Shared Key Table
 
 936         AsicAddSharedKeyEntry(pAd,
 
 939                                                   pAd->SharedKey[BSS0][0].CipherAlg,
 
 940                                                   pAd->SharedKey[BSS0][0].Key,
 
 941                                                   pAd->SharedKey[BSS0][0].TxMic,
 
 942                                                   pAd->SharedKey[BSS0][0].RxMic);
 
 944         // Update ASIC WCID attribute table and IVEIV table
 
 945         RTMPAddWcidAttributeEntry(pAd,
 
 948                                                           pAd->SharedKey[BSS0][0].CipherAlg,
 
 951         // Make transmitting frame
 
 952         MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
 
 953                                                 LENGTH_802_3,                   &Header802_3,
 
 954                                                 Packet.Body_Len[1] + 4, &Packet,
 
 958         // Copy frame to Tx ring and Send Message 4 to authenticator
 
 959         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
 
 961         MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
 
 963         DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
 
 966 VOID    Wpa2PairMsg3Action(
 
 967         IN  PRTMP_ADAPTER   pAd,
 
 968         IN  MLME_QUEUE_ELEM *Elem)
 
 971         PHEADER_802_11      pHeader;
 
 972         PUCHAR              pOutBuffer = NULL;
 
 973         UCHAR               Header802_3[14];
 
 977         UCHAR               Mic[16], OldMic[16];
 
 978         UCHAR               *mpool, *KEYDATA, *digest;
 
 980         MAC_TABLE_ENTRY         *pEntry = NULL;
 
 981         KEY_INFO                        peerKeyInfo;
 
 984         os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
 
 989         // KEYDATA Len = 512.
 
 990         KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
 
 992         digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
 
 994         DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
 
 996         pHeader = (PHEADER_802_11) Elem->Msg;
 
 998         // Process message 3 frame.
 
 999         pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
 
1001         NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
 
1002         NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
 
1004         *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
 
1006         // 1. Verify cipher type match
 
1007         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
 
1009                 os_free_mem(pAd, (PUCHAR)mpool);
 
1012         else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
 
1014                 os_free_mem(pAd, (PUCHAR)mpool);
 
1018         // 2. Check MIC value
 
1019         // Save the MIC and replace with zero
 
1020         NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
1021         NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
1022         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
1025                 HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
1026                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
1030                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
 
1033         if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
 
1035                 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
 
1036                 os_free_mem(pAd, (PUCHAR)mpool);
 
1040                 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
 
1042         // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
 
1043         if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
 
1045                 os_free_mem(pAd, (PUCHAR)mpool);
 
1049         // Update new replay counter
 
1050         NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
1052         // 4. Double check ANonce
 
1053         if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
 
1055                 os_free_mem(pAd, (PUCHAR)mpool);
 
1060         // 5. Decrypt GTK from Key Data
 
1061         DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
 
1062         if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
1065                 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
 
1071                 // Construct 32 bytes RC4 Key
 
1072                 NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
 
1073                 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
 
1074                 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
 
1075                 //discard first 256 bytes
 
1076                 for(i = 0; i < 256; i++)
 
1077                         ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
 
1078                 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
 
1079                 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
 
1082         if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
 
1084                 os_free_mem(pAd, (PUCHAR)mpool);
 
1088         // Update GTK to ASIC
 
1089         // Update group key information to ASIC Shared Key Table
 
1090         AsicAddSharedKeyEntry(pAd,
 
1092                                                   pAd->StaCfg.DefaultKeyId,
 
1093                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 
1094                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
 
1095                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
 
1096                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
 
1098         // Update ASIC WCID attribute table and IVEIV table
 
1099         RTMPAddWcidAttributeEntry(pAd,
 
1101                                                           pAd->StaCfg.DefaultKeyId,
 
1102                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 
1105         // init 802.3 header and Fill Packet
 
1106         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
1108         // Zero message 4 body
 
1109         NdisZeroMemory(&Packet, sizeof(Packet));
 
1110         Packet.ProVer   = EAPOL_VER;
 
1111         Packet.ProType  = EAPOLKey;
 
1112         Packet.Body_Len[1]      = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;            // No data field
 
1115         // Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
 
1117         Packet.KeyDesc.Type = WPA2_KEY_DESC;
 
1119         // Key descriptor version and appropriate RSN IE
 
1120         Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
 
1122         // Update Key Length
 
1123         Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
 
1124         Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
 
1127         Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
 
1129         // KeyMic field presented
 
1130         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
1131         Packet.KeyDesc.KeyInfo.Secure = 1;
 
1133         // Convert to little-endian format.
 
1134         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
1137         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
1139         // Out buffer for transmitting message 4
 
1140         MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
 
1141         if(pOutBuffer == NULL)
 
1143                 os_free_mem(pAd, (PUCHAR)mpool);
 
1147         // Prepare EAPOL frame for MIC calculation
 
1148         // Be careful, only EAPOL frame is counted for MIC calculation
 
1149         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
 
1150                 Packet.Body_Len[1] + 4,    &Packet,
 
1153         // Prepare and Fill MIC value
 
1154         NdisZeroMemory(Mic, sizeof(Mic));
 
1155         if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
1158                 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
1159                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
1163                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
1165         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
1168         // Prepare pair-wise key information into shared key table
 
1169         NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
 
1170         pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
 
1171     NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
 
1172         NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
 
1173         NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
 
1175         // Decide its ChiperAlg
 
1176         if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
 
1177                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
 
1178         else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
 
1179                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
 
1181                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
 
1183         // Update these related information to MAC_TABLE_ENTRY
 
1184         pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
1185         NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
 
1186         NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
 
1187         NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
 
1188         pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
 
1190         // Update pairwise key information to ASIC Shared Key Table
 
1191         AsicAddSharedKeyEntry(pAd,
 
1194                                                   pAd->SharedKey[BSS0][0].CipherAlg,
 
1195                                                   pAd->SharedKey[BSS0][0].Key,
 
1196                                                   pAd->SharedKey[BSS0][0].TxMic,
 
1197                                                   pAd->SharedKey[BSS0][0].RxMic);
 
1199         // Update ASIC WCID attribute table and IVEIV table
 
1200         RTMPAddWcidAttributeEntry(pAd,
 
1203                                                           pAd->SharedKey[BSS0][0].CipherAlg,
 
1206         // Make  Transmitting frame
 
1207         MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
 
1208                                                 LENGTH_802_3,                   &Header802_3,
 
1209                                                 Packet.Body_Len[1] + 4, &Packet,
 
1213         // Copy frame to Tx ring and Send Message 4 to authenticator
 
1214         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
 
1216         // set 802.1x port control
 
1217         STA_PORT_SECURED(pAd);
 
1219     // Indicate Connected for GUI
 
1220     pAd->IndicateMediaState = NdisMediaStateConnected;
 
1222         MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
 
1223         os_free_mem(pAd, (PUCHAR)mpool);
 
1226         // send wireless event - for set key done WPA2
 
1227         if (pAd->CommonCfg.bWirelessEvent)
 
1228                 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
 
1230         DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
 
1235         ========================================================================
 
1237         Routine Description:
 
1238                 Process Group key 2-way handshaking
 
1241                 pAd     Pointer to our adapter
 
1249         ========================================================================
 
1251 VOID    WpaGroupMsg1Action(
 
1252         IN      PRTMP_ADAPTER   pAd,
 
1253         IN      MLME_QUEUE_ELEM *Elem)
 
1256         PUCHAR              pOutBuffer = NULL;
 
1257         UCHAR               Header802_3[14];
 
1259         EAPOL_PACKET        Packet;
 
1260         PEAPOL_PACKET       pGroup;
 
1261         UCHAR               *mpool, *digest, *KEYDATA;
 
1262         UCHAR               Mic[16], OldMic[16];
 
1263         UCHAR               GTK[32], Key[32];
 
1264         KEY_INFO                        peerKeyInfo;
 
1267         os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
 
1273         digest = (UCHAR *) ROUND_UP(mpool, 4);
 
1274         // KEYDATA Len = 512.
 
1275         KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
 
1277         DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
 
1279         // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
 
1280         pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
 
1282         NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
 
1283         NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
 
1285         *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
 
1287         // 0. Check cipher type match
 
1288         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
 
1290                 os_free_mem(pAd, (PUCHAR)mpool);
 
1293         else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
 
1295                 os_free_mem(pAd, (PUCHAR)mpool);
 
1299         // 1. Verify Replay counter
 
1300         //    Check Replay Counter, it has to be larger than last one. No need to be exact one larger
 
1301         if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
 
1303                 os_free_mem(pAd, (PUCHAR)mpool);
 
1307         // Update new replay counter
 
1308         NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
1310         // 2. Verify MIC is valid
 
1311         // Save the MIC and replace with zero
 
1312         NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
1313         NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
 
1315         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
1317                 HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
1318                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
1322                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
 
1325         if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
 
1327                 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
 
1328                 MlmeFreeMemory(pAd, (PUCHAR)mpool);
 
1332                 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
 
1335         // 3. Decrypt GTK from Key Data
 
1336         if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
 
1339                 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA,  pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
 
1346                 // Construct 32 bytes RC4 Key
 
1347                 NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
 
1348                 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
 
1349                 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
 
1350                 //discard first 256 bytes
 
1351                 for(i = 0; i < 256; i++)
 
1352                         ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
 
1353                 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
 
1354                 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
 
1357         // Process decrypted key data material
 
1358         // Parse keyData to handle KDE format for WPA2PSK
 
1359         if (peerKeyInfo.EKD_DL)
 
1361                 if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
 
1363                         os_free_mem(pAd, (PUCHAR)mpool);
 
1369                 // set key material, TxMic and RxMic for WPAPSK
 
1370                 NdisMoveMemory(GTK, KEYDATA, 32);
 
1371                 NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
 
1372                 pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
 
1374                 // Prepare pair-wise key information into shared key table
 
1375                 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
 
1376                 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
 
1377                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
 
1378                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, >K[16], LEN_TKIP_RXMICK);
 
1379                 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, >K[24], LEN_TKIP_TXMICK);
 
1381                 // Update Shared Key CipherAlg
 
1382                 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
 
1383                 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
 
1384                         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
 
1385                 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
 
1386                         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
 
1388         //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
 
1391         // Update group key information to ASIC Shared Key Table
 
1392         AsicAddSharedKeyEntry(pAd,
 
1394                                                   pAd->StaCfg.DefaultKeyId,
 
1395                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 
1396                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
 
1397                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
 
1398                                                   pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
 
1400         // Update ASIC WCID attribute table and IVEIV table
 
1401         RTMPAddWcidAttributeEntry(pAd,
 
1403                                                           pAd->StaCfg.DefaultKeyId,
 
1404                                                           pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
 
1407         // set 802.1x port control
 
1408         STA_PORT_SECURED(pAd);
 
1410     // Indicate Connected for GUI
 
1411     pAd->IndicateMediaState = NdisMediaStateConnected;
 
1413         // init header and Fill Packet
 
1414         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
1416         // Zero Group message 1 body
 
1417         NdisZeroMemory(&Packet, sizeof(Packet));
 
1418         Packet.ProVer   = EAPOL_VER;
 
1419         Packet.ProType  = EAPOLKey;
 
1420         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;                // No data field
 
1423         // Group Message 2 as  EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
 
1425         if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
 
1427                 Packet.KeyDesc.Type = WPA2_KEY_DESC;
 
1431                 Packet.KeyDesc.Type = WPA1_KEY_DESC;
 
1434         // Key descriptor version and appropriate RSN IE
 
1435         Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
 
1437         // Update Key Length
 
1438         Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
 
1439         Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
 
1441         // Key Index as G-Msg 1
 
1442         if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
 
1443                 Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
 
1445         // Key Type Group key
 
1446         Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
 
1448         // KeyMic field presented
 
1449         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
1452         Packet.KeyDesc.KeyInfo.Secure  = 1;
 
1454         // Convert to little-endian format.
 
1455         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
1458         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
1460         // Out buffer for transmitting group message 2
 
1461         MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
 
1462         if(pOutBuffer == NULL)
 
1464                 MlmeFreeMemory(pAd, (PUCHAR)mpool);
 
1468         // Prepare EAPOL frame for MIC calculation
 
1469         // Be careful, only EAPOL frame is counted for MIC calculation
 
1470         MakeOutgoingFrame(pOutBuffer,           &FrameLen,
 
1471                 Packet.Body_Len[1] + 4,    &Packet,
 
1474         // Prepare and Fill MIC value
 
1475         NdisZeroMemory(Mic, sizeof(Mic));
 
1476         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
1479                 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
1480                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
1484                 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
1486         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
1489         MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
 
1490                                                 LENGTH_802_3,                   &Header802_3,
 
1491                                                 Packet.Body_Len[1] + 4, &Packet,
 
1495         // 5. Copy frame to Tx ring and prepare for encryption
 
1496         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
 
1498         // 6 Free allocated memory
 
1499         MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
 
1500         os_free_mem(pAd, (PUCHAR)mpool);
 
1502         // send wireless event - for set key done WPA2
 
1503         if (pAd->CommonCfg.bWirelessEvent)
 
1504                 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
 
1506         DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
 
1510         ========================================================================
 
1512         Routine Description:
 
1516                 pAd     Pointer to our adapter
 
1523         ========================================================================
 
1525 VOID    WpaMacHeaderInit(
 
1526         IN              PRTMP_ADAPTER   pAd,
 
1527         IN OUT  PHEADER_802_11  pHdr80211,
 
1531         NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
 
1532         pHdr80211->FC.Type      = BTYPE_DATA;
 
1533         pHdr80211->FC.ToDs      = 1;
 
1535                 pHdr80211->FC.Wep = 1;
 
1537          //     Addr1: BSSID, Addr2: SA, Addr3: DA
 
1538         COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
 
1539         COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
 
1540         COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
 
1541         pHdr80211->Sequence =   pAd->Sequence;
 
1545         ========================================================================
 
1547         Routine Description:
 
1548                 Copy frame from waiting queue into relative ring buffer and set
 
1549         appropriate ASIC register to kick hardware encryption before really
 
1553                 pAd             Pointer to our adapter
 
1554                 PNDIS_PACKET    Pointer to outgoing Ndis frame
 
1555                 NumberOfFrag    Number of fragment required
 
1562         ========================================================================
 
1564 VOID    RTMPToWirelessSta(
 
1565         IN      PRTMP_ADAPTER   pAd,
 
1566         IN  PUCHAR          pHeader802_3,
 
1570     IN  BOOLEAN                 is4wayFrame)
 
1574         PNDIS_PACKET    pPacket;
 
1579                 // 1. build a NDIS packet and call RTMPSendPacket();
 
1580                 //    be careful about how/when to release this internal allocated NDIS PACKET buffer
 
1581                 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
 
1582                 if (Status != NDIS_STATUS_SUCCESS)
 
1586                         RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
 
1588                         RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
 
1590                 // 2. send out the packet
 
1591                 Status = STASendPacket(pAd, pPacket);
 
1592                 if(Status == NDIS_STATUS_SUCCESS)
 
1594                         // Dequeue one frame from TxSwQueue0..3 queue and process it
 
1595                         // There are three place calling dequeue for TX ring.
 
1596                         // 1. Here, right after queueing the frame.
 
1597                         // 2. At the end of TxRingTxDone service routine.
 
1598                         // 3. Upon NDIS call RTMPSendPackets
 
1599                         if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
 
1600                                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
 
1602                                 for(Index = 0; Index < 5; Index ++)
 
1603                                         if(pAd->TxSwQueue[Index].Number > 0)
 
1604                                                 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
 
1612     ========================================================================
 
1614     Routine Description:
 
1615     Check Sanity RSN IE form AP
 
1622     ========================================================================
 
1625         IN  PRTMP_ADAPTER   pAd,
 
1633         BOOLEAN                         result = FALSE;
 
1639         while (len > sizeof(RSNIE2))
 
1641                 pEid = (PEID_STRUCT) pVIE;
 
1643                 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
 
1645                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
 
1646                                 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
 
1647                                 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
 
1649                                         DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
 
1653                         *Offset += (pEid->Len + 2);
 
1656                 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
 
1658                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
 
1659                                 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
 
1660                                 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
 
1662                                         DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
 
1666                         *Offset += (pEid->Len + 2);
 
1673                 pVIE += (pEid->Len + 2);
 
1674                 len  -= (pEid->Len + 2);
 
1677         DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
 
1685     ========================================================================
 
1687     Routine Description:
 
1688     Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
 
1689     GTK  is encaptulated in KDE format at  p.83 802.11i D10
 
1698     ========================================================================
 
1700 BOOLEAN ParseKeyData(
 
1701         IN  PRTMP_ADAPTER   pAd,
 
1703         IN  UCHAR           KeyDataLen,
 
1704         IN      UCHAR                   bPairewise)
 
1706     PKDE_ENCAP          pKDE = NULL;
 
1707     PUCHAR              pMyKeyData = pKeyData;
 
1708     UCHAR               KeyDataLength = KeyDataLen;
 
1712         // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
 
1715                 // Check RSN IE whether it is WPA2/WPA2PSK
 
1716                 if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
 
1718                         DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
 
1719                         hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
 
1725                         pMyKeyData += skip_offset;
 
1726                         KeyDataLength -= skip_offset;
 
1728                         //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
 
1732         DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
 
1735         if (KeyDataLength >= 8)
 
1737         pKDE = (PKDE_ENCAP) pMyKeyData;
 
1741                 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
 
1746         // Sanity check - shared key index should not be 0
 
1747         if (pKDE->GTKEncap.Kid == 0)
 
1749         DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
 
1753         // Sanity check - KED length
 
1754         if (KeyDataLength < (pKDE->Len + 2))
 
1756         DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
 
1760         // Get GTK length - refer to IEEE 802.11i-2004 p.82
 
1761         GTKLEN = pKDE->Len -6;
 
1763         if (GTKLEN < LEN_AES_KEY)
 
1765                 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
 
1769                 DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
 
1772         // set key material, TxMic and RxMic for WPAPSK
 
1773         NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
 
1774         pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
 
1776         // Update shared key table
 
1777         NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
 
1778         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
 
1779         NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
 
1780         NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
 
1781         NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
 
1783         // Update Shared Key CipherAlg
 
1784         pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
 
1785         if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
 
1786                 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
 
1787         else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
 
1788                 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
 
1795         ========================================================================
 
1797         Routine Description:
 
1798                 Cisco CCKM PRF function
 
1801                 key                             Cisco Base Transient Key (BTK)
 
1802                 key_len                 The key length of the BTK
 
1803                 data                    Ruquest Number(RN) + BSSID
 
1804                 data_len                The length of the data
 
1805                 output                  Store for PTK(Pairwise transient keys)
 
1806                 len                             The length of the output
 
1813         ========================================================================
 
1825         INT             currentindex = 0;
 
1828         NdisMoveMemory(input, data, data_len);
 
1829         total_len = data_len;
 
1830         input[total_len] = 0;
 
1832         for     (i = 0; i <     (len + 19) / 20; i++)
 
1834                 HMAC_SHA1(input, total_len,     key, key_len, &output[currentindex]);
 
1836                 input[total_len - 1]++;
 
1841         ========================================================================
 
1843         Routine Description:
 
1844                 Process MIC error indication and record MIC error timer.
 
1847                 pAd     Pointer to our adapter
 
1848                 pWpaKey                 Pointer to the WPA key structure
 
1853         IRQL = DISPATCH_LEVEL
 
1857         ========================================================================
 
1859 VOID    RTMPReportMicError(
 
1860         IN      PRTMP_ADAPTER   pAd,
 
1861         IN      PCIPHER_KEY     pWpaKey)
 
1864     UCHAR   unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
 
1866         // Record Last MIC error time and count
 
1868         if (pAd->StaCfg.MicErrCnt == 0)
 
1870                 pAd->StaCfg.MicErrCnt++;
 
1871                 pAd->StaCfg.LastMicErrorTime = Now;
 
1872         NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
 
1874         else if (pAd->StaCfg.MicErrCnt == 1)
 
1876                 if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
 
1878                         // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
 
1879                         pAd->StaCfg.LastMicErrorTime = Now;
 
1884                         if (pAd->CommonCfg.bWirelessEvent)
 
1885                                 RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
 
1887                         pAd->StaCfg.LastMicErrorTime = Now;
 
1888                         // Violate MIC error counts, MIC countermeasures kicks in
 
1889                         pAd->StaCfg.MicErrCnt++;
 
1894                 // MIC error count >= 2
 
1895                 // This should not happen
 
1899                                 MLME_CNTL_STATE_MACHINE,
 
1900                                 OID_802_11_MIC_FAILURE_REPORT_FRAME,
 
1904     if (pAd->StaCfg.MicErrCnt == 2)
 
1906         RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
 
1911 #ifdef WPA_SUPPLICANT_SUPPORT
 
1912 #define LENGTH_EAP_H    4
 
1913 // If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
 
1914 INT         WpaCheckEapCode(
 
1915         IN  PRTMP_ADAPTER               pAd,
 
1924         if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
 
1927         pData = pFrame + OffSet; // skip offset bytes
 
1929         if(*(pData+1) == EAPPacket)     // 802.1x header - Packet Type
 
1931                  result = *(pData+4);           // EAP header - Code
 
1937 VOID    WpaSendMicFailureToWpaSupplicant(
 
1938     IN  PRTMP_ADAPTER    pAd,
 
1939     IN  BOOLEAN          bUnicast)
 
1941     union iwreq_data    wrqu;
 
1942     char custom[IW_CUSTOM_MAX] = {0};
 
1944     sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
 
1946         sprintf(custom, "%s unicast", custom);
 
1947     wrqu.data.length = strlen(custom);
 
1948     wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
 
1952 #endif // WPA_SUPPLICANT_SUPPORT //
 
1954 VOID    WpaMicFailureReportFrame(
 
1955         IN  PRTMP_ADAPTER   pAd,
 
1956         IN MLME_QUEUE_ELEM *Elem)
 
1958         PUCHAR              pOutBuffer = NULL;
 
1959         UCHAR               Header802_3[14];
 
1961         EAPOL_PACKET        Packet;
 
1965         DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
 
1967     bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
 
1968         pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
 
1970         // init 802.3 header and Fill Packet
 
1971         MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
 
1973         NdisZeroMemory(&Packet, sizeof(Packet));
 
1974         Packet.ProVer   = EAPOL_VER;
 
1975         Packet.ProType  = EAPOLKey;
 
1977         Packet.KeyDesc.Type = WPA1_KEY_DESC;
 
1979     // Request field presented
 
1980     Packet.KeyDesc.KeyInfo.Request = 1;
 
1982         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
1984                 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
 
1988                 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
 
1991     Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
 
1993         // KeyMic field presented
 
1994         Packet.KeyDesc.KeyInfo.KeyMic  = 1;
 
1996     // Error field presented
 
1997         Packet.KeyDesc.KeyInfo.Error  = 1;
 
1999         // Update packet length after decide Key data payload
 
2000         Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
 
2003         NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
 
2004     inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
 
2006         // Convert to little-endian format.
 
2007         *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
 
2010         MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
 
2011         if(pOutBuffer == NULL)
 
2016         // Prepare EAPOL frame for MIC calculation
 
2017         // Be careful, only EAPOL frame is counted for MIC calculation
 
2018         MakeOutgoingFrame(pOutBuffer,               &FrameLen,
 
2019                               Packet.Body_Len[1] + 4,   &Packet,
 
2022         // Prepare and Fill MIC value
 
2023         NdisZeroMemory(Mic, sizeof(Mic));
 
2024         if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
 
2026         UCHAR digest[20] = {0};
 
2027                 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
 
2028                 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
 
2032                 hmac_md5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
 
2034         NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
 
2036     MakeOutgoingFrame(pOutBuffer,               &FrameLen,
 
2037                                 LENGTH_802_3,                           &Header802_3,
 
2038                                 Packet.Body_Len[1] + 4,     &Packet,
 
2041         // opy frame to Tx ring and send MIC failure report frame to authenticator
 
2042         RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
 
2044         MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
 
2046         DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
 
2049 /** from wpa_supplicant
 
2050  * inc_byte_array - Increment arbitrary length byte array by one
 
2051  * @counter: Pointer to byte array
 
2052  * @len: Length of the counter in bytes
 
2054  * This function increments the last byte of the counter by one and continues
 
2055  * rolling over to more significant bytes if the byte was incremented from
 
2058 void inc_byte_array(UCHAR *counter, int len)
 
2063                 if (counter[pos] != 0)
 
2069 VOID WpaDisassocApAndBlockAssoc(
 
2070     IN PVOID SystemSpecific1,
 
2071     IN PVOID FunctionContext,
 
2072     IN PVOID SystemSpecific2,
 
2073     IN PVOID SystemSpecific3)
 
2075     RTMP_ADAPTER                *pAd = (PRTMP_ADAPTER)FunctionContext;
 
2076     MLME_DISASSOC_REQ_STRUCT    DisassocReq;
 
2078         // disassoc from current AP first
 
2079         DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
 
2080         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
 
2081         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
 
2083         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
 
2084         pAd->StaCfg.bBlockAssoc = TRUE;