/** @file | |
The Miscellaneous Routines for WiFi Connection Manager. | |
Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "WifiConnectionMgrDxe.h" | |
// | |
// STA AKM preference order | |
// REF: https://www.wi-fi.org/file/wpa3-specification | |
// | |
STATIC UINT32 mAKMSuitePreference[] = { | |
IEEE_80211_AKM_SUITE_8021X_SUITE_B192, // AKM Suite 12 | |
IEEE_80211_AKM_SUITE_8021X_SUITE_B, // AKM Suite 11 | |
IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256, // AKM Suite 5 | |
IEEE_80211_AKM_SUITE_8021X_OR_PMKSA, // AKM Suite 1 | |
IEEE_80211_AKM_SUITE_SAE, // AKM Suite 8 | |
IEEE_80211_AKM_SUITE_PSK_SHA256, // AKM Suite 6 | |
IEEE_80211_AKM_SUITE_PSK, // AKM Suite 2 | |
IEEE_80211_AKM_SUITE_OWE // AKM Suite 18 | |
}; | |
#define AKM_SUITE_PREFERENCE_COUNT (sizeof (mAKMSuitePreference) / sizeof (UINT32)) | |
/** | |
Empty function for event process function. | |
@param Event The Event need to be process | |
@param Context The context of the event. | |
**/ | |
VOID | |
EFIAPI | |
WifiMgrInternalEmptyFunction ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
return; | |
} | |
/** | |
Convert the mac address into a hexadecimal encoded ":" seperated string. | |
@param[in] Mac The mac address. | |
@param[in] StrSize The size, in bytes, of the output buffer specified by Str. | |
@param[out] Str The storage to return the mac string. | |
**/ | |
VOID | |
WifiMgrMacAddrToStr ( | |
IN EFI_80211_MAC_ADDRESS *Mac, | |
IN UINT32 StrSize, | |
OUT CHAR16 *Str | |
) | |
{ | |
if ((Mac == NULL) || (Str == NULL)) { | |
return; | |
} | |
UnicodeSPrint ( | |
Str, | |
StrSize, | |
L"%02X:%02X:%02X:%02X:%02X:%02X", | |
Mac->Addr[0], | |
Mac->Addr[1], | |
Mac->Addr[2], | |
Mac->Addr[3], | |
Mac->Addr[4], | |
Mac->Addr[5] | |
); | |
} | |
/** | |
Read private key file to buffer. | |
@param[in] FileContext The file context of private key file. | |
@param[out] PrivateKeyDataAddr The buffer address to restore private key file, should be | |
freed by caller. | |
@param[out] PrivateKeyDataSize The size of read private key file. | |
@retval EFI_SUCCESS Successfully read the private key file. | |
@retval EFI_INVALID_PARAMETER One or more of the parameters is invalid. | |
**/ | |
EFI_STATUS | |
WifiMgrReadFileToBuffer ( | |
IN WIFI_MGR_FILE_CONTEXT *FileContext, | |
OUT VOID **DataAddr, | |
OUT UINTN *DataSize | |
) | |
{ | |
EFI_STATUS Status; | |
if ((FileContext != NULL) && (FileContext->FHandle != NULL)) { | |
Status = ReadFileContent ( | |
FileContext->FHandle, | |
DataAddr, | |
DataSize, | |
0 | |
); | |
if (FileContext->FHandle != NULL) { | |
FileContext->FHandle->Close (FileContext->FHandle); | |
} | |
FileContext->FHandle = NULL; | |
return Status; | |
} | |
return EFI_INVALID_PARAMETER; | |
} | |
/** | |
Get the Nic data by the NicIndex. | |
@param[in] Private The pointer to the global private data structure. | |
@param[in] NicIndex The index indicates the position of wireless NIC. | |
@return Pointer to the Nic data, or NULL if not found. | |
**/ | |
WIFI_MGR_DEVICE_DATA * | |
WifiMgrGetNicByIndex ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
IN UINT32 NicIndex | |
) | |
{ | |
LIST_ENTRY *Entry; | |
WIFI_MGR_DEVICE_DATA *Nic; | |
if (Private == NULL) { | |
return NULL; | |
} | |
NET_LIST_FOR_EACH (Entry, &Private->NicList) { | |
Nic = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_DEVICE_DATA, | |
Link, | |
WIFI_MGR_DEVICE_DATA_SIGNATURE | |
); | |
if (Nic->NicIndex == NicIndex) { | |
return Nic; | |
} | |
} | |
return NULL; | |
} | |
/** | |
Find a network profile through its' SSId and securit type, and the SSId is an unicode string. | |
@param[in] SSId The target network's SSId. | |
@param[in] SecurityType The target network's security type. | |
@param[in] ProfileList The profile list on a Nic. | |
@return Pointer to a network profile, or NULL if not found. | |
**/ | |
WIFI_MGR_NETWORK_PROFILE * | |
WifiMgrGetProfileByUnicodeSSId ( | |
IN CHAR16 *SSId, | |
IN UINT8 SecurityType, | |
IN LIST_ENTRY *ProfileList | |
) | |
{ | |
LIST_ENTRY *Entry; | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
if ((SSId == NULL) || (ProfileList == NULL)) { | |
return NULL; | |
} | |
NET_LIST_FOR_EACH (Entry, ProfileList) { | |
Profile = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_NETWORK_PROFILE, | |
Link, | |
WIFI_MGR_PROFILE_SIGNATURE | |
); | |
if ((StrCmp (SSId, Profile->SSId) == 0) && (SecurityType == Profile->SecurityType)) { | |
return Profile; | |
} | |
} | |
return NULL; | |
} | |
/** | |
Find a network profile through its' SSId and securit type, and the SSId is an ascii string. | |
@param[in] SSId The target network's SSId. | |
@param[in] SecurityType The target network's security type. | |
@param[in] ProfileList The profile list on a Nic. | |
@return Pointer to a network profile, or NULL if not found. | |
**/ | |
WIFI_MGR_NETWORK_PROFILE * | |
WifiMgrGetProfileByAsciiSSId ( | |
IN CHAR8 *SSId, | |
IN UINT8 SecurityType, | |
IN LIST_ENTRY *ProfileList | |
) | |
{ | |
CHAR16 SSIdUniCode[SSID_STORAGE_SIZE]; | |
if (SSId == NULL) { | |
return NULL; | |
} | |
if (AsciiStrToUnicodeStrS (SSId, SSIdUniCode, SSID_STORAGE_SIZE) != RETURN_SUCCESS) { | |
return NULL; | |
} | |
return WifiMgrGetProfileByUnicodeSSId (SSIdUniCode, SecurityType, ProfileList); | |
} | |
/** | |
Find a network profile through its' profile index. | |
@param[in] ProfileIndex The target network's profile index. | |
@param[in] ProfileList The profile list on a Nic. | |
@return Pointer to a network profile, or NULL if not found. | |
**/ | |
WIFI_MGR_NETWORK_PROFILE * | |
WifiMgrGetProfileByProfileIndex ( | |
IN UINT32 ProfileIndex, | |
IN LIST_ENTRY *ProfileList | |
) | |
{ | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
LIST_ENTRY *Entry; | |
if (ProfileList == NULL) { | |
return NULL; | |
} | |
NET_LIST_FOR_EACH (Entry, ProfileList) { | |
Profile = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_NETWORK_PROFILE, | |
Link, | |
WIFI_MGR_PROFILE_SIGNATURE | |
); | |
if (Profile->ProfileIndex == ProfileIndex) { | |
return Profile; | |
} | |
} | |
return NULL; | |
} | |
/** | |
To test if the AKMSuite is in supported AKMSuite list. | |
@param[in] SupportedAKMSuiteCount The count of the supported AKMSuites. | |
@param[in] SupportedAKMSuiteList The supported AKMSuite list. | |
@param[in] AKMSuite The AKMSuite to be tested. | |
@return True if this AKMSuite is supported, or False if not. | |
**/ | |
BOOLEAN | |
WifiMgrSupportAKMSuite ( | |
IN UINT16 SupportedAKMSuiteCount, | |
IN UINT32 *SupportedAKMSuiteList, | |
IN UINT32 *AKMSuite | |
) | |
{ | |
UINT16 Index; | |
if ((AKMSuite == NULL) || (SupportedAKMSuiteList == NULL) || | |
(SupportedAKMSuiteCount == 0)) | |
{ | |
return FALSE; | |
} | |
for (Index = 0; Index < SupportedAKMSuiteCount; Index++) { | |
if (SupportedAKMSuiteList[Index] == *AKMSuite) { | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} | |
/** | |
To check if the CipherSuite is in supported CipherSuite list. | |
@param[in] SupportedCipherSuiteCount The count of the supported CipherSuites. | |
@param[in] SupportedCipherSuiteList The supported CipherSuite list. | |
@param[in] CipherSuite The CipherSuite to be tested. | |
@return True if this CipherSuite is supported, or False if not. | |
**/ | |
BOOLEAN | |
WifiMgrSupportCipherSuite ( | |
IN UINT16 SupportedCipherSuiteCount, | |
IN UINT32 *SupportedCipherSuiteList, | |
IN UINT32 *CipherSuite | |
) | |
{ | |
UINT16 Index; | |
if ((CipherSuite == NULL) || (SupportedCipherSuiteCount == 0) || | |
(SupportedCipherSuiteList == NULL)) | |
{ | |
return FALSE; | |
} | |
for (Index = 0; Index < SupportedCipherSuiteCount; Index++) { | |
if (SupportedCipherSuiteList[Index] == *CipherSuite) { | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} | |
/** | |
Check an AKM suite list and a Cipher suite list to see if one or more AKM suites or Cipher suites | |
are supported and find the matchable security type. | |
@param[in] AKMList The target AKM suite list to be checked. | |
@param[in] CipherList The target Cipher suite list to be checked | |
@param[in] Nic The Nic to operate, contains the supported AKMSuite list | |
and supported CipherSuite list | |
@param[out] SecurityType To identify a security type from the AKM suite list and | |
Cipher suite list | |
@param[out] AKMSuiteSupported To identify if this security type is supported. If it is | |
NULL, overcome this field | |
@param[out] CipherSuiteSupported To identify if this security type is supported. If it is | |
NULL, overcome this field | |
@retval EFI_SUCCESS This operation has completed successfully. | |
@retval EFI_INVALID_PARAMETER No Nic found or the suite list is null. | |
**/ | |
EFI_STATUS | |
WifiMgrCheckRSN ( | |
IN EFI_80211_AKM_SUITE_SELECTOR *AKMList, | |
IN EFI_80211_CIPHER_SUITE_SELECTOR *CipherList, | |
IN WIFI_MGR_DEVICE_DATA *Nic, | |
OUT UINT8 *SecurityType, | |
OUT BOOLEAN *AKMSuiteSupported, | |
OUT BOOLEAN *CipherSuiteSupported | |
) | |
{ | |
EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; | |
EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; | |
EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; | |
UINT32 *AKMSuite; | |
EFI_80211_SUITE_SELECTOR *CipherSuite; | |
UINT16 AKMIndex; | |
UINT16 CipherIndex; | |
if ((Nic == NULL) || (AKMList == NULL) || (CipherList == NULL) || (SecurityType == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
SupportedAKMSuites = Nic->SupportedSuites.SupportedAKMSuites; | |
SupportedSwCipherSuites = Nic->SupportedSuites.SupportedSwCipherSuites; | |
SupportedHwCipherSuites = Nic->SupportedSuites.SupportedHwCipherSuites; | |
*SecurityType = SECURITY_TYPE_UNKNOWN; | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*AKMSuiteSupported = FALSE; | |
*CipherSuiteSupported = FALSE; | |
} | |
if (AKMList->AKMSuiteCount == 0) { | |
if (CipherList->CipherSuiteCount == 0) { | |
*SecurityType = SECURITY_TYPE_NONE; | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*AKMSuiteSupported = TRUE; | |
*CipherSuiteSupported = TRUE; | |
} | |
} | |
return EFI_SUCCESS; | |
} | |
for (AKMIndex = 0; AKMIndex < AKM_SUITE_PREFERENCE_COUNT; AKMIndex++) { | |
AKMSuite = mAKMSuitePreference + AKMIndex; | |
if (WifiMgrSupportAKMSuite (AKMList->AKMSuiteCount, (UINT32 *)AKMList->AKMSuiteList, AKMSuite) && | |
WifiMgrSupportAKMSuite (SupportedAKMSuites->AKMSuiteCount, (UINT32 *)SupportedAKMSuites->AKMSuiteList, AKMSuite)) | |
{ | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*AKMSuiteSupported = TRUE; | |
} | |
// | |
// OWE transition mode allow CipherSuiteCount is 0 | |
// | |
if (CipherList->CipherSuiteCount == 0) { | |
*SecurityType = WifiMgrGetSecurityType ((UINT32 *)AKMSuite, NULL); | |
if (*SecurityType != SECURITY_TYPE_UNKNOWN) { | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*CipherSuiteSupported = TRUE; | |
} | |
return EFI_SUCCESS; | |
} | |
} | |
for (CipherIndex = 0; CipherIndex < CipherList->CipherSuiteCount; CipherIndex++) { | |
CipherSuite = CipherList->CipherSuiteList + CipherIndex; | |
if (SupportedSwCipherSuites != NULL) { | |
if (WifiMgrSupportCipherSuite ( | |
SupportedSwCipherSuites->CipherSuiteCount, | |
(UINT32 *)SupportedSwCipherSuites->CipherSuiteList, | |
(UINT32 *)CipherSuite | |
)) | |
{ | |
*SecurityType = WifiMgrGetSecurityType ((UINT32 *)AKMSuite, (UINT32 *)CipherSuite); | |
if (*SecurityType != SECURITY_TYPE_UNKNOWN) { | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*CipherSuiteSupported = TRUE; | |
} | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
if (SupportedHwCipherSuites != NULL) { | |
if (WifiMgrSupportCipherSuite ( | |
SupportedHwCipherSuites->CipherSuiteCount, | |
(UINT32 *)SupportedHwCipherSuites->CipherSuiteList, | |
(UINT32 *)CipherSuite | |
)) | |
{ | |
*SecurityType = WifiMgrGetSecurityType ((UINT32 *)AKMSuite, (UINT32 *)CipherSuite); | |
if (*SecurityType != SECURITY_TYPE_UNKNOWN) { | |
if ((AKMSuiteSupported != NULL) && (CipherSuiteSupported != NULL)) { | |
*CipherSuiteSupported = TRUE; | |
} | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
} | |
} | |
} | |
*SecurityType = WifiMgrGetSecurityType ( | |
(UINT32 *)AKMList->AKMSuiteList, | |
(UINT32 *)CipherList->CipherSuiteList | |
); | |
return EFI_SUCCESS; | |
} | |
/** | |
Get the security type for a certain AKMSuite and CipherSuite. | |
@param[in] AKMSuite An certain AKMSuite. | |
@param[in] CipherSuite An certain CipherSuite. | |
@return a security type if found, or SECURITY_TYPE_UNKNOWN. | |
**/ | |
UINT8 | |
WifiMgrGetSecurityType ( | |
IN UINT32 *AKMSuite, | |
IN UINT32 *CipherSuite | |
) | |
{ | |
if ((AKMSuite != NULL) && (*AKMSuite == IEEE_80211_AKM_SUITE_OWE)) { | |
return SECURITY_TYPE_NONE; | |
} | |
if (CipherSuite == NULL) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_NONE; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_USE_GROUP) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_NONE; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else if ((*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP40) || | |
(*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP104)) | |
{ | |
return SECURITY_TYPE_WEP; | |
} else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_CCMP) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
if (*AKMSuite == IEEE_80211_AKM_SUITE_SAE) { | |
return SECURITY_TYPE_WPA3_PERSONAL; | |
} else if ((*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA) || | |
(*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256)) | |
{ | |
return SECURITY_TYPE_WPA2_ENTERPRISE; | |
} else if ((*AKMSuite == IEEE_80211_AKM_SUITE_PSK) || | |
(*AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256)) | |
{ | |
return SECURITY_TYPE_WPA2_PERSONAL; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_TKIP) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
if ((*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA) || | |
(*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256)) | |
{ | |
return SECURITY_TYPE_WPA_ENTERPRISE; | |
} else if ((*AKMSuite == IEEE_80211_AKM_SUITE_PSK) || | |
(*AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256)) | |
{ | |
return SECURITY_TYPE_WPA_PERSONAL; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_GCMP) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_SUITE_B) { | |
return SECURITY_TYPE_WPA3_ENTERPRISE; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_GCMP256) { | |
if (AKMSuite == NULL) { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_SUITE_B192) { | |
return SECURITY_TYPE_WPA3_ENTERPRISE; | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} else { | |
return SECURITY_TYPE_UNKNOWN; | |
} | |
} | |
/** | |
Get supported AKMSuites and CipherSuites from supplicant for a Nic. | |
@param[in] Nic The Nic to operate. | |
@retval EFI_SUCCESS Get the supported suite list successfully. | |
@retval EFI_INVALID_PARAMETER No Nic found or supplicant is NULL. | |
**/ | |
EFI_STATUS | |
WifiMgrGetSupportedSuites ( | |
IN WIFI_MGR_DEVICE_DATA *Nic | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_SUPPLICANT_PROTOCOL *Supplicant; | |
EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; | |
EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; | |
EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; | |
UINTN DataSize; | |
SupportedAKMSuites = NULL; | |
SupportedSwCipherSuites = NULL; | |
SupportedHwCipherSuites = NULL; | |
if ((Nic == NULL) || (Nic->Supplicant == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Supplicant = Nic->Supplicant; | |
DataSize = 0; | |
Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedAKMSuites, NULL, &DataSize); | |
if ((Status == EFI_BUFFER_TOO_SMALL) && (DataSize > 0)) { | |
SupportedAKMSuites = AllocateZeroPool (DataSize); | |
if (SupportedAKMSuites == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Status = Supplicant->GetData ( | |
Supplicant, | |
EfiSupplicant80211SupportedAKMSuites, | |
(UINT8 *)SupportedAKMSuites, | |
&DataSize | |
); | |
if (!EFI_ERROR (Status)) { | |
Nic->SupportedSuites.SupportedAKMSuites = SupportedAKMSuites; | |
} else { | |
FreePool (SupportedAKMSuites); | |
} | |
} else { | |
SupportedAKMSuites = NULL; | |
} | |
DataSize = 0; | |
Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedSoftwareCipherSuites, NULL, &DataSize); | |
if ((Status == EFI_BUFFER_TOO_SMALL) && (DataSize > 0)) { | |
SupportedSwCipherSuites = AllocateZeroPool (DataSize); | |
if (SupportedSwCipherSuites == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Status = Supplicant->GetData ( | |
Supplicant, | |
EfiSupplicant80211SupportedSoftwareCipherSuites, | |
(UINT8 *)SupportedSwCipherSuites, | |
&DataSize | |
); | |
if (!EFI_ERROR (Status)) { | |
Nic->SupportedSuites.SupportedSwCipherSuites = SupportedSwCipherSuites; | |
} else { | |
FreePool (SupportedSwCipherSuites); | |
} | |
} else { | |
SupportedSwCipherSuites = NULL; | |
} | |
DataSize = 0; | |
Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedHardwareCipherSuites, NULL, &DataSize); | |
if ((Status == EFI_BUFFER_TOO_SMALL) && (DataSize > 0)) { | |
SupportedHwCipherSuites = AllocateZeroPool (DataSize); | |
if (SupportedHwCipherSuites == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Status = Supplicant->GetData ( | |
Supplicant, | |
EfiSupplicant80211SupportedHardwareCipherSuites, | |
(UINT8 *)SupportedHwCipherSuites, | |
&DataSize | |
); | |
if (!EFI_ERROR (Status)) { | |
Nic->SupportedSuites.SupportedHwCipherSuites = SupportedHwCipherSuites; | |
} else { | |
FreePool (SupportedHwCipherSuites); | |
} | |
} else { | |
SupportedHwCipherSuites = NULL; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Clean secrets from a network profile. | |
@param[in] Profile The profile to be cleanned. | |
**/ | |
VOID | |
WifiMgrCleanProfileSecrets ( | |
IN WIFI_MGR_NETWORK_PROFILE *Profile | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol; | |
ZeroMem (Profile->Password, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); | |
ZeroMem (Profile->EapPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); | |
ZeroMem (Profile->PrivateKeyPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); | |
// | |
// When EFI WiFi profile sync protocol is found the system is performing a recovery boot in secure | |
// boot mode. The profile sync driver will manage the CA certificate, client certificate, and key | |
// data, cleaning them at exit boot services. | |
// | |
Status = gBS->LocateProtocol (&gEdkiiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol); | |
if (!EFI_ERROR (Status)) { | |
return; | |
} | |
if (Profile->CACertData != NULL) { | |
ZeroMem (Profile->CACertData, Profile->CACertSize); | |
FreePool (Profile->CACertData); | |
} | |
Profile->CACertData = NULL; | |
Profile->CACertSize = 0; | |
if (Profile->ClientCertData != NULL) { | |
ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); | |
FreePool (Profile->ClientCertData); | |
} | |
Profile->ClientCertData = NULL; | |
Profile->ClientCertSize = 0; | |
if (Profile->PrivateKeyData != NULL) { | |
ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize); | |
FreePool (Profile->PrivateKeyData); | |
} | |
Profile->PrivateKeyData = NULL; | |
Profile->PrivateKeyDataSize = 0; | |
} | |
/** | |
Free all network profiles in a profile list. | |
@param[in] ProfileList The profile list to be freed. | |
**/ | |
VOID | |
WifiMgrFreeProfileList ( | |
IN LIST_ENTRY *ProfileList | |
) | |
{ | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
LIST_ENTRY *Entry; | |
LIST_ENTRY *NextEntry; | |
if (ProfileList == NULL) { | |
return; | |
} | |
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ProfileList) { | |
Profile = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_NETWORK_PROFILE, | |
Link, | |
WIFI_MGR_PROFILE_SIGNATURE | |
); | |
WifiMgrCleanProfileSecrets (Profile); | |
if (Profile->Network.AKMSuite != NULL) { | |
FreePool (Profile->Network.AKMSuite); | |
} | |
if (Profile->Network.CipherSuite != NULL) { | |
FreePool (Profile->Network.CipherSuite); | |
} | |
FreePool (Profile); | |
} | |
} | |
/** | |
Free user configured hidden network list. | |
@param[in] HiddenList The hidden network list to be freed. | |
**/ | |
VOID | |
WifiMgrFreeHiddenList ( | |
IN LIST_ENTRY *HiddenList | |
) | |
{ | |
WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; | |
LIST_ENTRY *Entry; | |
LIST_ENTRY *NextEntry; | |
if (HiddenList == NULL) { | |
return; | |
} | |
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, HiddenList) { | |
HiddenNetwork = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_HIDDEN_NETWORK_DATA, | |
Link, | |
WIFI_MGR_HIDDEN_NETWORK_SIGNATURE | |
); | |
FreePool (HiddenNetwork); | |
} | |
} | |
/** | |
Free the resources of a config token. | |
@param[in] ConfigToken The config token to be freed. | |
**/ | |
VOID | |
WifiMgrFreeToken ( | |
IN WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken | |
) | |
{ | |
EFI_80211_GET_NETWORKS_RESULT *Result; | |
if (ConfigToken == NULL) { | |
return; | |
} | |
switch (ConfigToken->Type) { | |
case TokenTypeGetNetworksToken: | |
if (ConfigToken->Token.GetNetworksToken != NULL) { | |
gBS->CloseEvent (ConfigToken->Token.GetNetworksToken->Event); | |
if (ConfigToken->Token.GetNetworksToken->Data != NULL) { | |
FreePool (ConfigToken->Token.GetNetworksToken->Data); | |
} | |
Result = ConfigToken->Token.GetNetworksToken->Result; | |
if (Result != NULL) { | |
FreePool (Result); | |
} | |
FreePool (ConfigToken->Token.GetNetworksToken); | |
} | |
FreePool (ConfigToken); | |
break; | |
case TokenTypeConnectNetworkToken: | |
if (ConfigToken->Token.ConnectNetworkToken != NULL) { | |
gBS->CloseEvent (ConfigToken->Token.ConnectNetworkToken->Event); | |
if (ConfigToken->Token.ConnectNetworkToken->Data != NULL) { | |
FreePool (ConfigToken->Token.ConnectNetworkToken->Data); | |
} | |
FreePool (ConfigToken->Token.ConnectNetworkToken); | |
} | |
FreePool (ConfigToken); | |
break; | |
case TokenTypeDisconnectNetworkToken: | |
if (ConfigToken->Token.DisconnectNetworkToken != NULL) { | |
FreePool (ConfigToken->Token.DisconnectNetworkToken); | |
} | |
FreePool (ConfigToken); | |
break; | |
default: | |
break; | |
} | |
} |