/* ======================================================================== Routine Description: It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. It shall be called by 4-way handshake processing. Arguments: pAd - pointer to our pAdapter context PMK - pointer to PMK ANonce - pointer to ANonce AA - pointer to Authenticator Address SNonce - pointer to SNonce SA - pointer to Supplicant Address len - indicate the length of PTK (octet) Return Value: Output pointer to the PTK Note: Refer to IEEE 802.11i-2004 8.5.1.2 ======================================================================== */ VOID WpaCountPTK( IN PRTMP_ADAPTER pAd, IN UCHAR *PMK, IN UCHAR *ANonce, IN UCHAR *AA, IN UCHAR *SNonce, IN UCHAR *SA, OUT UCHAR *output, IN UINT len) { UCHAR concatenation[76]; UINT CurrPos = 0; UCHAR temp[32]; UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; // initiate the concatenation input NdisZeroMemory(temp, sizeof(temp)); NdisZeroMemory(concatenation, 76); // Get smaller address if (RTMPCompareMemory(SA, AA, 6) == 1) NdisMoveMemory(concatenation, AA, 6); else NdisMoveMemory(concatenation, SA, 6); CurrPos += 6; // Get larger address if (RTMPCompareMemory(SA, AA, 6) == 1) NdisMoveMemory(&concatenation[CurrPos], SA, 6); else NdisMoveMemory(&concatenation[CurrPos], AA, 6); // store the larger mac address for backward compatible of // ralink proprietary STA-key issue NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); CurrPos += 6; // Get smaller Nonce if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); else NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); CurrPos += 32; // Get larger Nonce if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); else NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); CurrPos += 32; hex_dump("concatenation=", concatenation, 76); // Use PRF to generate PTK PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len); }
static void Handle_read(int sock, void *eloop_ctx, void *sock_ctx) { rtapd *rtapd = eloop_ctx; int len; unsigned char buf[3000]; u8 *sa, *da, *pos, *pos_vlan, apidx=0, isVlanTag=0; u16 ethertype,i; priv_rec *rec; size_t left; u8 RalinkIe[9] = {221, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; len = recv(sock, buf, sizeof(buf), 0); if (len < 0) { perror("recv"); Handle_term(15,eloop_ctx,sock_ctx); return; } rec = (priv_rec*)buf; left = len -sizeof(*rec)+1; if (left <= 0) { DBGPRINT(RT_DEBUG_ERROR," too short recv\n"); return; } sa = rec->saddr; da = rec->daddr; ethertype = rec->ethtype[0] << 8; ethertype |= rec->ethtype[1]; #ifdef ETH_P_VLAN if(ethertype == ETH_P_VLAN) { pos_vlan = rec->xframe; if(left >= 4) { ethertype = *(pos_vlan+2) << 8; ethertype |= *(pos_vlan+3); } if((ethertype == ETH_P_PRE_AUTH) || (ethertype == ETH_P_PAE)) { isVlanTag = 1; DBGPRINT(RT_DEBUG_TRACE,"Recv vlan tag for 802.1x. (%02x %02x)\n", *(pos_vlan), *(pos_vlan+1)); } } #endif if ((ethertype == ETH_P_PRE_AUTH) || (ethertype == ETH_P_PAE)) { // search this packet is coming from which interface for (i = 0; i < rtapd->conf->SsidNum; i++) { if (memcmp(da, rtapd->own_addr[i], 6) == 0) { apidx = i; break; } } if(i >= rtapd->conf->SsidNum) { DBGPRINT(RT_DEBUG_WARN, "Receive unexpected DA (%02x:%02x:%02x:%02x:%02x:%02x)\n", MAC2STR(da)); return; } if (ethertype == ETH_P_PRE_AUTH) { DBGPRINT(RT_DEBUG_TRACE, "Receive WPA2 pre-auth packet for %s%d\n", rtapd->prefix_wlan_name, apidx); } else { DBGPRINT(RT_DEBUG_TRACE, "Receive EAP packet for %s%d\n", rtapd->prefix_wlan_name, apidx); } } else { DBGPRINT(RT_DEBUG_ERROR, "Receive unexpected ethertype 0x%04X!!!\n", ethertype); return; } pos = rec->xframe; //strip 4 bytes for valn tag if(isVlanTag) { pos += 4; left -= 4; } /* Check if this is a internal command or not */ if (left == sizeof(RalinkIe) && RTMPCompareMemory(pos, RalinkIe, 5) == 0) { u8 icmd = *(pos + 5); switch(icmd) { case DOT1X_DISCONNECT_ENTRY: { struct sta_info *s; s = rtapd->sta_hash[STA_HASH(sa)]; while (s != NULL && memcmp(s->addr, sa, 6) != 0) s = s->hnext; DBGPRINT(RT_DEBUG_TRACE, "Receive discard-notification form wireless driver.\n"); if (s) { DBGPRINT(RT_DEBUG_TRACE,"This station(%02x:%02x:%02x:%02x:%02x:%02x) is removed.\n", MAC2STR(sa)); Ap_free_sta(rtapd, s); } else { DBGPRINT(RT_DEBUG_INFO, "This station(%02x:%02x:%02x:%02x:%02x:%02x) doesn't exist.\n", MAC2STR(sa)); } } break; case DOT1X_RELOAD_CONFIG: Handle_reload_config(rtapd); break; default: DBGPRINT(RT_DEBUG_ERROR, "Unknown internal command(%d)!!!\n", icmd); break; } } else { /* Process the general EAP packet */ ieee802_1x_receive(rtapd, sa, &apidx, pos, left, ethertype, sock); } }
VOID PMF_DerivePTK( IN PRTMP_ADAPTER pAd, IN UCHAR *PMK, IN UCHAR *ANonce, IN UCHAR *AA, IN UCHAR *SNonce, IN UCHAR *SA, OUT UCHAR *output, IN UINT len) { UCHAR concatenation[76]; UINT CurrPos = 0; UCHAR temp[32]; UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; /* initiate the concatenation input */ NdisZeroMemory(temp, sizeof(temp)); NdisZeroMemory(concatenation, 76); /* Get smaller address */ if (RTMPCompareMemory(SA, AA, 6) == 1) NdisMoveMemory(concatenation, AA, 6); else NdisMoveMemory(concatenation, SA, 6); CurrPos += 6; /* Get larger address */ if (RTMPCompareMemory(SA, AA, 6) == 1) NdisMoveMemory(&concatenation[CurrPos], SA, 6); else NdisMoveMemory(&concatenation[CurrPos], AA, 6); /* store the larger mac address for backward compatible of ralink proprietary STA-key issue */ NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); CurrPos += 6; /* Get smaller Nonce */ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) NdisMoveMemory(&concatenation[CurrPos], temp, 32); else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); else NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); CurrPos += 32; /* Get larger Nonce */ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) NdisMoveMemory(&concatenation[CurrPos], temp, 32); else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); else NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); CurrPos += 32; hex_dump("[PMF]PMK", PMK, LEN_PMK); hex_dump("[PMF]concatenation=", concatenation, 76); /* Calculate a key material through FT-KDF */ KDF(PMK, LEN_PMK, Prefix, 22, concatenation, 76, output, len); }