📄 cmm_wpa.c
字号:
} else { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n")); return FALSE; } DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN)); // skip it pMyKeyData += 8; KeyDataLength -= 8; } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) { DefaultIdx = GroupKeyIndex; DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx)); } // Sanity check - shared key index must be 1 ~ 3 if (DefaultIdx < 1 || DefaultIdx > 3) { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); return FALSE; } #ifdef CONFIG_STA_SUPPORT // Todo#endif // CONFIG_STA_SUPPORT // return TRUE; }/* ======================================================================== Routine Description: Construct EAPoL message for WPA handshaking Its format is below, +--------------------+ | Protocol Version | 1 octet +--------------------+ | Protocol Type | 1 octet +--------------------+ | Body Length | 2 octets +--------------------+ | Descriptor Type | 1 octet +--------------------+ | Key Information | 2 octets +--------------------+ | Key Length | 1 octet +--------------------+ | Key Repaly Counter | 8 octets +--------------------+ | Key Nonce | 32 octets +--------------------+ | Key IV | 16 octets +--------------------+ | Key RSC | 8 octets +--------------------+ | Key ID or Reserved | 8 octets +--------------------+ | Key MIC | 8 octets +--------------------+ | Key Data Length | 2 octets +--------------------+ | Key Data | n octets +--------------------+ Arguments: pAd Pointer to our adapter Return Value: None Note: ========================================================================*/VOID ConstructEapolMsg( IN PRTMP_ADAPTER pAd, IN UCHAR AuthMode, IN UCHAR WepStatus, IN UCHAR GroupKeyWepStatus, IN UCHAR MsgType, IN UCHAR DefaultKeyIdx, IN UCHAR *ReplayCounter, IN UCHAR *KeyNonce, IN UCHAR *TxRSC, IN UCHAR *PTK, IN UCHAR *GTK, IN UCHAR *RSNIE, IN UCHAR RSNIE_Len, OUT PEAPOL_PACKET pMsg){ BOOLEAN bWPA2 = FALSE; // Choose WPA2 or not if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK)) bWPA2 = TRUE; // Init Packet and Fill header pMsg->ProVer = EAPOL_VER; pMsg->ProType = EAPOLKey; // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG; // Fill in EAPoL descriptor if (bWPA2) pMsg->KeyDesc.Type = WPA2_KEY_DESC; else pMsg->KeyDesc.Type = WPA1_KEY_DESC; // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. pMsg->KeyDesc.KeyInfo.KeyDescVer = (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP)); // Specify Key Type as Group(0) or Pairwise(1) if (MsgType >= EAPOL_GROUP_MSG_1) pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY; else pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; // Specify Key Index, only group_msg1_WPA1 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)) pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx; if (MsgType == EAPOL_PAIR_MSG_3) pMsg->KeyDesc.KeyInfo.Install = 1; if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)) pMsg->KeyDesc.KeyInfo.KeyAck = 1; if (MsgType != EAPOL_PAIR_MSG_1) pMsg->KeyDesc.KeyInfo.KeyMic = 1; if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) { pMsg->KeyDesc.KeyInfo.Secure = 1; } if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))) { pMsg->KeyDesc.KeyInfo.EKD_DL = 1; }#ifdef BIG_ENDIAN // key Information element has done. // Swap byte-order for big-endian platforn *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = SWAP16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));#endif // Fill in Key Length { if (MsgType >= EAPOL_GROUP_MSG_1) { // the length of group key cipher pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY); } else { // the length of pairwise key cipher pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY); } } // Fill in replay counter NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY); // Fill Key Nonce field // ANonce : pairwise_msg1 & pairwise_msg3 // SNonce : pairwise_msg2 // GNonce : group_msg1_wpa1 if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)))) NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE); // Fill key IV - WPA2 as 0, WPA1 as random if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) { // Suggest IV be random number plus some number, NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV); pMsg->KeyDesc.KeyIv[15] += 2; } // Fill Key RSC field // It contains the RSC for the GTK being installed. if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) { NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6); } // Clear Key MIC field for MIC calculation later NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); ConstructEapolKeyData(pAd, AuthMode, WepStatus, GroupKeyWepStatus, MsgType, DefaultKeyIdx, bWPA2, PTK, GTK, RSNIE, RSNIE_Len, pMsg); // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. if (MsgType != EAPOL_PAIR_MSG_1) { CalculateMIC(pAd, WepStatus, PTK, pMsg); } DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1])); DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));}/* ======================================================================== Routine Description: Construct the Key Data field of EAPoL message Arguments: pAd Pointer to our adapter Elem Message body Return Value: None Note: ========================================================================*/VOID ConstructEapolKeyData( IN PRTMP_ADAPTER pAd, IN UCHAR AuthMode, IN UCHAR WepStatus, IN UCHAR GroupKeyWepStatus, IN UCHAR MsgType, IN UCHAR DefaultKeyIdx, IN BOOLEAN bWPA2Capable, IN UCHAR *PTK, IN UCHAR *GTK, IN UCHAR *RSNIE, IN UCHAR RSNIE_LEN, OUT PEAPOL_PACKET pMsg){ UCHAR *mpool, *Key_Data, *Rc4GTK; UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)]; UCHAR data_offset; if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) return; // allocate memory pool os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500); if (mpool == NULL) return; /* Rc4GTK Len = 512 */ Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4); /* Key_Data Len = 512 */ Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4); NdisZeroMemory(Key_Data, 512); pMsg->KeyDesc.KeyDataLen[1] = 0; data_offset = 0; // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3))) { if (bWPA2Capable) Key_Data[data_offset + 0] = IE_WPA2; else Key_Data[data_offset + 0] = IE_WPA; Key_Data[data_offset + 1] = RSNIE_LEN; NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN); data_offset += (2 + RSNIE_LEN); } // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))) { // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h Key_Data[data_offset + 0] = 0xDD; if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField) } else { Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField) } Key_Data[data_offset + 2] = 0x00; Key_Data[data_offset + 3] = 0x0F; Key_Data[data_offset + 4] = 0xAC; Key_Data[data_offset + 5] = 0x01; // GTK KDE format - 802.11i-2004 Figure-43x Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03); Key_Data[data_offset + 7] = 0x00; // Reserved Byte data_offset += 8; } // Encapsulate GTK and encrypt the key-data field with KEK. // Only for pairwise_msg3_WPA2 and group_msg1 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1)) { // Fill in GTK if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY); data_offset += LEN_AES_KEY; } else { NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH); data_offset += TKIP_GTK_LENGTH; } // Still dont know why, but if not append will occur "GTK not include in MSG3" // Patch for compatibility between zero config and funk if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) { if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { Key_Data[data_offset + 0] = 0xDD; Key_Data[data_offset + 1] = 0; data_offset += 2; } else { Key_Data[data_offset + 0] = 0xDD; Key_Data[data_offset + 1] = 0; Key_Data[data_offset + 2] = 0; Key_Data[data_offset + 3] = 0; Key_Data[data_offset + 4] = 0; Key_Data[data_offset + 5] = 0; data_offset += 6; } } // Encrypt the data material in key data field if (WepStatus == Ndis802_11Encryption3Enabled) { AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK); // AES wrap function will grow 8 bytes in length data_offset += 8; } else { // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) // put TxTsc in Key RSC field pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32. // ekey is the contanetion of IV-field, and PTK[16]->PTK[31] NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV); NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK); ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV) pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset); WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset); } NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset); } else { NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset); } // set key data length field and total length pMsg->KeyDesc.KeyDataLen[1] = data_offset; pMsg->Body_Len[1] += data_offset; os_free_mem(pAd, mpool);}VOID CalculateMIC( IN PRTMP_ADAPTER pAd, IN UCHAR PeerWepStatus, IN UCHAR *PTK, OUT PEAPOL_PACKET pMsg){ UCHAR *OutBuffer; ULONG FrameLen = 0; UCHAR mic[LEN_KEY_DESC_MIC]; UCHAR digest[80]; // allocate memory for MIC calculation os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512); if (OutBuffer == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n")); return; } // make a frame for calculating MIC. MakeOutgoingFrame(OutBuffer, &FrameLen, pMsg->Body_Len[1] + 4, pMsg, END_OF_ARGS); NdisZeroMemory(mic, sizeof(mic)); // Calculate MIC if (PeerWepStatus == Ndis802_11Encryption3Enabled) { HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } else { hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic); } NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); os_free_mem(pAd, OutBuffer);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -