UniqueID::UniqueID() { time_t m_time; int m_pid; char userName[255]; char hostName[255]; int ip = 3434; time(&(m_time)); UniqueID::basedata += m_time; m_pid = _getpid(); strcpy(userName,getenv(ENVSTRING)); WSADATA wsaData; if(WSAStartup(MAKEWORD( 2, 2),&wsaData) == 0) { gethostname(hostName,255); HOSTENT * host = gethostbyname(hostName); memcpy((void*)&ip, host->h_addr, 4); } else { strcpy(hostName,"ERROR_SOCKET"); } #ifdef WIN32 MEMORYSTATUS lpBuffer; // memory status structure GlobalMemoryStatus(&lpBuffer); int paso = (lpBuffer.dwAvailVirtual >> 8) * GenRandom() + GenRandom(); #else int paso = GenRandom() * GenRandom(); #endif WIN32 char* temp = uid; sprintf(temp,"%04.4x-",m_pid); temp += 5; sprintf(temp,"%08.8x-",m_time); temp += 9; sprintf(temp,"%08.8x",do_hash(userName) + ip); temp += 8; sprintf(temp,"%08.8x-",do_hash(hostName) + ip); temp += 9; sprintf(temp,"%08.8x",paso); UniqueID::basedata++; }
std::string InspIRCd::GenRandomStr(int length, bool printable) { char* buf = new char[length]; GenRandom(buf, length); std::string rv; rv.resize(length); for(int i=0; i < length; i++) rv[i] = printable ? 0x3F + (buf[i] & 0x3F) : buf[i]; delete[] buf; return rv; }
std::string GenRandomString( int len ) { const int lCharSetsize = strlen(RandStrCharSet); std::string lRet(len,' '); for(int i = 0; i<len; ++i) { int lseed = GenRandom(); lRet[i] = RandStrCharSet[lseed%lCharSetsize]; } return lRet; }
// NOTE: this has a slight bias for lower values if max is not a power of 2. // Don't use it if that matters. unsigned long InspIRCd::GenRandomInt(unsigned long max) { unsigned long rv; GenRandom((char*)&rv, sizeof(rv)); return rv % max; }
/* ========================================================================== Description: Timer execution function for periodically updating group key. Return: ========================================================================== */ VOID GREKEYPeriodicExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { UINT i, apidx; ULONG temp_counter = 0; struct rtmp_adapter *pAd = (struct rtmp_adapter *)FunctionContext; PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) SystemSpecific3; MULTISSID_STRUCT *pMbss = NULL; struct rtmp_wifi_dev *wdev; for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { if (&pAd->ApCfg.MBSSID[apidx].REKEYTimer == pTimer) break; } if (apidx == pAd->ApCfg.BssidNum) return; else pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; if (wdev->AuthMode < Ndis802_11AuthModeWPA || wdev->AuthMode > Ndis802_11AuthModeWPA1PSKWPA2PSK) return; if ((pMbss->WPAREKEY.ReKeyMethod == TIME_REKEY) && (pMbss->REKEYCOUNTER < 0xffffffff)) temp_counter = (++pMbss->REKEYCOUNTER); /* REKEYCOUNTER is incremented every MCAST packets transmitted, */ /* But the unit of Rekeyinterval is 1K packets */ else if (pMbss->WPAREKEY.ReKeyMethod == PKT_REKEY) temp_counter = pMbss->REKEYCOUNTER/1000; else { return; } if (temp_counter > (pMbss->WPAREKEY.ReKeyInterval)) { pMbss->REKEYCOUNTER = 0; pMbss->RekeyCountDown = 3; DBGPRINT(RT_DEBUG_TRACE, ("Rekey Interval Excess, GKeyDoneStations=%d\n", pMbss->StaCount)); /* take turn updating different groupkey index, */ if ((pMbss->StaCount) > 0) { /* change key index */ wdev->DefaultKeyId = (wdev->DefaultKeyId == 1) ? 2 : 1; /* Generate GNonce randomly */ GenRandom(pAd, wdev->bssid, pMbss->GNonce); /* Update GTK */ WpaDeriveGTK(pMbss->GMK, (u8 *)pMbss->GNonce, wdev->bssid, pMbss->GTK, LEN_TKIP_GTK); /* Process 2-way handshaking */ for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { MAC_TABLE_ENTRY *pEntry; pEntry = &pAd->MacTab.Content[i]; if (IS_ENTRY_CLIENT(pEntry) && (pEntry->WpaState == AS_PTKINITDONE) && (pEntry->apidx == apidx)) { pEntry->GTKState = REKEY_NEGOTIATING; #ifdef DROP_MASK_SUPPORT /* Disable Drop Mask */ set_drop_mask_per_client(pAd, pEntry, 1, 0); set_drop_mask_per_client(pAd, pEntry, 2, 0); #endif /* DROP_MASK_SUPPORT */ WPAStart2WayGroupHS(pAd, pEntry); DBGPRINT(RT_DEBUG_TRACE, ("Rekey interval excess, Update Group Key for %x %x %x %x %x %x , DefaultKeyId= %x \n",\ PRINT_MAC(pEntry->Addr), wdev->DefaultKeyId)); } } } } /* Use countdown to ensure the 2-way handshaking had completed */ if (pMbss->RekeyCountDown > 0) { pMbss->RekeyCountDown--; if (pMbss->RekeyCountDown == 0) { unsigned short Wcid; /* Get a specific WCID to record this MBSS key attribute */ GET_GroupKey_WCID(pAd, Wcid, apidx); /* Install shared key table */ WPAInstallSharedKey(pAd, wdev->GroupKeyWepStatus, apidx, wdev->DefaultKeyId, Wcid, true, pMbss->GTK, LEN_TKIP_GTK); } } }
/* ========================================================================== Description: Function to handle countermeasures active attack. Init 60-sec timer if necessary. Return: ========================================================================== */ VOID HandleCounterMeasure(struct rtmp_adapter *pAd, MAC_TABLE_ENTRY *pEntry) { INT i; bool Cancelled; if (!pEntry) return; /* Todo by AlbertY - Not support currently in ApClient-link */ if (IS_ENTRY_APCLI(pEntry)) return; /* if entry not set key done, ignore this RX MIC ERROR */ if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED)) return; DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n")); /* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */ pEntry->CMTimerRunning = true; pAd->ApCfg.MICFailureCounter++; /* send wireless event - for MIC error */ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0); if (pAd->ApCfg.CMTimerRunning == true) { DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n")); /* send wireless event - for counter measures */ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0); ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M); /* renew GTK */ GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce); /* Cancel CounterMeasure Timer */ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); pAd->ApCfg.CMTimerRunning = false; for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) { MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, false); } } /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec disallow new association , too */ pAd->ApCfg.BANClass3Data = true; /* check how many entry left... should be zero */ /*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */ /*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */ } RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE); pAd->ApCfg.CMTimerRunning = true; pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime; RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime); }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_BuildSetupRequest( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PRT_802_11_TDLS pTDLS) { ULONG Timeout = TDLS_TIMEOUT; BOOLEAN TimerCancelled; /* fill action code */ TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_SETUP_REQUEST); /* fill Dialog Token */ pAd->StaCfg.TdlsDialogToken++; if (pAd->StaCfg.TdlsDialogToken == 0) pAd->StaCfg.TdlsDialogToken++; pTDLS->Token = pAd->StaCfg.TdlsDialogToken; TDLS_InsertDialogToken(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->Token); /* fill link identifier */ TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pAd->CurrentAddress, pTDLS->MacAddr); // fill capability TDLS_InsertCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill ssid TDLS_InsertSSIDIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill support rate TDLS_InsertSupportRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill ext rate TDLS_InsertExtRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill Qos Capability TDLS_InsertQosCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); #ifdef DOT11_N_SUPPORT // fill HT Capability TDLS_InsertHtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill 20/40 BSS Coexistence (7.3.2.61) #ifdef DOT11N_DRAFT3 TDLS_InsertBSSCoexistenceIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // // fill Extended Capabilities (7.3.2.27) TDLS_InsertExtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // TPK Handshake if RSNA Enabled // Pack TPK Message 1 here! if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) && ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))) { UCHAR CipherTmp[64] = {0}; UCHAR CipherTmpLen = 0; FT_FTIE FtIe; ULONG KeyLifetime = TDLS_KEY_TIMEOUT; // sec ULONG tmp; UCHAR Length; // RSNIE (7.3.2.25) CipherTmpLen = CipherSuiteTDLSLen; if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskTkip, CipherTmpLen); else NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskAes, CipherTmpLen); // update AKM if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) CipherTmp[19] = TDLS_AKM_SUITE_1X; // Insert RSN_IE to outgoing frame MakeOutgoingFrame((pFrameBuf + *pFrameLen), &tmp, CipherTmpLen, &CipherTmp, END_OF_ARGS); *pFrameLen = *pFrameLen + tmp; // FTIE (7.3.2.48) NdisZeroMemory(&FtIe, sizeof(FtIe)); Length = sizeof(FtIe); // generate SNonce GenRandom(pAd, pAd->CurrentAddress, FtIe.SNonce); hex_dump("TDLS - Generate SNonce ", FtIe.SNonce, 32); NdisMoveMemory(pTDLS->SNonce, FtIe.SNonce, 32); TDLS_InsertFTIE( pAd, (pFrameBuf + *pFrameLen), pFrameLen, Length, FtIe.MICCtr, FtIe.MIC, FtIe.ANonce, FtIe.SNonce); // Timeout Interval (7.3.2.49) TDLS_InsertTimeoutIntervalIE( pAd, (pFrameBuf + *pFrameLen), pFrameLen, 2, /* key lifetime interval */ KeyLifetime); pTDLS->KeyLifetime = KeyLifetime; } // ==>> Set sendout timer RTMPCancelTimer(&pTDLS->Timer, &TimerCancelled); RTMPSetTimer(&pTDLS->Timer, Timeout); // ==>> State Change pTDLS->Status = TDLS_MODE_WAIT_RESPONSE; }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_BuildSetupResponse( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PRT_802_11_TDLS pTDLS, IN UCHAR RsnLen, IN PUCHAR pRsnIe, IN UCHAR FTLen, IN PUCHAR pFTIe, IN UCHAR TILen, IN PUCHAR pTIIe, IN UINT16 StatusCode) { /* fill action code */ TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_SETUP_RESPONSE); /* fill status code */ TDLS_InsertStatusCode(pAd, (pFrameBuf + *pFrameLen), pFrameLen, StatusCode); /* fill Dialog Token */ TDLS_InsertDialogToken(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->Token); if (StatusCode == MLME_SUCCESS) { /* fill link identifier */ TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->MacAddr, pAd->CurrentAddress); // fill capability TDLS_InsertCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill ssid TDLS_InsertSSIDIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill support rate TDLS_InsertSupportRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill ext rate TDLS_InsertExtRateIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); // fill Qos Capability TDLS_InsertQosCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); #ifdef DOT11_N_SUPPORT // fill HT Capability TDLS_InsertHtCapIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen); #endif // DOT11_N_SUPPORT // // TPK Handshake if RSNA Enabled // Pack TPK Message 2 here! if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) && ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))) { FT_FTIE *ft; ULONG tmp; UINT key_len = LEN_PMK; // RSNIE (7.3.2.25) // Insert RSN_IE of the Peer TDLS to outgoing frame MakeOutgoingFrame((pFrameBuf + *pFrameLen), &tmp, RsnLen, pRsnIe, END_OF_ARGS); *pFrameLen = *pFrameLen + tmp; // FTIE (7.3.2.48) // Construct FTIE (IE + Length + MIC Control + MIC + ANonce + SNonce) // point to the element of IE ft = (FT_FTIE *)(pFTIe + 2); // generate ANonce GenRandom(pAd, pAd->CurrentAddress, ft->ANonce); hex_dump("TDLS - Generate ANonce ", ft->ANonce, 32); // set MIC field to zero before MIC calculation NdisZeroMemory(ft->MIC, 16); // copy SNonce from peer TDLS NdisMoveMemory(ft->SNonce, pTDLS->SNonce, 32); // copy ANonce to TDLS entry NdisMoveMemory(pTDLS->ANonce, ft->ANonce, 32); //if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) //key_len = 48; // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Derive TPK-KCK for MIC key, TPK-TK for direct link data TDLS_FTDeriveTPK( pTDLS->MacAddr, /* MAC Address of Initiator */ pAd->CurrentAddress, /* I am Responder */ pTDLS->ANonce, pTDLS->SNonce, pAd->CommonCfg.Bssid, key_len, pTDLS->TPK, pTDLS->TPKName); // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //////////////////////////////////////////////////////////////////////// // The MIC field of FTIE shall be calculated on the concatenation, in the following order, of // 1. MAC_I (6 bytes) // 2. MAC_R (6 bytes) // 3. Transaction Sequence = 2 (1 byte) // 4. Link Identifier (20 bytes) // 5. RSN IE without the IE header (20 bytes) // 6. Timeout Interval IE (7 bytes) // 7. FTIE without the IE header, with the MIC field of FTIE set to zero (82 bytes) { UCHAR content[512]; ULONG c_len = 0; ULONG tmp_len = 0; UCHAR Seq = 2; UCHAR mic[16]; UCHAR LinkIdentifier[20]; UINT tmp_aes_len = 0; NdisZeroMemory(LinkIdentifier, 20); LinkIdentifier[0] = IE_TDLS_LINK_IDENTIFIER; LinkIdentifier[1] = 18; NdisMoveMemory(&LinkIdentifier[2], pAd->CommonCfg.Bssid, 6); NdisMoveMemory(&LinkIdentifier[8], pTDLS->MacAddr, 6); NdisMoveMemory(&LinkIdentifier[14], pAd->CurrentAddress, 6); NdisZeroMemory(mic, sizeof(mic)); /* make a header frame for calculating MIC. */ MakeOutgoingFrame(content, &tmp_len, MAC_ADDR_LEN, pTDLS->MacAddr, MAC_ADDR_LEN, pAd->CurrentAddress, 1, &Seq, END_OF_ARGS); c_len += tmp_len; /* concatenate Link Identifier */ MakeOutgoingFrame(content + c_len, &tmp_len, 20, LinkIdentifier, END_OF_ARGS); c_len += tmp_len; /* concatenate RSNIE */ MakeOutgoingFrame(content + c_len, &tmp_len, 20, (pRsnIe + 2), END_OF_ARGS); c_len += tmp_len; /* concatenate Timeout Interval IE */ MakeOutgoingFrame(content + c_len, &tmp_len, 7, pTIIe, END_OF_ARGS); c_len += tmp_len; /* concatenate FTIE */ MakeOutgoingFrame(content + c_len, &tmp_len, sizeof(FT_FTIE), (PUCHAR)ft, END_OF_ARGS); c_len += tmp_len; /* Calculate MIC */ //AES_128_CMAC(pTDLS->TPK, content, c_len, mic); /* Compute AES-128-CMAC over the concatenation */ tmp_aes_len = AES_KEY128_LENGTH; AES_CMAC(content, c_len, pTDLS->TPK, 16, mic, &tmp_aes_len); // Fill Mic to ft struct NdisMoveMemory(ft->MIC, mic, 16); } //////////////////////////////////////////////////////////////////////// // Insert FT_IE to outgoing frame TDLS_InsertFTIE( pAd, (pFrameBuf + *pFrameLen), pFrameLen, sizeof(FT_FTIE), ft->MICCtr, ft->MIC, ft->ANonce, ft->SNonce); // Timeout Interval (7.3.2.49) // Insert TI_IE to outgoing frame TDLS_InsertTimeoutIntervalIE( pAd, (pFrameBuf + *pFrameLen), pFrameLen, 2, /* key lifetime interval */ pTDLS->KeyLifetime); } } }
void GenUniRandVec(uint32_t uStart, uint32_t uEnd, uint32_t uNum, vector<uint32_t>& randVec) { uint32_t uOrignSize = uEnd - uStart + 1; if (uNum > uOrignSize + 1 || uNum == 0) // 超过能随机的范围, 或者不需要随机 { return; } /* 如果需要不重复的随机数和数据源的比列比较接近,那么采用数组下标置换算法 如果需要不重复的随机数占数据源的比列比较少,那么采用随机碰撞算法 如果数据源本身数据在100以内,并且随机比列低于0.2,那么直接只用数组下标置换算法 */ // 随机碰撞方式 if ((uOrignSize > 100 && uOrignSize * 0.3 >= uNum) || (uOrignSize <= 100 && uOrignSize * 0.2 >= uNum)) { do { uint32_t uRandIndex = GenRandom(uStart, uEnd); // 查找是否已经存在了 bool bFind = false; vector<uint32_t>::iterator randIt = randVec.begin(); vector<uint32_t>::iterator randItEnd = randVec.end(); for (; randIt != randItEnd; randIt++) { if (uRandIndex == *randIt) { bFind = true; } } if (!bFind) { randVec.push_back(uRandIndex); } } while (randVec.size() < uNum); return; } // 采用数组下标置换算法,需要先复制一次数据 vector<uint32_t> tmpVec; for (uint32_t uRank=uStart; uRank<=uEnd; uRank++) { tmpVec.push_back(uRank); } /* 采用数组下标置换的方式,传入的orignVec需要是指定随机范围内数字排序好之后的数组 如果获得了指定数量的随机值后,算法就终止 */ uint32_t uRandCount = 0; for (uint32_t i=0; i<uOrignSize; i++) { if (uRandCount == uNum) { break; } // 在min和max之间随机一个数字 uint32_t uRandIndex = GenRandom(i, uOrignSize-1); // 置换元素下标 std::swap(tmpVec[i], tmpVec[uRandIndex]); randVec.push_back(tmpVec[i]); //if (tmpVec[i] == 0) //{ // continue; //} ++uRandCount; } return; }