mirror of https://github.com/acidanthera/audk.git
851 lines
25 KiB
C
851 lines
25 KiB
C
/** @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;
|
|
}
|
|
}
|