⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wps_enrollee.c

📁 WiFi Protected Setup (WPS) 又叫Simple config。 是无线局域网领域推出的新协议
💻 C
📖 第 1 页 / 共 5 页
字号:
{
	WPS_s32 ret;
	WPS_s16 AttributeDataLength = WPS_n2h16(WPS_get_word((WPS_u8 *)Input+2));
	const WPS_u8 *IV = Input+4;

	WPS_u8 IV_temp[16];
	WPS_MEM_CPY(IV_temp, IV, 16);

	WPS_u8 *temp = (WPS_u8 *)WPS_MALLOC(AttributeDataLength-16);
	WPS_AES_CBC_Decrypt(enrollee->KeyWrapKey, 16, IV_temp, 16, Input+4+16, AttributeDataLength-16, temp, AttributeDataLength-16);

#if ENROLLEE_DEBUG	
	WPS_PRINTF("-----------------Data||KWA (%d bytes)---------------\n", AttributeDataLength-16);
	PrintHex(temp, AttributeDataLength-16);
	WPS_PRINTF("--------------------------------------------------\n");
#endif	

	WPS_u8 *p = temp;
	WPS_u8 *HMAC_Input = temp;
	WPS_s16 HMAC_InputLen = 0;

	// Calculate the HMAC_InputLen, all elements before "KeyWrapAuthenticator".
	while (WPS_n2h16(WPS_get_word(p)) != E_KeyWrapAuthenticator_ID)
	{
		HMAC_InputLen += 2+2+WPS_n2h16(WPS_get_word(p+2));
		p = temp+HMAC_InputLen;
	}

#if ENROLLEE_DEBUG	
	WPS_PRINTF("HMAC_InputLen = %d\n", HMAC_InputLen);
#endif	

	WPS_u8 HMAC_Output[32];
	WPS_HMAC_Sha256(enrollee->AuthKey, 32, HMAC_Input, HMAC_InputLen, HMAC_Output, 32);
	if (WPS_MEM_CMP(HMAC_Output, temp+HMAC_InputLen+2+2, E_KeyWrapAuthenticator_Length) == 0)
	{
		WPS_MEM_CPY(Output, temp, (HMAC_InputLen > OutputBuffLen ? OutputBuffLen : HMAC_InputLen));
		ret = 0;
	}
	else
	{
		ret = -1;
	}
	WPS_MFREE(temp);
	return ret;
}

//
// Function to compute Diffie-Hellman Share Key,
// and then calculate KDK and AuthKey, KeyWrapKey, EMSK.
// Return values:
//     0: Successful.
//     -1: Failed.
//
WPS_s32 wps_enrol_key_derivation(struct enrollee *enrollee)
{
#if ENROLLEE_DEBUG	
	WPS_PRINTF("\nEnrollee Key Infomation:\n");
#endif
	//
	// Compute KDK...
	// KDK = HMAC-SHA256,DHKey (N1 || EnrolleeMAC || N2)
	//
	WPS_s32 DHKeyLen = WPS_dh_sharedkey_size(enrollee->DH_e);
	WPS_u8 *DHKey = (WPS_u8 *)WPS_MALLOC(DHKeyLen);
	if (WPS_dh_compute_sharedkey(
		enrollee->DH_e, 
		enrollee->PK_R, 
		E_PublicKey_Length,
		DHKey,
		DHKeyLen) == -1)
	{
		WPS_PRINTF("wps_enrol_key_derivation: Compute DH shared key failed!\n");
		WPS_MFREE(DHKey);
		return -1;
	}

#if 0
	WPS_PRINTF("\n---------PK_E--------------------------\n");
	PrintHex(enrollee->PK_E, E_PublicKey_Length);

	WPS_PRINTF("\n---------PK_R--------------------------\n");
	PrintHex(enrollee->PK_R, E_PublicKey_Length);

	WPS_PRINTF("\n---------Diffie-Hellman Share Key------\n");
	PrintHex(DHKey, DHKeyLen);
#endif

	WPS_u8 DHKey2[32];
	WPS_Sha256(DHKey, DHKeyLen, DHKey2, 32);

	WPS_s32 InputLen = E_EnrolleeNonce_Length+E_MACAddress_Length+E_RegistrarNonce_Length;
	WPS_u8 *Input = (WPS_u8 *)WPS_MALLOC(InputLen);// 16+6+16=38
	WPS_MEM_CPY(Input, enrollee->EnrolleeNonce, E_EnrolleeNonce_Length);
	WPS_MEM_CPY(Input+E_EnrolleeNonce_Length, enrollee->EnrolleeMAC, E_MACAddress_Length);
	WPS_MEM_CPY(Input+E_EnrolleeNonce_Length+E_MACAddress_Length, enrollee->RegistrarNonce, E_EnrolleeNonce_Length);

	WPS_HMAC_Sha256(DHKey2, 32, Input, InputLen, enrollee->KDK, 32);

	WPS_MFREE(Input);
	WPS_MFREE(DHKey);

	/* Given KDK and key derivation function, 
	 * the Registration Protocol session keys are derived as follows:
	 * AuthKey || KeyWrapKey || EMSK = kdf(KDK, "Wi-Fi Easy and Secure Key Derivation", 640) 
	 */
	WPS_u8 CombiKey[640/8];

	kdf(enrollee->KDK, 32, "Wi-Fi Easy and Secure Key Derivation", CombiKey, 640);
	WPS_MEM_CPY(enrollee->AuthKey, CombiKey, 32);
	WPS_MEM_CPY(enrollee->KeyWrapKey, CombiKey+32, 16);
	WPS_MEM_CPY(enrollee->EMSK, CombiKey+32+16, 32);

#if ENROLLEE_DEBUG
	WPS_PRINTF("\n---------AuthKey-----------------------\n");
	PrintHex(enrollee->AuthKey, 32);

	WPS_PRINTF("\n---------KeyWrapKey--------------------\n");
	PrintHex(enrollee->KeyWrapKey, 16);

	WPS_PRINTF("\n---------EMSK--------------------------\n");
	PrintHex(enrollee->EMSK, 32);
	WPS_PRINTF("\n");
#endif

	return 0;
}

//
// Return values:
//  0: OK
// -1: Invalid
//
WPS_s32 wps_enrol_check_rh1_using_rsn1(struct enrollee *enrollee)
{
	WPS_u8 TempRHash1[E_RHash1_Length];

	WPS_u8 TempInput1[ E_RSNonce1_Length+16+E_PublicKey_Length+E_PublicKey_Length ];
	WPS_MEM_CPY(TempInput1, enrollee->RSNonce1, E_RSNonce1_Length);
	WPS_MEM_CPY(TempInput1+E_RSNonce1_Length, enrollee->PSK1, 16);
	WPS_MEM_CPY(TempInput1+E_RSNonce1_Length+16, enrollee->PK_E, E_PublicKey_Length);
	WPS_MEM_CPY(TempInput1+E_RSNonce1_Length+16+E_PublicKey_Length, enrollee->PK_R, E_PublicKey_Length);
	WPS_HMAC_Sha256(enrollee->AuthKey, 32, TempInput1, E_RSNonce1_Length+16+E_PublicKey_Length+E_PublicKey_Length, TempRHash1, E_RHash1_Length);

	if (WPS_MEM_CMP(enrollee->RHash1, TempRHash1, E_RHash1_Length) == 0)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

//
// Return values:
//  0: OK
// -1: Invalid
//
WPS_s32 wps_enrol_check_rh2_using_rsn2(struct enrollee *enrollee)
{
	WPS_u8 TempRHash2[E_RHash2_Length];

	WPS_u8 TempInput2[ E_RSNonce2_Length+16+E_PublicKey_Length+E_PublicKey_Length ];
	WPS_MEM_CPY(TempInput2, enrollee->RSNonce2, E_RSNonce2_Length);
	WPS_MEM_CPY(TempInput2+E_RSNonce2_Length, enrollee->PSK2, 16);
	WPS_MEM_CPY(TempInput2+E_RSNonce2_Length+16, enrollee->PK_E, E_PublicKey_Length);
	WPS_MEM_CPY(TempInput2+E_RSNonce2_Length+16+E_PublicKey_Length, enrollee->PK_R, E_PublicKey_Length);
	WPS_HMAC_Sha256(enrollee->AuthKey, 32, TempInput2, E_RSNonce2_Length+16+E_PublicKey_Length+E_PublicKey_Length, TempRHash2, E_RHash2_Length);

	if (WPS_MEM_CMP(enrollee->RHash2, TempRHash2, E_RHash2_Length) == 0)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

WPS_s32 wps_enrol_upt_last_msg_for_snd(struct enrollee *enrollee, WPS_u8 *SendBuff, WPS_s16 MessageLength)
{
	if (enrollee->LastPacket != NULL)
	{
		WPS_MFREE(enrollee->LastPacket);
		enrollee->LastPacket = NULL;
	}
	WPS_s32 LastPacketLen = EAP_HEAD_LENGTH+MessageLength;
	WPS_u8 *temp = (WPS_u8 *)WPS_MALLOC(LastPacketLen);
	if (temp == NULL)
	{
		WPS_PRINTF("wps_enrol_upt_last_msg_for_snd: no enough memory\n");
		return -1;
	}
	WPS_MEM_CPY(temp, SendBuff, LastPacketLen);
	enrollee->LastPacket = temp;
	enrollee->LastPacketLength = LastPacketLen;
	enrollee->LastMessage = enrollee->LastPacket+EAP_HEAD_LENGTH;
	enrollee->LastMessageLength = MessageLength;
	return 0;
}

WPS_s32 wps_enrol_upt_last_msg_for_rcv(struct enrollee *enrollee, struct eap_packet *packet)
{
	if (enrollee->LastPacket != NULL)
	{
		WPS_MFREE(enrollee->LastPacket);
		enrollee->LastPacket = NULL;
	}
	WPS_s32 LastPacketLen = WPS_n2h16(packet->Length);
	WPS_u8 *temp = (WPS_u8 *)WPS_MALLOC(LastPacketLen);
	if (temp == NULL)
	{
		WPS_PRINTF("wps_enrol_upt_last_msg_for_rcv: no enough memory\n");
		return -1;
	}
	WPS_MEM_CPY(temp, (WPS_u8 *)packet, LastPacketLen);
	enrollee->LastPacket = temp;
	enrollee->LastPacketLength = LastPacketLen;
	enrollee->LastMessage = enrollee->LastPacket+EAP_HEAD_LENGTH;
	enrollee->LastMessageLength = EAP_MESSAGE_LENGTH(packet);
	return 0;
}

/////////////////////////////////////////////////////////////////////////////////////

WPS_s32 wps_enrol_snd_m1(struct enrollee *enrollee)
{
	WPS_u8 SendBuff[SEND_BUFFER_SIZE];
	struct eap_packet* packet = (struct eap_packet*)(SendBuff);
	WPS_u8 *MessageData = SendBuff + EAP_HEAD_LENGTH;
	WPS_u8 *p = MessageData;
	WPS_s16 MessageLength = 0;
	WPS_s16 DataLength;

	//
	// To fill the MessageData
	//
	WPS_set_word(p, WPS_h2n16(E_Version_ID));
	WPS_set_word(p+2, WPS_h2n16(E_Version_Length));
	*(p+4) = enrollee->MyVersion;
	MessageLength += 2+2+E_Version_Length;
	p += 2+2+E_Version_Length;

	WPS_set_word(p, WPS_h2n16(E_MessageType_ID));
	WPS_set_word(p+2, WPS_h2n16(E_MessageType_Length));
	*(p+4) = MESSAGE_TYPE_M1; // M1
	MessageLength += 2+2+E_MessageType_Length;
	p += 2+2+E_MessageType_Length;

	WPS_set_word(p, WPS_h2n16(E_UUID_E_ID));
	WPS_set_word(p+2, WPS_h2n16(E_UUID_E_Length));
	WPS_MEM_CPY(p+4, enrollee->UUID_E, E_UUID_E_Length);
	MessageLength += 2+2+E_UUID_E_Length;
	p += 2+2+E_UUID_E_Length;

	WPS_set_word(p, WPS_h2n16(E_MACAddress_ID));
	WPS_set_word(p+2, WPS_h2n16(E_MACAddress_Length));
	WPS_MEM_CPY(p+4, enrollee->EnrolleeMAC, E_MACAddress_Length);
	MessageLength += 2+2+E_MACAddress_Length;
	p += 2+2+E_MACAddress_Length;

	WPS_set_word(p, WPS_h2n16(E_EnrolleeNonce_ID));
	WPS_set_word(p+2, WPS_h2n16(E_EnrolleeNonce_Length));
	WPS_MEM_CPY(p+4, enrollee->EnrolleeNonce, E_EnrolleeNonce_Length);
	MessageLength += 2+2+E_EnrolleeNonce_Length;
	p += 2+2+E_EnrolleeNonce_Length;

	WPS_set_word(p, WPS_h2n16(E_PublicKey_ID));
	WPS_set_word(p+2, WPS_h2n16(E_PublicKey_Length));
	WPS_MEM_CPY(p+4, enrollee->PK_E, E_PublicKey_Length);
	MessageLength += 2+2+E_PublicKey_Length;
	p += 2+2+E_PublicKey_Length;

	WPS_set_word(p, WPS_h2n16(E_AuthenticationTypeFlags_ID));
	WPS_set_word(p+2, WPS_h2n16(E_AuthenticationTypeFlags_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->AuthenticationTypeFlags_E));
	MessageLength += 2+2+E_AuthenticationTypeFlags_Length;
	p += 2+2+E_AuthenticationTypeFlags_Length;

	WPS_set_word(p, WPS_h2n16(E_EncryptionTypeFlags_ID));
	WPS_set_word(p+2, WPS_h2n16(E_EncryptionTypeFlags_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->EncryptionTypeFlags_E));
	MessageLength += 2+2+E_EncryptionTypeFlags_Length;
	p += 2+2+E_EncryptionTypeFlags_Length;

	WPS_set_word(p, WPS_h2n16(E_ConnectionTypeFlags_ID));
	WPS_set_word(p+2, WPS_h2n16(E_ConnectionTypeFlags_Length));
	*(p+4) = enrollee->ConnectionTypeFlags_E;
	MessageLength += 2+2+E_ConnectionTypeFlags_Length;
	p += 2+2+E_ConnectionTypeFlags_Length;

	WPS_set_word(p, WPS_h2n16(E_ConfigMethods_ID));
	WPS_set_word(p+2, WPS_h2n16(E_ConfigMethods_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->ConfigMethods_E));
	MessageLength += 2+2+E_ConfigMethods_Length;
	p += 2+2+E_ConfigMethods_Length;

	WPS_set_word(p, WPS_h2n16(E_SimpleConfigState_ID));
	WPS_set_word(p+2, WPS_h2n16(E_SimpleConfigState_Length));
	*(p+4) = enrollee->SimpleConfigState_E;
	MessageLength += 2+2+E_SimpleConfigState_Length;
	p += 2+2+E_SimpleConfigState_Length;

	DataLength = WPS_STR_LEN((WPS_char *)(enrollee->Manufacturer_E))+1;
	WPS_set_word(p, WPS_h2n16(E_Manufacturer_ID));
	WPS_set_word(p+2, WPS_h2n16(DataLength));
	WPS_MEM_CPY(p+4, enrollee->Manufacturer_E, DataLength);
	MessageLength += 2+2+DataLength;
	p += 2+2+DataLength;

	DataLength = WPS_STR_LEN((WPS_char *)(enrollee->ModelName_E))+1;
	WPS_set_word(p, WPS_h2n16(E_ModelName_ID));
	WPS_set_word(p+2, WPS_h2n16(DataLength));
	WPS_MEM_CPY(p+4, enrollee->ModelName_E, DataLength);
	MessageLength += 2+2+DataLength;
	p += 2+2+DataLength;

	DataLength = WPS_STR_LEN((WPS_char *)(enrollee->ModelNumber_E))+1;
	WPS_set_word(p, WPS_h2n16(E_ModelNumber_ID));
	WPS_set_word(p+2, WPS_h2n16(DataLength));
	WPS_MEM_CPY(p+4, enrollee->ModelNumber_E, DataLength);
	MessageLength += 2+2+DataLength;
	p += 2+2+DataLength;

	DataLength = WPS_STR_LEN((WPS_char *)(enrollee->SerialNumber_E))+1;
	WPS_set_word(p, WPS_h2n16(E_SerialNumber_ID));
	WPS_set_word(p+2, WPS_h2n16(DataLength));
	WPS_MEM_CPY(p+4, enrollee->SerialNumber_E, DataLength);
	MessageLength += 2+2+DataLength;
	p += 2+2+DataLength;

	WPS_set_word(p, WPS_h2n16(E_PrimaryDeviceType_ID));
	WPS_set_word(p+2, WPS_h2n16(E_PrimaryDeviceType_Length));
	WPS_MEM_CPY(p+4, &(enrollee->primary_device_type_E), E_PrimaryDeviceType_Length);
	MessageLength += 2+2+E_PrimaryDeviceType_Length;
	p += 2+2+E_PrimaryDeviceType_Length;

	DataLength = WPS_STR_LEN((WPS_char *)(enrollee->DeviceName_E))+1;
	WPS_set_word(p, WPS_h2n16(E_DeviceName_ID));
	WPS_set_word(p+2, WPS_h2n16(DataLength));
	WPS_MEM_CPY(p+4, enrollee->DeviceName_E, DataLength);
	MessageLength += 2+2+DataLength;
	p += 2+2+DataLength;

	WPS_set_word(p, WPS_h2n16(E_RFBands_ID));
	WPS_set_word(p+2, WPS_h2n16(E_RFBands_Length));
	*(p+4) = enrollee->RFBands_E;
	MessageLength += 2+2+E_RFBands_Length;
	p += 2+2+E_RFBands_Length;

	WPS_set_word(p, WPS_h2n16(E_AssociationState_ID));
	WPS_set_word(p+2, WPS_h2n16(E_AssociationState_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->AssociationState_E));
	MessageLength += 2+2+E_AssociationState_Length;
	p += 2+2+E_AssociationState_Length;

	WPS_set_word(p, WPS_h2n16(E_DevicePasswordID_ID));
	WPS_set_word(p+2, WPS_h2n16(E_DevicePasswordID_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->DevicePasswordID_E));
	MessageLength += 2+2+E_DevicePasswordID_Length;
	p += 2+2+E_DevicePasswordID_Length;

	WPS_set_word(p, WPS_h2n16(E_ConfigurationError_ID));
	WPS_set_word(p+2, WPS_h2n16(E_ConfigurationError_Length));
	WPS_set_word((p+4), WPS_h2n16(enrollee->ConfigurationError_E));
	MessageLength += 2+2+E_ConfigurationError_Length;
	p += 2+2+E_ConfigurationError_Length;

	WPS_set_word(p, WPS_h2n16(E_OSVersion_ID));
	WPS_set_word(p+2, WPS_h2n16(E_OSVersion_Length));
	WPS_set_dword(p+4, WPS_h2n32(enrollee->OSVersion_E));
	MessageLength += 2+2+E_OSVersion_Length;
	p += 2+2+E_OSVersion_Length;

	//
	// Some optional data elements
	//

	BuildEAPHead(packet, EAP_RESPONSE_CODE, enrollee->eap_id, WSC_MSG, MessageLength);

	WPS_s32 ret = Wlan_SendEapPacket(SendBuff, EAP_HEAD_LENGTH + MessageLength);
	if (ret < 0)
	{
		WPS_PRINTF("SendM1: packet send failed!\n");
		return -1;
	}
	WPS_StartTimer(enrollee->resend_timer, WPS_RETRANSMISSION_TIMEOUT * 1000, wps_resend_packet_timeout, (void *)enrollee);
	WPS_StartTimer(enrollee->permessage_timer, WPS_PER_PACKET_TIMEOUT * 1000, wps_permessage_timeout, (void *)enrollee);

	//
	// Update Enrollee state machine
	//
	enrollee->e_state = E_STATE_D;
#if ENROLLEE_DEBUG	
	WPS_PRINTF("SendM1: Enrollee state change to E_STATE_D\n");
#endif

	//
	// Update LastMessage point
	//
	if (wps_enrol_upt_last_msg_for_snd(enrollee, SendBuff, MessageLength) == -1)
	{
		return -1;
	}

	return 0;
}

WPS_s32 wps_enrol_snd_m3(struct enrollee *enrollee)
{
	WPS_u8 SendBuff[SEND_BUFFER_SIZE];
	struct eap_packet* packet = (struct eap_packet*)(SendBuff);
	WPS_u8 *MessageData = SendBuff + EAP_HEAD_LENGTH;
	WPS_u8 *p = MessageData;
	WPS_s16 MessageLength = 0;

	//
	// To fill the MessageData
	//
	WPS_set_word(p, WPS_h2n16(E_Version_ID));
	WPS_set_word(p+2, WPS_h2n16(E_Version_Length));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -