/* ======================================================================== Routine Description: HMAC using SHA256 hash function Arguments: key Secret key key_len The length of the key in bytes message Message context message_len The length of message in bytes macLen Request the length of message authentication code Return Value: mac Message authentication code Note: None ======================================================================== */ void RT_HMAC_SHA256 ( IN const u8 Key[], IN UINT KeyLen, IN const u8 Message[], IN UINT MessageLen, OUT u8 MAC[], IN UINT MACLen) { SHA256_CTX_STRUC sha_ctx1; SHA256_CTX_STRUC sha_ctx2; u8 K0[SHA256_BLOCK_SIZE]; u8 Digest[SHA256_DIGEST_SIZE]; UINT index; memset(&sha_ctx1, 0, sizeof(SHA256_CTX_STRUC)); memset(&sha_ctx2, 0, sizeof(SHA256_CTX_STRUC)); /* * If the length of K = B(Block size): K0 = K. * If the length of K > B: hash K to obtain an L byte string, * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). * If the length of K < B: append zeros to the end of K to create a B-byte string K0 */ memset(K0, 0, SHA256_BLOCK_SIZE); if (KeyLen <= SHA256_BLOCK_SIZE) { memmove(K0, Key, KeyLen); } else { RT_SHA256(Key, KeyLen, K0); } /* Exclusive-Or K0 with ipad */ /* ipad: Inner pad; the byte x・36・ repeated B times. */ for (index = 0; index < SHA256_BLOCK_SIZE; index++) K0[index] ^= 0x36; /* End of for */ RT_SHA256_Init(&sha_ctx1); /* H(K0^ipad) */ RT_SHA256_Append(&sha_ctx1, K0, sizeof(K0)); /* H((K0^ipad)||text) */ RT_SHA256_Append(&sha_ctx1, Message, MessageLen); RT_SHA256_End(&sha_ctx1, Digest); /* Exclusive-Or K0 with opad and remove ipad */ /* opad: Outer pad; the byte x・5c・ repeated B times. */ for (index = 0; index < SHA256_BLOCK_SIZE; index++) K0[index] ^= 0x36^0x5c; /* End of for */ RT_SHA256_Init(&sha_ctx2); /* H(K0^opad) */ RT_SHA256_Append(&sha_ctx2, K0, sizeof(K0)); /* H( (K0^opad) || H((K0^ipad)||text) ) */ RT_SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE); RT_SHA256_End(&sha_ctx2, Digest); if (MACLen > SHA256_DIGEST_SIZE) memmove(MAC, Digest,SHA256_DIGEST_SIZE); else memmove(MAC, Digest, MACLen); } /* End of RT_HMAC_SHA256 */
INT NfcBuildOOBDevPasswdTLV( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscCtrl, IN UCHAR HandoverType, OUT UCHAR *pbuf, OUT USHORT *pBufLen) { INT Status = NDIS_STATUS_SUCCESS; UCHAR *TB = NULL;; PUCHAR pData = NULL, pSrcData = NULL; USHORT PasswdID = 0, len; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscCtrl->RegData; INT Len = 0, templen = 0; INT DH_Len = 0, idx; UCHAR HashData[SHA256_DIGEST_SIZE]; INT nfc_dev_passwd_len=0; #ifdef WSC_V2_SUPPORT PWSC_TLV pWscTLV = &pWscCtrl->WscV2Info.ExtraTlv; #endif /* WSC_V2_SUPPORT */ os_alloc_mem(pAd, (UCHAR **)&pData, (NFC_WSC_TLV_SIZE*sizeof(UCHAR))); if (pData == NULL) { return NDIS_STATUS_RESOURCES; } os_alloc_mem(pAd, (UCHAR **)&TB, (128*sizeof(UCHAR))); if (pData == NULL) { os_free_mem(NULL, pData); return NDIS_STATUS_RESOURCES; } DH_Len = sizeof(pWscCtrl->RegData.Pke); /* Enrollee 192 random bytes for DH key generation */ for (idx = 0; idx < 192; idx++) pWscCtrl->RegData.EnrolleeRandom[idx] = RandomByte(pAd); RT_DH_PublicKey_Generate ( WPS_DH_G_VALUE, sizeof(WPS_DH_G_VALUE), WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE), pWscCtrl->RegData.EnrolleeRandom, sizeof(pWscCtrl->RegData.EnrolleeRandom), pWscCtrl->RegData.Pke, (UINT *) &DH_Len); /* For Handover case, We may as Registrar So keep the same public key for Registrar */ RTMPMoveMemory(pWscCtrl->RegData.Pkr, pWscCtrl->RegData.Pke, DH_Len); hex_dump("Pkr", pWscCtrl->RegData.Pkr, DH_Len); hex_dump("Pke", pWscCtrl->RegData.Pkr, DH_Len); RT_SHA256(&pWscCtrl->RegData.Pke[0], 192, &HashData[0]); RTMPMoveMemory(&pWscCtrl->NfcPasswdHash[0], &HashData[0], NFC_DEV_PASSWD_HASH_LEN); hex_dump("NfcBuildOOBDevPasswdTLV - Public Key HashData", &HashData[0], 20); if (HandoverType == TYPE_PASSWDHO_S || HandoverType == TYPE_PASSWDHO_R) { PasswdID = DEV_PASS_ID_NFC_HANDOVER; pWscCtrl->NfcPasswdID = cpu2be16(PasswdID); NdisZeroMemory(&pWscCtrl->NfcPasswd[0], 32); pWscCtrl->NfcPasswdLen = NFC_DEV_PASSWD_LEN; } else { PasswdID = (RandomByte(pAd) << 8) + RandomByte(pAd); if (PasswdID < 0x10) PasswdID = 0x10; pWscCtrl->NfcPasswdID = cpu2be16(PasswdID); NfcGenRandomPasswd(pAd, pWscCtrl); hex_dump("NfcBuildOOBDevPasswdTLV - NfcPasswd", &pWscCtrl->NfcPasswd[0], NFC_DEV_PASSWD_LEN); } pSrcData = pData; NdisZeroMemory(pData, NFC_WSC_TLV_SIZE); NdisZeroMemory(&TB[0], 128); if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S) { /* Reserv for "Length of WSC attribute" */ pData += 2; } hex_dump("NfcBuildOOBDevPasswdTLV - 1 pSrcData", pSrcData, Len); NdisMoveMemory(&TB[0], &HashData[0], NFC_DEV_PASSWD_HASH_LEN); NdisMoveMemory(&TB[20], &pWscCtrl->NfcPasswdID, sizeof(pWscCtrl->NfcPasswdID)); if (HandoverType == TYPE_PASSWORD) { /* New SPEC Handover remove this part. */ NdisMoveMemory(&TB[22], &pWscCtrl->NfcPasswd[0], NFC_DEV_PASSWD_LEN); nfc_dev_passwd_len = NFC_DEV_PASSWD_LEN; } templen = AppendWSCTLV(WSC_ID_OOB_DEV_PWD, pData, &TB[0], NFC_DEV_PASSWD_HASH_LEN+sizeof(PasswdID)+nfc_dev_passwd_len); pData += templen; Len += templen; hex_dump("NfcBuildOOBDevPasswdTLV - 2 pSrcData", pSrcData, Len); if (HandoverType == TYPE_PASSWDHO_S) /* Build for Handover Select Message */ { templen = AppendWSCTLV(WSC_ID_SSID, pData, pAd->ApCfg.MBSSID[0].Ssid, pAd->ApCfg.MBSSID[0].SsidLen); pData += templen; Len += templen; /* Optional items. RF_Band, AP_Channel and MAC_Address */ UCHAR RF_Band; if (pAd->CommonCfg.Channel > 14) RF_Band = 0x02; /* 5.0GHz */ else RF_Band = 0x01; /* 2.4GHz */ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, &RF_Band, 0); pData += templen; Len += templen; USHORT Channel = 0; Channel = pAd->CommonCfg.Channel; #ifdef RT_BIG_ENDIAN Channel = SWAP16(Channel); #endif /* RT_BIG_ENDIAN */ templen = AppendWSCTLV(WSC_ID_AP_CHANNEL, pData, (UINT8 *)&Channel, 0); pData += templen; Len += templen; templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pAd->CommonCfg.Bssid, 0); pData += templen; Len += templen; } else if (HandoverType == TYPE_PASSWDHO_R) /* Build for Handover Request Message */ { templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWscCtrl->Wsc_Uuid_E[0], 0); pData += templen; Len += templen; } #ifdef WSC_V2_SUPPORT if (pWscCtrl->WscV2Info.bEnableWpsV2) { /* Version2 */ WscGenV2Msg(pWscCtrl, FALSE, NULL, 0, &pData, &Len); /* Extra attribute that is not defined in WSC Sepc. */ if (pWscTLV->pTlvData && pWscTLV->TlvLen) { templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen); pData += templen; Len += templen; } } #endif // WSC_V2_SUPPORT // if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S) { /*Assign for "Length of WSC attribute" */ len = cpu2be16(Len); memcpy(pSrcData, &len, 2); hex_dump("NfcBuildOOBDevPasswdTLV - pSrcData", pSrcData, Len+2); } else hex_dump("NfcBuildOOBDevPasswdTLV - pSrcData", pSrcData, Len); if (pbuf && (Len < NFC_WSC_TLV_SIZE)) { if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S) { NdisMoveMemory(pbuf, pSrcData, Len+2); *pBufLen = (USHORT)Len+2; } else { NdisMoveMemory(pbuf, pSrcData, Len); *pBufLen = (USHORT)Len; } hex_dump("NfcBuildOOBDevPasswdTLV", pbuf, *pBufLen); } else { DBGPRINT(RT_DEBUG_TRACE, ("%s: (Len=%d)\n", __FUNCTION__, Len)); Status = NDIS_STATUS_RESOURCES; } os_free_mem(NULL, pSrcData); os_free_mem(NULL, TB); return Status; }