678 lines
24 KiB
C
678 lines
24 KiB
C
/** @file
|
|
This driver is the WiFi Profile Sync with CSME through ASF supporting WLAN using
|
|
the WifiConnectionManager driver. This is used only when One Click Recovery driver
|
|
triggers an HTTPS boot recovery and the platfrom supports WLAN HTTPS image recovery
|
|
and boot.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains a 'Sample Driver' and is licensed as such under the terms
|
|
of your license agreement with Intel or your vendor. This file may be modified
|
|
by the user, subject to the additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
#include "WifiProfileSync.h"
|
|
#include "WifiProfileSyncUtils.h"
|
|
#include <WifiProfileSyncAsfMsgs.h>
|
|
#include <Protocol/WifiProfileSyncProtocol.h>
|
|
|
|
#include <Uefi.h>
|
|
#include <CpuRegs.h>
|
|
#include <SetupVariable.h>
|
|
|
|
//
|
|
// Libraries
|
|
//
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/TimerLib.h>
|
|
#include <Library/DxeAsfLib.h>
|
|
#include <Library/BootGuardLibVer1.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DxeAmtHeciLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
|
//
|
|
// GUID's
|
|
//
|
|
#include <Guid/EventGroup.h>
|
|
#include <Guid/GlobalVariable.h>
|
|
#include <Guid/AuthenticatedVariableFormat.h>
|
|
|
|
//
|
|
// Protocol's
|
|
//
|
|
#include <Protocol/WiFi2.h>
|
|
#include <Protocol/AsfProtocol.h>
|
|
#include <Protocol/AmtWrapperProtocol.h>
|
|
|
|
//
|
|
// WiFi Profile Sync Protocol
|
|
//
|
|
GLOBAL_REMOVE_IF_UNREFERENCED WIFI_PROFILE_SYNC_PROTOCOL mWiFiProfileSyncProtocol = {
|
|
WIFI_PROFILE_SYNC_PROTOCOL_REVISION,
|
|
WifiProfileSyncSetConnectStatus,
|
|
WifiProfileSyncGetConnectStatus,
|
|
WifiProfileSyncGetProfile
|
|
};
|
|
|
|
GLOBAL_REMOVE_IF_UNREFERENCED WIFI_PROFILE *mSyncProfile = NULL;
|
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STATUS mWcmConnectionStatus;
|
|
|
|
/**
|
|
Function to set the WiFi connection status recieved by the WiFiConnectionManager
|
|
as EFI_80211_CONNECT_NETWORK_RESULT_CODE, this will get converted to EFI_STATUS
|
|
type
|
|
|
|
@param[in] EFI_80211_CONNECT_NETWORK_RESULT_CODE WiFi connection attempt results
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
WifiProfileSyncSetConnectStatus (
|
|
IN EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
|
|
)
|
|
{
|
|
switch (ConnectionStatus) {
|
|
case ConnectSuccess:
|
|
mWcmConnectionStatus = EFI_SUCCESS;
|
|
break;
|
|
case ConnectRefused:
|
|
mWcmConnectionStatus = EFI_ACCESS_DENIED;
|
|
break;
|
|
case ConnectFailed:
|
|
mWcmConnectionStatus = EFI_DEVICE_ERROR;
|
|
break;
|
|
case ConnectFailureTimeout:
|
|
mWcmConnectionStatus = EFI_TIMEOUT;
|
|
break;
|
|
case ConnectFailedReasonUnspecified:
|
|
mWcmConnectionStatus = EFI_DEVICE_ERROR;
|
|
break;
|
|
default:
|
|
mWcmConnectionStatus = EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
/**
|
|
Function to retrieve the WiFi connection status when in OCR WLAN flow
|
|
|
|
@return EFI_SUCCESS WiFi connection completed succesfully
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WifiProfileSyncGetConnectStatus (
|
|
VOID
|
|
)
|
|
{
|
|
return mWcmConnectionStatus;
|
|
}
|
|
|
|
/**
|
|
Setup data update to included wifi driver.
|
|
|
|
@param [in] NetworkSupport Determine if we are adding or removing the WiFi device from
|
|
PCI required for boot list
|
|
|
|
@retval EFI_SUCCESS Setup data set successfully
|
|
@retval EFI_UNSUPPORTED Failed to get or set the setup data
|
|
@retval Others Error occurred
|
|
**/
|
|
EFI_STATUS
|
|
IncludeWifiSetupData (
|
|
IN BOOLEAN NetworkSupport
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_DATA SetupData;
|
|
UINT32 SetupAttributes;
|
|
UINTN VariableSize;
|
|
EFI_EVENT ReadyToBootServiceEvent;
|
|
|
|
VariableSize = sizeof (SETUP_DATA);
|
|
Status = gRT->GetVariable (
|
|
L"Setup",
|
|
&gSetupVariableGuid,
|
|
&SetupAttributes,
|
|
&VariableSize,
|
|
&SetupData
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get setup data EfiNetworkSupport during update.\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
SetupData.EfiNetworkSupport = NetworkSupport ? EfiNetworkWifi : EfiNetworkDisabled;
|
|
|
|
Status = gRT->SetVariable (
|
|
L"Setup",
|
|
&gSetupVariableGuid,
|
|
SetupAttributes,
|
|
sizeof (SETUP_DATA),
|
|
&SetupData
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to set setup data EfiNetworkSupport during update.\n"));
|
|
ASSERT_EFI_ERROR (Status);
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (NetworkSupport) {
|
|
// Register Ready to Boot Event for resetting the setup data to avoid triggering Wifi connection on regular boot
|
|
Status = EfiCreateEventReadyToBootEx (
|
|
TPL_CALLBACK,
|
|
WifiProfileSyncDisableNetwork,
|
|
NULL,
|
|
&ReadyToBootServiceEvent
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to to register callback to disable network setup data.\n"));
|
|
ASSERT_EFI_ERROR (Status);
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Callback to reset EFI newtork data setup data
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback
|
|
@param[in] Context A pointer to private data registered with the callback function
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
WifiProfileSyncDisableNetwork (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
// Remove WiFi device from PCI device needed for boot
|
|
IncludeWifiSetupData (FALSE);
|
|
}
|
|
|
|
/**
|
|
Event function to clear memory and uninstall WiFi profile protocol from system once
|
|
WiFi Connection Manager has aquired necessary profile data to during OCR WLAN boot flow.
|
|
|
|
@return EFI_SUCCESS Profiles returned
|
|
@return EFI_UNSUPPORTED Protocol not supported
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
WifiProfileSyncClean (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN NumHandle;
|
|
UINTN Index;
|
|
WIFI_PROFILE_SYNC_PROTOCOL *ProfileSyncProtocol;
|
|
|
|
HandleBuffer = NULL;
|
|
|
|
// Clean memory
|
|
if (mSyncProfile != NULL) {
|
|
ZeroMem (mSyncProfile, sizeof (mSyncProfile));
|
|
FreePool (mSyncProfile);
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (&gWiFiProfileSyncProtocolGuid, NULL, (VOID **) &ProfileSyncProtocol);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to find profile protocol with status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
// Get handle for WiFi profile porotocol to uninstall protocol
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gWiFiProfileSyncProtocolGuid,
|
|
NULL,
|
|
&NumHandle,
|
|
&HandleBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get handle to uninstall protocol with status %r\n", Status));
|
|
return Status;
|
|
}
|
|
// Uninstall the WiFi profile protocol
|
|
for (Index = 0; Index < NumHandle; Index++) {
|
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
HandleBuffer[Index],
|
|
&gWiFiProfileSyncProtocolGuid,
|
|
&mWiFiProfileSyncProtocol,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to uninstall WiFi profile protocol."));
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Callback set for exit boot services to clear the profile data from memory and unistall protocol
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback
|
|
@param[in] Context A pointer to private data registered with the callback function
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
WifiProfileSyncCleanCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = WifiProfileSyncClean ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to clean WiFi profile secrets!"));
|
|
}
|
|
gBS->CloseEvent (Event);
|
|
}
|
|
|
|
/**
|
|
This API will be used by the WiFi connection manager to get the WiFi profile that ASF shared
|
|
and stored in WiFi profile protocol. This will as well align the ASF to the WCM profile
|
|
structure
|
|
|
|
@param[in, out] WcmProfile WiFi Connection Manager profile structure
|
|
|
|
@return EFI_SUCCESS Profiles returned
|
|
@return EFI_UNSUPPORTED Profile protocol sharing not supported or enabled
|
|
@return EFI_NOT_FOUND No profiles returned
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WifiProfileSyncGetProfile (
|
|
IN OUT WIFI_MGR_NETWORK_PROFILE *WcmProfile
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Oui_Ieee_80211i;
|
|
|
|
// Send Sync'd ASF profile data to WCM profile data
|
|
WcmProfile->Signature = WIFI_MGR_PROFILE_SIGNATURE;
|
|
WcmProfile->NicIndex = 1;
|
|
WcmProfile->ProfileIndex = 0;
|
|
CopyMem (&WcmProfile->SSId, &mSyncProfile->ProfileData->SSId, mSyncProfile->ProfileData->SSIdLength);
|
|
|
|
// Psk Key
|
|
if (mSyncProfile->ProfileData->PskKeyType == PSK_NETWORK) {
|
|
Status = BufferToHexArray ((CHAR16 *) &WcmProfile->Password, PASSWORD_STORAGE_SIZE, (UINT8 *) &mSyncProfile->ProfileData->PskKey, mSyncProfile->ProfileData->PskKeyLen);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "[WiFiProfileSync] Failed to convert password with status of %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
// CA Certificate
|
|
WcmProfile->CACertSize = mSyncProfile->CaCert->CertSize;
|
|
if (mSyncProfile->CaCert->CertSize > 0) {
|
|
WcmProfile->CACertData = (VOID *) &mSyncProfile->CaCert->Cert;
|
|
} else {
|
|
WcmProfile->CACertData = (VOID *) NULL;
|
|
}
|
|
|
|
// Client certificate and key
|
|
if (mSyncProfile->ProfileData->UserCredentialsClientCertificateAvailable) {
|
|
WcmProfile->ClientCertData = (VOID *) &mSyncProfile->Cert->Certificate;
|
|
WcmProfile->ClientCertSize = mSyncProfile->Cert->CertSize;
|
|
WcmProfile->PrivateKeyData = (VOID *) &mSyncProfile->Key->Key;
|
|
WcmProfile->PrivateKeyDataSize = mSyncProfile->Key->KeySize;
|
|
} else {
|
|
WcmProfile->ClientCertData = NULL;
|
|
WcmProfile->ClientCertSize = 0;
|
|
WcmProfile->PrivateKeyData = NULL;
|
|
WcmProfile->PrivateKeyDataSize = 0;
|
|
}
|
|
|
|
// 802.1x EAP
|
|
WcmProfile->IsAvailable = TRUE;
|
|
WcmProfile->EapAuthMethod = MapEapAuthMethod (mSyncProfile->ProfileData->AuthenticationProtocol_eapMethod);
|
|
if (StrLen ((CHAR16 *) &mSyncProfile->ProfileData->UserCredentialsRoamingIdentity) > 0 ) {
|
|
CopyMem (&WcmProfile->EapIdentity, &mSyncProfile->ProfileData->UserCredentialsRoamingIdentity, sizeof (mSyncProfile->ProfileData->UserCredentialsRoamingIdentity)-1);
|
|
} else {
|
|
CopyMem (&WcmProfile->EapIdentity, &mSyncProfile->ProfileData->UserCredentialsUsername, sizeof (mSyncProfile->ProfileData->UserCredentialsUsername)-1);
|
|
}
|
|
CopyMem (&WcmProfile->EapPassword, &mSyncProfile->ProfileData->UserCredentialsPassword, sizeof (mSyncProfile->ProfileData->UserCredentialsPassword));
|
|
WcmProfile->EapSecondAuthMethod = MapAuthInnerMethodToEapSecondAuthMethod (mSyncProfile->ProfileData->AuthenticationProtocolInnerMethod);
|
|
|
|
// Network authentication and encryption method
|
|
WcmProfile->Network.BSSType = IeeeInfrastructureBSS;
|
|
WcmProfile->Network.AKMSuite = (EFI_80211_AKM_SUITE_SELECTOR *) AllocateZeroPool (sizeof (EFI_80211_AKM_SUITE_SELECTOR));
|
|
WcmProfile->Network.CipherSuite = (EFI_80211_CIPHER_SUITE_SELECTOR *) AllocateZeroPool (sizeof (EFI_80211_CIPHER_SUITE_SELECTOR));
|
|
if ((WcmProfile->Network.AKMSuite == NULL) || (WcmProfile->Network.CipherSuite == NULL)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
WcmProfile->Network.SSId.SSIdLen = mSyncProfile->ProfileData->SSIdLength;
|
|
CopyMem (&WcmProfile->Network.SSId.SSId, &mSyncProfile->ProfileData->SSId, sizeof (WcmProfile->Network.SSId.SSId));
|
|
|
|
WcmProfile->Network.AKMSuite->AKMSuiteCount = 1;
|
|
WcmProfile->Network.CipherSuite->CipherSuiteCount = 1;
|
|
|
|
Oui_Ieee_80211i = OUI_IEEE_80211I;
|
|
CopyMem (&WcmProfile->Network.AKMSuite->AKMSuiteList[0].Oui, &Oui_Ieee_80211i, sizeof (Oui_Ieee_80211i));
|
|
CopyMem (&WcmProfile->Network.CipherSuite->CipherSuiteList[0].Oui, &Oui_Ieee_80211i, sizeof (Oui_Ieee_80211i));
|
|
|
|
WcmProfile->Network.AKMSuite->AKMSuiteList[0].SuiteType = MapAuthenticationToAKM (mSyncProfile->ProfileData->AuthenticationMethod);
|
|
WcmProfile->Network.CipherSuite->CipherSuiteList[0].SuiteType = MapEncryptionToCipher (mSyncProfile->ProfileData->EncryptionMethod);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Retrieve WiFi profile information including client certificate and key using ASF
|
|
|
|
@param[in,out] Profile WiFi profile protocol structure aquired from ASF
|
|
|
|
@return EFI_SUCCESS Profiles returned
|
|
@return EFI_OUT_OF_RESOURCES Not enough memory
|
|
@return EFI_UNSUPPORTED Profile Sync is not supported via PCD or other parameter
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
GetAsfWifiProfile (
|
|
IN OUT WIFI_PROFILE *Profile
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 TimeoutCount = 0;
|
|
|
|
if (Profile == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Invalid profile address supplied!\n"));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
while (TimeoutCount < ME_DELAY_COUNT) {
|
|
// Get ASF profile name
|
|
Profile->ProfileData = (WIFI_PROFILE_DATA *) AllocateZeroPool (sizeof (WIFI_PROFILE_DATA));
|
|
if (Profile->ProfileData == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = AsfWifiGetProfileName (Profile->ProfileData);
|
|
if (!EFI_ERROR (Status) && (Profile->ProfileData->Status == AmtStatusSuccess)) {
|
|
TimeoutCount = 0;
|
|
break;
|
|
}
|
|
MicroSecondDelay (ME_WLAN_DELAY);
|
|
TimeoutCount++;
|
|
if ((TimeoutCount >= ME_DELAY_COUNT) || (Profile->ProfileData->Status != AmtStatusNotFound)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get profile name within time limit with status 0x%X\n", Profile->ProfileData->Status));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
// Get profile data
|
|
Status = AsfWifiGetProfileData (Profile->ProfileData);
|
|
if (EFI_ERROR (Status) || (Profile->ProfileData->Status != AmtStatusSuccess)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (Profile->ProfileData->UserCredentialsClientCertificateAvailable == 0x01) {
|
|
// Get Certificate
|
|
Profile->Cert = (WIFI_8021X_CLIENT_CERT *) AllocateZeroPool (sizeof (WIFI_8021X_CLIENT_CERT));
|
|
if (Profile->Cert == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = AsfWifiGetClientCertificate (Profile);
|
|
if (EFI_ERROR (Status) || (Profile->Cert->Status != AmtStatusSuccess)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get client certificate with status 0x%x\n", Profile->Cert->Status));
|
|
return Status;
|
|
}
|
|
|
|
// Get key
|
|
Profile->Key = (WIFI_8021X_CLIENT_KEY *) AllocateZeroPool (sizeof (WIFI_8021X_CLIENT_KEY));
|
|
if (Profile->Key == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = AsfWifiGetClientKey (Profile);
|
|
if (EFI_ERROR (Status) || (Profile->Key->Status != AmtStatusSuccess)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get client key with status 0x%x\n", Profile->Key->Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
if (Profile->ProfileData->RootCACertificateIndex != ROOT_CA_NOT_AVAILABLE) {
|
|
Profile->CaCert = (ROOT_CA_CERTIFICATE *) AllocateZeroPool (sizeof (ROOT_CA_CERTIFICATE));
|
|
if (Profile->CaCert == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = AsfGetRootCaCertificate (0, Profile->CaCert);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get root CA certificate with status 0x%x\n", Status));
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Enable or disable HECI in the WiFI driver during HTTP boot flows.
|
|
|
|
@param[in] State Value corresponding to enable, TRUE, or disable, FALSE.
|
|
|
|
@return EFI_SUCCESS Successfully set the flag for the WiFi driver
|
|
@return EFI_UNSUPPORTED Failed to set the enable/disable flag
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
EnableWifiAmtCoex (
|
|
IN BOOLEAN State
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = gRT->SetVariable (
|
|
L"EnableWifiAmtCoex",
|
|
&gUefiIntelCnvWlanVariablesGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof(State),
|
|
&State
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Main flow for profile sync drivers getting profile from ASF
|
|
|
|
@return EFI_SUCCESS Profiles returned
|
|
@return EFI_UNSUPPORTED Profile Sync is not supported to retrieve ASF profile
|
|
@return Others Error Occurred
|
|
**/
|
|
EFI_STATUS
|
|
WifiProfileSyncMain (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_EVENT ExitBootServiceEvent;
|
|
WIFI_PROFILE_SYNC_PROTOCOL *ProfileSyncProtocol;
|
|
|
|
mWcmConnectionStatus = EFI_NOT_READY;
|
|
|
|
Status = gBS->LocateProtocol (&gWiFiProfileSyncProtocolGuid, NULL, (VOID **) &ProfileSyncProtocol);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to find profile protocol with status %r\n", Status));
|
|
ASSERT_EFI_ERROR (Status);
|
|
return Status;
|
|
}
|
|
|
|
mSyncProfile = (WIFI_PROFILE *) AllocateZeroPool (sizeof (WIFI_PROFILE));
|
|
if (mSyncProfile == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
// Get profile from ASF
|
|
Status = GetAsfWifiProfile (mSyncProfile);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to get ASF WiFi profile data, certificate, and key with status %r!\n", Status));
|
|
WifiProfileSyncClean ();
|
|
return EFI_LOAD_ERROR;
|
|
}
|
|
|
|
// Set supported network setup variable to WiFi network
|
|
IncludeWifiSetupData (TRUE);
|
|
|
|
// Set WiFi AMT coexistence flag true
|
|
Status = EnableWifiAmtCoex (TRUE);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to set enable WiFi AMT coexistence flag to TRUE with status %r!\n", Status));
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
// Register Exit Boot Services Event to clear profile data from memory
|
|
Status = gBS->CreateEventEx (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_NOTIFY,
|
|
WifiProfileSyncCleanCallback,
|
|
NULL,
|
|
&gEfiEventExitBootServicesGuid,
|
|
&ExitBootServiceEvent
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to register profile protocol clean callback with status %r\n", Status));
|
|
WifiProfileSyncClean ();
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Check for Secure boot, boot gaurd and proper boot options and pcd's are enabling for ProfileSync.
|
|
|
|
@return EFI_SUCCESS Profiles returned
|
|
@return EFI_UNSUPPORTED Protocol not supported
|
|
@return Others Error Occurred
|
|
**/
|
|
BOOLEAN
|
|
IsProfileSyncSupported (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 SpecialCommand;
|
|
UINT8 SecureBootState;
|
|
UINTN VarSize;
|
|
UINT32 VarAttributes;
|
|
UINT64 BootGuardBootStatus;
|
|
UINT64 BootGuardOperationMode;
|
|
AMT_WRAPPER_PROTOCOL *AmtWrapper;
|
|
|
|
// Check for secure boot enabled
|
|
VarSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_SECURE_BOOT_ENABLE_NAME,
|
|
&gEfiSecureBootEnableDisableGuid,
|
|
&VarAttributes,
|
|
&VarSize,
|
|
&SecureBootState
|
|
);
|
|
if (EFI_ERROR (Status) || (SecureBootState == SECURE_BOOT_DISABLE)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Unsupported - Secureboot disabled!\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
if (IsBootGuardSupported ()) {
|
|
BootGuardBootStatus = (*(UINT64 *) (UINTN) (TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_BOOTSTATUS) & (BIT63 | BIT62));
|
|
BootGuardOperationMode = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & (B_BOOT_GUARD_SACM_INFO_MEASURED_BOOT | B_BOOT_GUARD_SACM_INFO_VERIFIED_BOOT);
|
|
|
|
if ((BootGuardBootStatus == V_CPU_BOOT_GUARD_LOAD_ACM_SUCCESS) && (BootGuardOperationMode != 0)) {
|
|
SpecialCommand = AsfGetSpecialCommand ();
|
|
if (SpecialCommand == ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD) {
|
|
return TRUE;
|
|
}
|
|
Status = gBS->LocateProtocol (&gAmtWrapperProtocolGuid, NULL, (VOID **) &AmtWrapper);
|
|
if (!EFI_ERROR (Status) && AmtWrapper->IsKvmEnabled ()) {
|
|
return TRUE;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Unsupported - Bootguard disabled!\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Unsupported - Bootguard is not supported!\n"));
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
The entry point for the Wifi Profile Sync driver.
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the EFI image
|
|
@param[in] SystemTable A pointer to the EFI System Table
|
|
|
|
@retval EFI_SUCCESS The entry point is executed successfully
|
|
@retval other Some error occurs when executing this entry point
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
WifiProfileSyncEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_TPL OldTpl;
|
|
|
|
if (!IsProfileSyncSupported ()) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] WiFi profile sync not supported!\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EnableWifiAmtCoex (FALSE);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to set enable WiFi AMT coexistence flag to FALSE with status %r!\n", Status));
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&ImageHandle,
|
|
&gWiFiProfileSyncProtocolGuid,
|
|
&mWiFiProfileSyncProtocol,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "[WiFiProfileSync] Failed to install protocol with status %r\n", Status));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
|
Status = WifiProfileSyncMain ();
|
|
gBS->RestoreTPL (OldTpl);
|
|
|
|
return Status;
|
|
}
|