📄 dot11rsnlib.c
字号:
/* Check if the KSL record is valid. */ if (((pDot11->dot11Mode == DOT11_MODE_AP)&&(!pKsl->type.sta.associated)) || (pKsl->negSecPol == 0) || ((pKsl->negAuthPol == DOT11_AUTHPOL_PSK) && (!pKsl->pBss->pskValid)) || ((pKsl->negAuthPol == DOT11_AUTHPOL_8021X) && (!pKsl->pmkValid))) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: Can't receive EAPOL-Key packets " "from " DOT11_MAC_ADDR_STR " \n", DOT11_MAC_ADDR(pMblk->mBlkHdr.mData + DOT11_ADDR_LEN))); netMblkClChainFree(pMblk); pDot11->sme->ksl.unlock(pDot11); return ERROR; } pEapol = (DOT11_EAPOL_KEY_PKT *)(pMblk->mBlkHdr.mData + DOT11_ETHER_HEADER_LEN); if ((pMblk->mBlkHdr.mLen < sizeof(DOT11_EAPOL_KEY_PKT) + DOT11_ETHER_HEADER_LEN) || (ntohs(pEapol->length) < (sizeof(DOT11_EAPOL_KEY_PKT) - DOT11_EAPOL_HEADER_SIZE))) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: " DOT11_MAC_ADDR_STR " sends " "undersized EAPOL-Key packets.\n", DOT11_MAC_ADDR(pMblk->mBlkHdr.mData + DOT11_ADDR_LEN))); DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: mBlkLen=%d pEapol->length=%d" " sizeof(EAPOL_KEY_PKT)=%d\n", pMblk->mBlkPktHdr.len, ntohs(pEapol->length),sizeof(DOT11_EAPOL_KEY_PKT),0,0,0)); netMblkClChainFree(pMblk); pDot11->sme->ksl.unlock(pDot11); return ERROR; } /* Consolidate the keyInfo field from the message using byte accesses, since it is pretty much guaranteed to be mis-aligned due to the one byte length field at the start fo the header*/ keyInfo = pEapol->keyInfo[1] | (pEapol->keyInfo[0] << 8); /* Before we segregate things by key type, check for a request message from a STA - these are processed independent of key type */ if ((((keyInfo & DOT11_EAPOL_INFO_REQUEST) != 0) || ((keyInfo & DOT11_EAPOL_INFO_ERROR) != 0)) && (pDot11->dot11Mode == DOT11_MODE_AP)) { status = dot11RsnEapolReqProcess(pDot11, pKsl, pEapol); } /* Check if this is a pairwise key message. If so, then it is part of the four-way handshake. */ else if ((keyInfo & DOT11_EAPOL_INFO_KEYTYPE) != DOT11_KEYTYPE_GROUP) { /* Message A should have the ACK bit set and the MIC bit clear. This message can only be received by a station. The remote nonce should not be filled in. */ if (((keyInfo & DOT11_EAPOL_INFO_ACK) != 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) == 0) && (pKsl->dot11Mode == DOT11_MODE_AP)) { status = dot11Rsn4WayAProcess(pDot11, pKsl, pEapol); } /* Message B should have the ACK bit clear and the MIC bit set. Once again, the remote nonce should not be filled in. */ else if (((keyInfo & DOT11_EAPOL_INFO_ACK) == 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) != 0) && (!pKsl->remoteNonceValid) && (pKsl->dot11Mode == DOT11_MODE_ESS)) { status = dot11Rsn4WayBProcess(pDot11, pKsl, pEapol); } /* Message C Should have the ACK bit set and the MIC bit set. The Install bit should also be set. The remote nonce should be known, but the keys have not yet been derived. */ else if (((keyInfo & DOT11_EAPOL_INFO_ACK) != 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) != 0) && (pKsl->remoteNonceValid) && (pKsl->dot11Mode == DOT11_MODE_AP)) { status = dot11Rsn4WayCProcess(pDot11, pKsl, pEapol); } /* Message D should have the ACK clear and MIC set. The remote nonce is known at this point */ else if (((keyInfo & DOT11_EAPOL_INFO_ACK) == 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) != 0) && (pKsl->remoteNonceValid) && (pKsl->dot11Mode == DOT11_MODE_ESS)) { status = dot11Rsn4WayDProcess(pDot11, pKsl, pEapol); } else { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: Unable to decode packet from " DOT11_MAC_ADDR_STR "\n", DOT11_MAC_ADDR(pKsl->macAddr))); DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: keyInfo=%04x\n", keyInfo,0,0,0,0,0)); } } else /* This is part of the group handshake */ { /* There is no point going through with the group handshake if the fourway handshake has not occurred */ /* Message 1 of the group exchange should have the ACK bit set, the MIC bit set, the Info Secure bit set and the encrypted key data bit set and the . Only a station should receive this key. */ if (((keyInfo & DOT11_EAPOL_INFO_ACK) != 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) != 0) && (pKsl->dot11Mode == DOT11_MODE_AP)) { status = dot11RsnGroup1Process(pDot11, pKsl, pEapol); } else if (((keyInfo & DOT11_EAPOL_INFO_ACK) == 0) && ((keyInfo & DOT11_EAPOL_INFO_MIC) != 0) && (pKsl->dot11Mode == DOT11_MODE_ESS)) { status = dot11RsnGroup2Process(pDot11, pKsl, pEapol); } else { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: Unable to decode group packet" " from " DOT11_MAC_ADDR_STR "\n", DOT11_MAC_ADDR(pKsl->macAddr))); DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: keyInfo=%04x\n", keyInfo,0,0,0,0,0)); } } netMblkClChainFree(pMblk); /* Free the KSL Lock */ if (pDot11->sme->ksl.unlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnEapolPktReceive: Cannot free KSL lock \n", 0,0,0,0,0,0)); return ERROR; } else { return status; } }/****************************************************************************** dot11RsnFourwayStart - Starts the fourway handshake on an AP** When called on an AP, this starts the fourway conversation.** ERRNO: OK or ERROR if incorrect mode*/LOCAL STATUS dot11RsnFourwayStart ( DOT11_FW * pDot11, /* Pointer to device structure */ DOT11_KSL_ENTRY * pKsl ) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnFourwayStart: called.\n",0,0,0,0,0,0)); if (pKsl == NULL) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_RSN, ("dot11RsnFourwayStart: NULL pKsl",0,0,0,0,0,0)); return ERROR; } if (pDot11->dot11Mode != DOT11_MODE_AP) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnFourwayStart: This call is only allowed from a " "AP\n",0,0,0,0,0,0)); return ERROR; } /* The group cipher will be as presented. In an AP, this is the value that we sent to the station being echoed back at us. In a STA, this is the value provided by the AP. Since there is only one value permitted in this field, there is no negotiation here. */ pKsl->groupPol = pKsl->pBss->multiEncryptType; (VOID)dot11RsnNonceGenerate(pKsl->localNonce); pKsl->localNonceValid = TRUE; pKsl->remoteNonceValid = FALSE; pKsl->fourWayState = DOT11_FOURWAY_INIT; pKsl->derivedKeysValid = FALSE; pKsl->fourWayState = DOT11_FOURWAY_SENT_1; /* Take this opportunity to generate the GTK if this is the first station to associate */ if (!pKsl->pBss->gtkValid) { dot11RsnGtkRecalc(pDot11); } /* Start the timer waiting for message B back from the Station */ pKsl->eapolMsgTimer = dot11TimerAdd(DOT11_FOURWAY_MSG_TIMEOUT, (FUNCPTR)dot11RsnFourwayMsgTimeout, (int)pDot11, (int)pKsl); /* Start the 4-way timer. This times the entire conversation */ pKsl->fourWayGlobalTimer = dot11TimerAdd(DOT11_FOURWAY_GLOBAL_TIMEOUT, (FUNCPTR)pDot11->sme->rsn.fourwayTimeout, (int)pDot11, (int)pKsl); /* Send message A */ if (dot11RsnEapolPktSend(pDot11, pKsl, DOT11_EAPOL_INFO_NO_SECURE, DOT11_EAPOL_INFO_NO_MIC, DOT11_EAPOL_INFO_ACK, DOT11_EAPOL_INFO_NO_INSTALL, DOT11_EAPOL_INFO_NO_ENCRYPT, DOT11_EAPOL_INFO_NO_ERROR, DOT11_EAPOL_INFO_NO_REQUEST, DOT11_KEYTYPE_PAIRWISE, DOT11_EAPOL_NO_KEY_RSC, pKsl->localNonce, DOT11_EAPOL_NO_RSN_IE, DOT11_EAPOL_NO_GTK, 0, DOT11_EAPOL_NO_KEY_DATA, 0) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnFourwayStart: Error sending EAPOL-KEY\n" ,0,0,0,0,0,0)); return ERROR; } return OK; }/****************************************************************************** dot11RsnGtkRecalc - Recalculates the groupwise keys on an AP** This function is called to generate and redistribute the groupwise* keys on an AP. ** RETURNS: OK or ERROR*/LOCAL STATUS dot11RsnGtkRecalc ( DOT11_FW * pDot11 /* Pointer to DOT11 framework */ ) { UINT8 buffer[DOT11_NONCE_LEN + DOT11_ADDR_LEN]; UINT8 keyRsc[DOT11_EAPOL_KEYRSC_LEN]; DOT11_KSL_ENTRY * pKsl; DOT11_KEY key; int i, bssNum; DOT11_BSS * pBss; /* BSS to recalc key for */ if (pDot11->dot11Mode != DOT11_MODE_AP) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnGtkRecalc: Only valid on AP!\n",0,0,0,0,0,0)); return ERROR; } dot11TimerDel(pDot11->dpe->groupRekeyTimer); pDot11->dpe->groupRekeyTimer = 0; /* Check through all the BSSs. We'll only modify the one for the requested station unless forceRecalc == TRUE */ for (bssNum = 0; bssNum < DOT11_BSS_MAX; bssNum ++) { pBss = &pDot11->sme->bss[bssNum]; if (!pBss->inUse) { continue; } /* There is no group key exchange if the group policy is WEP, so just terminate */ if ((pBss->multiEncryptType == DOT11_KEY_TYPE_WEP40) || (pBss->multiEncryptType == DOT11_KEY_TYPE_WEP104)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnGtkRecalc[%d]: TSN network in effect; using " "WEP for group messages\n", bssNum, 0, 0, 0, 0, 0)); continue; } /* If there is no current group policy, don't bother with this BSS */ if (pBss->multiEncryptType == DOT11_KEY_TYPE_NONE) { continue; } /* Only regenerate the GMK if it hasn't been done before */ if (!pBss->gtkValid) { cciRand(CCI_APP_PROVIDER_ID, pBss->gmk, DOT11_GMK_LEN); } /* Re-generate the gNonce */ cciRand(CCI_APP_PROVIDER_ID, pBss->gNonce, DOT11_NONCE_LEN); /* Derive the GTK */ bcopy((char *)pBss->bssid, (char *)buffer, DOT11_ADDR_LEN); bcopy((char *)pBss->gNonce, (char *)&buffer[DOT11_ADDR_LEN], DOT11_NONCE_LEN); /* Rotate the keyslot to be used for this key. Avoid keyslot 0 as per 802.11i spec */ if (++pBss->multiKeySlot >= DOT11_MAX_DEFAULT_KEY) { pBss->multiKeySlot = 1; } DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_RSN, ("dot11RsnGtkRecalc[%d]: Regenerating group key using " "keyslot %d!\n", bssNum, pBss->multiKeySlot,0,0,0,0)); if (dot11RsnPrf(pBss->gmk, DOT11_GMK_LEN, (UINT8 *)"Group key expansion", strlen("Group key expansion"), buffer, DOT11_NONCE_LEN + DOT11_ADDR_LEN, DOT11_GTK_LEN * 8, pBss->gtk) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_RSN, ("dot11RsnGtkRecalc[%d]: PRF failed!\n",bssNum, 0,0,0,0,0)); /* Restart the group rekey time
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -