public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] NetworkPkg: Add WiFi profile sync protocol support
@ 2022-09-14 19:42 Clark-williams, Zachary
  2022-09-26  7:37 ` [edk2-devel] " Heng Luo
  0 siblings, 1 reply; 11+ messages in thread
From: Clark-williams, Zachary @ 2022-09-14 19:42 UTC (permalink / raw)
  To: devel; +Cc: Zachary Clark-Williams, Zachary Clark-Williams

From: Zachary Clark-Williams <zclarkw112@gmail.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845

Enables KVM and One Click Recovery WLAN capability with WiFi Profile
Sync feature and protocol. Adding WiFiProfileSyncProtocol, which
supports the profilesync driver operations for transferring WiFi profiles
from AMT to the Supplicant. WiFiConnectionManager will check for the
WifiProfileSyncProtocol and if found will operate on the premise of a
One Click Recovery, or KVM flow with a Wifi profile provided by AMT.

Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
---
 .../Protocol/WiFiProfileSyncProtocol.h        |  83 ++++++++
 NetworkPkg/NetworkPkg.dec                     |   3 +
 .../WifiConnectionManagerDxe.inf              |   3 +-
 .../WifiConnectionMgrDriver.c                 | 126 +++++++----
 .../WifiConnectionMgrDxe.h                    |   4 +-
 .../WifiConnectionMgrImpl.c                   | 197 ++++++++++++++++--
 .../WifiConnectionMgrMisc.c                   |  13 ++
 7 files changed, 370 insertions(+), 59 deletions(-)
 create mode 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h

diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
new file mode 100644
index 0000000000..e36daceabf
--- /dev/null
+++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
@@ -0,0 +1,83 @@
+/** @file
+  WiFi profile sync protocol. Supports One Click Recovery or KVM OS recovery
+  boot flow over WiFi.
+
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
+#define WIFI_PROFILE_SYNC_PROTOCOL_H_
+
+#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
+
+//
+//  WiFi Profile Sync Protocol GUID variable.
+//
+extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
+
+/**
+  Used by the WiFi connection manager to get the WiFi profile that AMT shared
+  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
+  the WiFi connection manager profile structure fo connection use.
+
+  @param[in, out]  WcmProfile       WiFi Connection Manager profile structure
+  @param[in, out]  MacAddress       MAC address from AMT saved to NiC MAC address
+
+  @retval EFI_SUCCESS               Stored WiFi profile converted and returned succefully
+  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or enabled
+  @retval EFI_NOT_FOUND             No profiles to returned
+  @retval Others                    Error Occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_PROFILE_GET)(
+  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
+  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
+  );
+
+/**
+  Saves the WiFi connection status recieved by the WiFiConnectionManager when
+  in a KVM OR One Click Recovery WLAN recovery flow. Input as
+  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and stored as EFI_STATUS type.
+
+  @param[in] ConnectionStatus     WiFi connection attempt results
+**/
+typedef
+VOID
+(EFIAPI *WIFI_SET_CONNECT_STATE)(
+  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
+  );
+
+/**
+  Retrieves the stored WiFi connection status when in either KVM OR One Click
+  Recovery WLAN recovery flow.
+
+  @retval EFI_SUCCESS               WiFi connection completed succesfully
+  @retval Others                    Connection failure occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_GET_CONNECT_STATE)(
+  VOID
+  );
+
+//
+//  WiFi Profile Sync Protocol structure.
+//
+typedef struct {
+  UINT32                    Revision;
+  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;
+  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;
+  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;
+} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
+
+/**
+  WiFi Profile Protocol revision number.
+
+  Revision 1:   Initial version
+**/
+#define EFI_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
+
+#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 5e43ebf8c5..53fb34c4a0 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -91,6 +91,9 @@
   ## Include/Protocol/HttpCallback.h
   gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
 
+  ## Include/Protocol/WiFiProfileSyncProtocol.h
+  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
+
 [PcdsFixedAtBuild]
   ## The max attempt number will be created by iSCSI driver.
   # @Prompt Max attempt number.
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
index 4394b6f4bb..7e36016cf8 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
@@ -9,7 +9,7 @@
 #  2). WPA2 Personal Network
 #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
 #
-#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -71,6 +71,7 @@
   gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
   gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
 
 [Guids]
   gWifiConfigGuid                               ## PRODUCES  ## GUID
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
index 67a01ca058..65df5b2c8a 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
@@ -1,7 +1,7 @@
 /** @file
   The driver binding protocol for the WiFi Connection Manager.
 
-  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_G
 EFI_GUID  mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
 EFI_GUID  mWifiConfigMainFormRefreshGuid    = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
 
+//
+// Wifi connection attempt counter for retries
+//
+extern UINT8  WifiConnectionCount;
+
 /**
   Tests to see if this driver supports a given controller. If a child device is provided,
   it further tests to see if this driver supports creating a handle for the specified child device.
@@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
   EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
   EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
   EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;
 
-  Nic = NULL;
+  WifiConnectionCount = 0;
+  Nic                 = NULL;
 
   //
   // Open Protocols
@@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
   InitializeListHead (&Nic->ProfileList);
 
   //
-  // Record the MAC address of the incoming NIC.
+  // WiFi profile sync protocol installation check for OS recovery flow.
   //
-  Status = NetLibGetMacAddress (
-             ControllerHandle,
-             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
-             &AddressSize
-             );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
-
-  //
-  // Create and start the timer for the status check
-  //
-  Status = gBS->CreateEvent (
-                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
-                  TPL_CALLBACK,
-                  WifiMgrOnTimerTick,
-                  Nic,
-                  &Nic->TickTimer
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
                   );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
+  if (!EFI_ERROR (Status)) {
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ERROR1;
+    }
 
-  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
-  if (EFI_ERROR (Status)) {
-    goto ERROR3;
-  }
+    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (Nic->ConnectPendingNetwork != NULL) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (EFI_ERROR (Status)) {
+        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+      }
+    } else {
+      goto ERROR1;
+    }
+  } else {
+    //
+    // Record the MAC address of the incoming NIC.
+    //
+    Status = NetLibGetMacAddress (
+               ControllerHandle,
+               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
+               &AddressSize
+               );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  Nic->ConnectState = WifiMgrDisconnected;
-  Nic->ScanState    = WifiMgrScanFinished;
+    //
+    // Create and start the timer for the status check
+    //
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
+                    TPL_CALLBACK,
+                    WifiMgrOnTimerTick,
+                    Nic,
+                    &Nic->TickTimer
+                    );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-  InsertTailList (&mPrivate->NicList, &Nic->Link);
-  Nic->NicIndex = mPrivate->NicCount++;
-  if (mPrivate->CurrentNic == NULL) {
-    mPrivate->CurrentNic = Nic;
-  }
+    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
+    if (EFI_ERROR (Status)) {
+      goto ERROR3;
+    }
 
-  gBS->RestoreTPL (OldTpl);
+    Nic->ConnectState = WifiMgrDisconnected;
+    Nic->ScanState    = WifiMgrScanFinished;
+
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+    InsertTailList (&mPrivate->NicList, &Nic->Link);
+    Nic->NicIndex = mPrivate->NicCount++;
+    if (mPrivate->CurrentNic == NULL) {
+      mPrivate->CurrentNic = Nic;
+    }
+
+    gBS->RestoreTPL (OldTpl);
+  }
 
   Status = gBS->InstallProtocolInterface (
                   &ControllerHandle,
@@ -385,10 +418,11 @@ WifiMgrDxeDriverBindingStop (
   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
   )
 {
-  EFI_STATUS                 Status;
-  EFI_TPL                    OldTpl;
-  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
-  WIFI_MGR_DEVICE_DATA       *Nic;
+  EFI_STATUS                      Status;
+  EFI_TPL                         OldTpl;
+  WIFI_MGR_PRIVATE_PROTOCOL       *WifiMgrIdentifier;
+  WIFI_MGR_DEVICE_DATA            *Nic;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   Status = gBS->OpenProtocol (
                   ControllerHandle,
@@ -481,7 +515,15 @@ WifiMgrDxeDriverBindingStop (
   //
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
-  RemoveEntryList (&Nic->Link);
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    RemoveEntryList (&Nic->Link);
+  }
+
   mPrivate->NicCount--;
   if (mPrivate->CurrentNic == Nic) {
     mPrivate->CurrentNic = NULL;
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
index 7b2e41e155..047f85dbc2 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
@@ -47,6 +47,7 @@
 #include <Protocol/SimpleNetwork.h>
 #include <Protocol/SimpleFileSystem.h>
 #include <Protocol/EapConfiguration.h>
+#include <Protocol/WiFiProfileSyncProtocol.h>
 
 //
 // Produced Protocols
@@ -73,7 +74,8 @@
 //
 #define WIFI_MGR_DXE_VERSION  0xb
 
-#define OUI_IEEE_80211I  0xAC0F00
+#define OUI_IEEE_80211I              0xAC0F00
+#define MAX_WIFI_CONNETION_ATTEMPTS  3
 
 typedef enum {
   Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0,
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
index 59bac48c42..3a04b4ddb1 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
@@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
   EFI_EAP_TYPE_MSCHAPV2
 };
 
+UINT8  WifiConnectionCount = 0;
+
 /**
   The callback function for scan operation. This function updates networks
   according to the latest scan result, and trigger UI refresh.
@@ -420,22 +422,34 @@ WifiMgrConfigPassword (
   //
   // Set password to supplicant
   //
+  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
+    Profile->Password[StrLen (Profile->Password)] = L'\0';
+  }
+
   if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {
     return EFI_NOT_FOUND;
   }
 
-  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
+  if (StrLen (Profile->Password) > PASSWORD_STORAGE_SIZE) {
+    ASSERT (EFI_INVALID_PARAMETER);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));
   if (AsciiPassword == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
-  Status = Supplicant->SetData (
-                         Supplicant,
-                         EfiSupplicant80211PskPassword,
-                         AsciiPassword,
-                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
-                         );
+  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, ((StrLen (Profile->Password) + 1) * sizeof (CHAR8)));
+  if (!EFI_ERROR (Status)) {
+    Status = Supplicant->SetData (
+                           Supplicant,
+                           EfiSupplicant80211PskPassword,
+                           AsciiPassword,
+                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
+                           );
+  }
+
   ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
   FreePool (AsciiPassword);
 
@@ -466,6 +480,7 @@ WifiMgrConfigEap (
   )
 {
   EFI_STATUS                      Status;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
   EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
   EFI_EAP_TYPE                    EapAuthMethod;
   EFI_EAP_TYPE                    EapSecondAuthMethod;
@@ -567,7 +582,13 @@ WifiMgrConfigEap (
       return EFI_OUT_OF_RESOURCES;
     }
 
-    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+    if (!EFI_ERROR (Status)) {
+      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
+    } else {
+      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    }
+
     Status = EapConfig->SetData (
                           EapConfig,
                           EFI_EAP_TYPE_IDENTITY,
@@ -892,6 +913,133 @@ WifiMgrPrepareConnection (
   return EFI_SUCCESS;
 }
 
+/**
+  Will reset NiC data, get profile from profile sync driver, and send for
+  another connection attempt.This function should not be called more than
+  3 times.
+
+  @param[in]  WiFiProfileSyncProtocol  The target network profile to connect.
+
+  @retval EFI_SUCCESS                  The operation is completed.
+  @retval other                        Operation failure.
+
+**/
+EFI_STATUS
+ConnectionRetry (
+  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
+  )
+{
+  EFI_STATUS                               Status;
+  WIFI_MGR_DEVICE_DATA                     *Nic;
+  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
+  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
+  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+
+  Nic = NULL;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFi2ProtocolGuid,
+                  NULL,
+                  (VOID **)&Wmp
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSupplicantProtocolGuid,
+                  NULL,
+                  (VOID **)&Supplicant
+                  );
+  if (EFI_ERROR (Status)) {
+    Supplicant = NULL;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiEapConfigurationProtocolGuid,
+                  NULL,
+                  (VOID **)&EapConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    EapConfig = NULL;
+  }
+
+  //
+  // Initialize Nic device data
+  //
+  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
+  if (Nic == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    return Status;
+  }
+
+  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
+  Nic->Private             = mPrivate;
+  Nic->Wmp                 = Wmp;
+  Nic->Supplicant          = Supplicant;
+  Nic->EapConfig           = EapConfig;
+  Nic->UserSelectedProfile = NULL;
+  Nic->OneTimeScanRequest  = FALSE;
+
+  if (Nic->Supplicant != NULL) {
+    Status = WifiMgrGetSupportedSuites (Nic);
+  }
+
+  if (!EFI_ERROR (Status)) {
+    InitializeListHead (&Nic->ProfileList);
+
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
+      goto ERROR;
+    }
+
+    Status = WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        return Status;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));
+  }
+
+  if (Nic->ConnectPendingNetwork != NULL) {
+    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
+    }
+
+    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
+    }
+
+    FreePool (Nic->ConnectPendingNetwork);
+  }
+
+ERROR:
+  if (Nic->Supplicant != NULL) {
+    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
+    }
+  }
+
+  FreePool (Nic);
+
+  return Status;
+}
+
 /**
   The callback function for connect operation.
 
@@ -908,12 +1056,13 @@ WifiMgrOnConnectFinished (
   IN  VOID       *Context
   )
 {
-  EFI_STATUS                 Status;
-  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
-  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
-  UINT8                      SecurityType;
-  UINT8                      SSIdLen;
-  CHAR8                      *AsciiSSId;
+  EFI_STATUS                      Status;
+  WIFI_MGR_MAC_CONFIG_TOKEN       *ConfigToken;
+  WIFI_MGR_NETWORK_PROFILE        *ConnectedProfile;
+  UINT8                           SecurityType;
+  UINT8                           SSIdLen;
+  CHAR8                           *AsciiSSId;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   ASSERT (Context != NULL);
 
@@ -925,6 +1074,24 @@ WifiMgrOnConnectFinished (
   ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
 
   ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
+
+  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
+    if ((WifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
+        (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
+    {
+      WifiConnectionCount++;
+      gBS->CloseEvent (Event);
+      Status = ConnectionRetry (WiFiProfileSyncProtocol);
+      if (!EFI_ERROR (Status)) {
+        return;
+      }
+
+      WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+    }
+  }
+
   if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
     if (ConfigToken->Nic->OneTimeConnectRequest) {
       //
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
index 4ad5643c24..87adfc5033 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
@@ -672,10 +672,23 @@ WifiMgrCleanProfileSecrets (
   IN  WIFI_MGR_NETWORK_PROFILE  *Profile
   )
 {
+  EFI_STATUS                      Status;
+  EFI_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 (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    return;
+  }
+
   if (Profile->CACertData != NULL) {
     ZeroMem (Profile->CACertData, Profile->CACertSize);
     FreePool (Profile->CACertData);
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2022-09-14 19:42 [PATCH] NetworkPkg: Add WiFi profile sync protocol support Clark-williams, Zachary
@ 2022-09-26  7:37 ` Heng Luo
  2022-09-26 15:39   ` Clark-williams, Zachary
  0 siblings, 1 reply; 11+ messages in thread
From: Heng Luo @ 2022-09-26  7:37 UTC (permalink / raw)
  To: devel@edk2.groups.io, Clark-williams, Zachary
  Cc: Zachary Clark-Williams, Maciej Rabeda

Hi Zachary,
> @@ -420,22 +422,34 @@ WifiMgrConfigPassword (
>    //
>    // Set password to supplicant
>    //
> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
> +
I don't understand this change, StrLen returns the length of a Null-terminated Unicode string, it means "Profile->Password[StrLen (Profile->Password)]" should always be 0. Did you see exceptional case?

Thanks,
Heng

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Clark-
> williams, Zachary
> Sent: Thursday, September 15, 2022 3:43 AM
> To: devel@edk2.groups.io
> Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Clark-williams, Zachary
> <zachary.clark-williams@intel.com>
> Subject: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol
> support
> 
> From: Zachary Clark-Williams <zclarkw112@gmail.com>
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845
> 
> Enables KVM and One Click Recovery WLAN capability with WiFi Profile Sync
> feature and protocol. Adding WiFiProfileSyncProtocol, which supports the
> profilesync driver operations for transferring WiFi profiles from AMT to the
> Supplicant. WiFiConnectionManager will check for the
> WifiProfileSyncProtocol and if found will operate on the premise of a One
> Click Recovery, or KVM flow with a Wifi profile provided by AMT.
> 
> Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
> ---
>  .../Protocol/WiFiProfileSyncProtocol.h        |  83 ++++++++
>  NetworkPkg/NetworkPkg.dec                     |   3 +
>  .../WifiConnectionManagerDxe.inf              |   3 +-
>  .../WifiConnectionMgrDriver.c                 | 126 +++++++----
>  .../WifiConnectionMgrDxe.h                    |   4 +-
>  .../WifiConnectionMgrImpl.c                   | 197 ++++++++++++++++--
>  .../WifiConnectionMgrMisc.c                   |  13 ++
>  7 files changed, 370 insertions(+), 59 deletions(-)  create mode 100644
> NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> 
> diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> new file mode 100644
> index 0000000000..e36daceabf
> --- /dev/null
> +++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> @@ -0,0 +1,83 @@
> +/** @file
> +  WiFi profile sync protocol. Supports One Click Recovery or KVM OS
> +recovery
> +  boot flow over WiFi.
> +
> +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
> +#define WIFI_PROFILE_SYNC_PROTOCOL_H_
> +
> +#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
> +
> +//
> +//  WiFi Profile Sync Protocol GUID variable.
> +//
> +extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
> +
> +/**
> +  Used by the WiFi connection manager to get the WiFi profile that AMT
> +shared
> +  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile
> +data to
> +  the WiFi connection manager profile structure fo connection use.
> +
> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile
> structure
> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC
> MAC address
> +
> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned
> succefully
> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or
> enabled
> +  @retval EFI_NOT_FOUND             No profiles to returned
> +  @retval Others                    Error Occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_PROFILE_GET)(
> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
> +  );
> +
> +/**
> +  Saves the WiFi connection status recieved by the
> +WiFiConnectionManager when
> +  in a KVM OR One Click Recovery WLAN recovery flow. Input as
> +  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and
> stored as EFI_STATUS type.
> +
> +  @param[in] ConnectionStatus     WiFi connection attempt results
> +**/
> +typedef
> +VOID
> +(EFIAPI *WIFI_SET_CONNECT_STATE)(
> +  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
> +  );
> +
> +/**
> +  Retrieves the stored WiFi connection status when in either KVM OR One
> +Click
> +  Recovery WLAN recovery flow.
> +
> +  @retval EFI_SUCCESS               WiFi connection completed succesfully
> +  @retval Others                    Connection failure occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_GET_CONNECT_STATE)(
> +  VOID
> +  );
> +
> +//
> +//  WiFi Profile Sync Protocol structure.
> +//
> +typedef struct {
> +  UINT32                    Revision;
> +  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;
> +  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;
> +  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;
> +} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
> +
> +/**
> +  WiFi Profile Protocol revision number.
> +
> +  Revision 1:   Initial version
> +**/
> +#define EFI_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
> +
> +#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
> diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
> index 5e43ebf8c5..53fb34c4a0 100644
> --- a/NetworkPkg/NetworkPkg.dec
> +++ b/NetworkPkg/NetworkPkg.dec
> @@ -91,6 +91,9 @@
>    ## Include/Protocol/HttpCallback.h
>    gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4,
> 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
> 
> +  ## Include/Protocol/WiFiProfileSyncProtocol.h
> +  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a,
> + 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
> +
>  [PcdsFixedAtBuild]
>    ## The max attempt number will be created by iSCSI driver.
>    # @Prompt Max attempt number.
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> index 4394b6f4bb..7e36016cf8 100644
> ---
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> +++
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> @@ -9,7 +9,7 @@
>  #  2). WPA2 Personal Network
>  #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
> # -#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2019 - 2022, Intel Corporation. All rights
> +reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -71,6 +71,7 @@
>    gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
>    gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
>    gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
> +  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
> 
>  [Guids]
>    gWifiConfigGuid                               ## PRODUCES  ## GUID
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> index 67a01ca058..65df5b2c8a 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> @@ -1,7 +1,7 @@
>  /** @file
>    The driver binding protocol for the WiFi Connection Manager.
> 
> -  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2019 - 2022, Intel Corporation. All rights
> + reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid =
> WIFI_CONFIG_NETWORK_LIST_REFRESH_G
>  EFI_GUID  mWifiConfigConnectFormRefreshGuid =
> WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
>  EFI_GUID  mWifiConfigMainFormRefreshGuid    =
> WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
> 
> +//
> +// Wifi connection attempt counter for retries // extern UINT8
> +WifiConnectionCount;
> +
>  /**
>    Tests to see if this driver supports a given controller. If a child device is
> provided,
>    it further tests to see if this driver supports creating a handle for the
> specified child device.
> @@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
>    EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
>    EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
>    EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;
> 
> -  Nic = NULL;
> +  WifiConnectionCount = 0;
> +  Nic                 = NULL;
> 
>    //
>    // Open Protocols
> @@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
>    InitializeListHead (&Nic->ProfileList);
> 
>    //
> -  // Record the MAC address of the incoming NIC.
> +  // WiFi profile sync protocol installation check for OS recovery flow.
>    //
> -  Status = NetLibGetMacAddress (
> -             ControllerHandle,
> -             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> -             &AddressSize
> -             );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> -
> -  //
> -  // Create and start the timer for the status check
> -  //
> -  Status = gBS->CreateEvent (
> -                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
> -                  TPL_CALLBACK,
> -                  WifiMgrOnTimerTick,
> -                  Nic,
> -                  &Nic->TickTimer
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
>                    );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> +  if (!EFI_ERROR (Status)) {
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ERROR1;
> +    }
> 
> -  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR3;
> -  }
> +    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);
> +    if (Nic->ConnectPendingNetwork != NULL) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
> +      if (EFI_ERROR (Status)) {
> +        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
> +      }
> +    } else {
> +      goto ERROR1;
> +    }
> +  } else {
> +    //
> +    // Record the MAC address of the incoming NIC.
> +    //
> +    Status = NetLibGetMacAddress (
> +               ControllerHandle,
> +               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> +               &AddressSize
> +               );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  Nic->ConnectState = WifiMgrDisconnected;
> -  Nic->ScanState    = WifiMgrScanFinished;
> +    //
> +    // Create and start the timer for the status check
> +    //
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
> +                    TPL_CALLBACK,
> +                    WifiMgrOnTimerTick,
> +                    Nic,
> +                    &Nic->TickTimer
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> -  InsertTailList (&mPrivate->NicList, &Nic->Link);
> -  Nic->NicIndex = mPrivate->NicCount++;
> -  if (mPrivate->CurrentNic == NULL) {
> -    mPrivate->CurrentNic = Nic;
> -  }
> +    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR3;
> +    }
> 
> -  gBS->RestoreTPL (OldTpl);
> +    Nic->ConnectState = WifiMgrDisconnected;
> +    Nic->ScanState    = WifiMgrScanFinished;
> +
> +    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +    InsertTailList (&mPrivate->NicList, &Nic->Link);
> +    Nic->NicIndex = mPrivate->NicCount++;
> +    if (mPrivate->CurrentNic == NULL) {
> +      mPrivate->CurrentNic = Nic;
> +    }
> +
> +    gBS->RestoreTPL (OldTpl);
> +  }
> 
>    Status = gBS->InstallProtocolInterface (
>                    &ControllerHandle,
> @@ -385,10 +418,11 @@ WifiMgrDxeDriverBindingStop (
>    IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
>    )
>  {
> -  EFI_STATUS                 Status;
> -  EFI_TPL                    OldTpl;
> -  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
> -  WIFI_MGR_DEVICE_DATA       *Nic;
> +  EFI_STATUS                      Status;
> +  EFI_TPL                         OldTpl;
> +  WIFI_MGR_PRIVATE_PROTOCOL       *WifiMgrIdentifier;
> +  WIFI_MGR_DEVICE_DATA            *Nic;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    Status = gBS->OpenProtocol (
>                    ControllerHandle,
> @@ -481,7 +515,15 @@ WifiMgrDxeDriverBindingStop (
>    //
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> -  RemoveEntryList (&Nic->Link);
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    RemoveEntryList (&Nic->Link);
> +  }
> +
>    mPrivate->NicCount--;
>    if (mPrivate->CurrentNic == Nic) {
>      mPrivate->CurrentNic = NULL;
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> index 7b2e41e155..047f85dbc2 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> @@ -47,6 +47,7 @@
>  #include <Protocol/SimpleNetwork.h>
>  #include <Protocol/SimpleFileSystem.h>
>  #include <Protocol/EapConfiguration.h>
> +#include <Protocol/WiFiProfileSyncProtocol.h>
> 
>  //
>  // Produced Protocols
> @@ -73,7 +74,8 @@
>  //
>  #define WIFI_MGR_DXE_VERSION  0xb
> 
> -#define OUI_IEEE_80211I  0xAC0F00
> +#define OUI_IEEE_80211I              0xAC0F00
> +#define MAX_WIFI_CONNETION_ATTEMPTS  3
> 
>  typedef enum {
>    Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0, diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> index 59bac48c42..3a04b4ddb1 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> @@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
>    EFI_EAP_TYPE_MSCHAPV2
>  };
> 
> +UINT8  WifiConnectionCount = 0;
> +
>  /**
>    The callback function for scan operation. This function updates networks
>    according to the latest scan result, and trigger UI refresh.
> @@ -420,22 +422,34 @@ WifiMgrConfigPassword (
>    //
>    // Set password to supplicant
>    //
> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
> +
>    if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {
>      return EFI_NOT_FOUND;
>    }
> 
> -  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof
> (UINT8));
> +  if (StrLen (Profile->Password) > PASSWORD_STORAGE_SIZE) {
> +    ASSERT (EFI_INVALID_PARAMETER);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) *
> + sizeof (CHAR8));
>    if (AsciiPassword == NULL) {
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword,
> PASSWORD_STORAGE_SIZE);
> -  Status = Supplicant->SetData (
> -                         Supplicant,
> -                         EfiSupplicant80211PskPassword,
> -                         AsciiPassword,
> -                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
> -                         );
> +  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8
> + *)AsciiPassword, ((StrLen (Profile->Password) + 1) * sizeof (CHAR8)));  if
> (!EFI_ERROR (Status)) {
> +    Status = Supplicant->SetData (
> +                           Supplicant,
> +                           EfiSupplicant80211PskPassword,
> +                           AsciiPassword,
> +                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
> +                           );
> +  }
> +
>    ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
>    FreePool (AsciiPassword);
> 
> @@ -466,6 +480,7 @@ WifiMgrConfigEap (
>    )
>  {
>    EFI_STATUS                      Status;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
>    EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
>    EFI_EAP_TYPE                    EapAuthMethod;
>    EFI_EAP_TYPE                    EapSecondAuthMethod;
> @@ -567,7 +582,13 @@ WifiMgrConfigEap (
>        return EFI_OUT_OF_RESOURCES;
>      }
> 
> -    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> (VOID **)&WiFiProfileSyncProtocol);
> +    if (!EFI_ERROR (Status)) {
> +      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
> +    } else {
> +      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    }
> +
>      Status = EapConfig->SetData (
>                            EapConfig,
>                            EFI_EAP_TYPE_IDENTITY, @@ -892,6 +913,133 @@
> WifiMgrPrepareConnection (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Will reset NiC data, get profile from profile sync driver, and send
> +for
> +  another connection attempt.This function should not be called more
> +than
> +  3 times.
> +
> +  @param[in]  WiFiProfileSyncProtocol  The target network profile to
> connect.
> +
> +  @retval EFI_SUCCESS                  The operation is completed.
> +  @retval other                        Operation failure.
> +
> +**/
> +EFI_STATUS
> +ConnectionRetry (
> +  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
> +  )
> +{
> +  EFI_STATUS                               Status;
> +  WIFI_MGR_DEVICE_DATA                     *Nic;
> +  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
> +  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
> +  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +
> +  Nic = NULL;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFi2ProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Wmp
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSupplicantProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Supplicant
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Supplicant = NULL;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiEapConfigurationProtocolGuid,
> +                  NULL,
> +                  (VOID **)&EapConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    EapConfig = NULL;
> +  }
> +
> +  //
> +  // Initialize Nic device data
> +  //
> +  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));  if (Nic ==
> + NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    return Status;
> +  }
> +
> +  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
> +  Nic->Private             = mPrivate;
> +  Nic->Wmp                 = Wmp;
> +  Nic->Supplicant          = Supplicant;
> +  Nic->EapConfig           = EapConfig;
> +  Nic->UserSelectedProfile = NULL;
> +  Nic->OneTimeScanRequest  = FALSE;
> +
> +  if (Nic->Supplicant != NULL) {
> +    Status = WifiMgrGetSupportedSuites (Nic);  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    InitializeListHead (&Nic->ProfileList);
> +
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate
> memory for ConnectPendingNetwork\n"));
> +      goto ERROR;
> +    }
> +
> +    Status = WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);
> +    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
> +      if (!EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi
> profile with status %r\n", Status));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get
> + Supported suites with status %r\n", Status));  }
> +
> +  if (Nic->ConnectPendingNetwork != NULL) {
> +    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
> +    }
> +
> +    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
> +    }
> +
> +    FreePool (Nic->ConnectPendingNetwork);  }
> +
> +ERROR:
> +  if (Nic->Supplicant != NULL) {
> +    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
> +    }
> +  }
> +
> +  FreePool (Nic);
> +
> +  return Status;
> +}
> +
>  /**
>    The callback function for connect operation.
> 
> @@ -908,12 +1056,13 @@ WifiMgrOnConnectFinished (
>    IN  VOID       *Context
>    )
>  {
> -  EFI_STATUS                 Status;
> -  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
> -  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
> -  UINT8                      SecurityType;
> -  UINT8                      SSIdLen;
> -  CHAR8                      *AsciiSSId;
> +  EFI_STATUS                      Status;
> +  WIFI_MGR_MAC_CONFIG_TOKEN       *ConfigToken;
> +  WIFI_MGR_NETWORK_PROFILE        *ConnectedProfile;
> +  UINT8                           SecurityType;
> +  UINT8                           SSIdLen;
> +  CHAR8                           *AsciiSSId;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    ASSERT (Context != NULL);
> 
> @@ -925,6 +1074,24 @@ WifiMgrOnConnectFinished (
>    ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
> 
>    ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
> +
> +  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> + (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
> +    WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (ConfigToken-
> >Token.ConnectNetworkToken->ResultCode);
> +    if ((WifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
> +        (ConfigToken->Token.ConnectNetworkToken->ResultCode !=
> ConnectSuccess))
> +    {
> +      WifiConnectionCount++;
> +      gBS->CloseEvent (Event);
> +      Status = ConnectionRetry (WiFiProfileSyncProtocol);
> +      if (!EFI_ERROR (Status)) {
> +        return;
> +      }
> +
> +      WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
> +    }
> +  }
> +
>    if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
>      if (ConfigToken->Nic->OneTimeConnectRequest) {
>        //
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> index 4ad5643c24..87adfc5033 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> @@ -672,10 +672,23 @@ WifiMgrCleanProfileSecrets (
>    IN  WIFI_MGR_NETWORK_PROFILE  *Profile
>    )
>  {
> +  EFI_STATUS                      Status;
> +  EFI_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 (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> + (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
> +    return;
> +  }
> +
>    if (Profile->CACertData != NULL) {
>      ZeroMem (Profile->CACertData, Profile->CACertSize);
>      FreePool (Profile->CACertData);
> --
> 2.26.2.windows.1
> 
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2022-09-26  7:37 ` [edk2-devel] " Heng Luo
@ 2022-09-26 15:39   ` Clark-williams, Zachary
  2022-09-26 16:27     ` Michael Brown
  0 siblings, 1 reply; 11+ messages in thread
From: Clark-williams, Zachary @ 2022-09-26 15:39 UTC (permalink / raw)
  To: Luo, Heng, devel@edk2.groups.io; +Cc: Zachary Clark-Williams, Maciej Rabeda

Yes this is checking if the users entered password had a terminator on the end, if it doesn't we are adding it. 
During dev and testing we found a failure case if this was not tested and fixed.

Thanks,
Zack

-----Original Message-----
From: Luo, Heng <heng.luo@intel.com> 
Sent: Monday, September 26, 2022 12:37 AM
To: devel@edk2.groups.io; Clark-williams, Zachary <zachary.clark-williams@intel.com>
Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Maciej Rabeda <maciej.rabeda@linux.intel.com>
Subject: RE: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support

Hi Zachary,
> @@ -420,22 +422,34 @@ WifiMgrConfigPassword (
>    //
>    // Set password to supplicant
>    //
> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
> +
I don't understand this change, StrLen returns the length of a Null-terminated Unicode string, it means "Profile->Password[StrLen (Profile->Password)]" should always be 0. Did you see exceptional case?

Thanks,
Heng

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Clark- 
> williams, Zachary
> Sent: Thursday, September 15, 2022 3:43 AM
> To: devel@edk2.groups.io
> Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Clark-williams, 
> Zachary <zachary.clark-williams@intel.com>
> Subject: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync 
> protocol support
> 
> From: Zachary Clark-Williams <zclarkw112@gmail.com>
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845
> 
> Enables KVM and One Click Recovery WLAN capability with WiFi Profile 
> Sync feature and protocol. Adding WiFiProfileSyncProtocol, which 
> supports the profilesync driver operations for transferring WiFi 
> profiles from AMT to the Supplicant. WiFiConnectionManager will check 
> for the WifiProfileSyncProtocol and if found will operate on the 
> premise of a One Click Recovery, or KVM flow with a Wifi profile provided by AMT.
> 
> Signed-off-by: Zachary Clark-Williams 
> <zachary.clark-williams@intel.com>
> ---
>  .../Protocol/WiFiProfileSyncProtocol.h        |  83 ++++++++
>  NetworkPkg/NetworkPkg.dec                     |   3 +
>  .../WifiConnectionManagerDxe.inf              |   3 +-
>  .../WifiConnectionMgrDriver.c                 | 126 +++++++----
>  .../WifiConnectionMgrDxe.h                    |   4 +-
>  .../WifiConnectionMgrImpl.c                   | 197 ++++++++++++++++--
>  .../WifiConnectionMgrMisc.c                   |  13 ++
>  7 files changed, 370 insertions(+), 59 deletions(-)  create mode 
> 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> 
> diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> new file mode 100644
> index 0000000000..e36daceabf
> --- /dev/null
> +++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> @@ -0,0 +1,83 @@
> +/** @file
> +  WiFi profile sync protocol. Supports One Click Recovery or KVM OS 
> +recovery
> +  boot flow over WiFi.
> +
> +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_ #define 
> +WIFI_PROFILE_SYNC_PROTOCOL_H_
> +
> +#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
> +
> +//
> +//  WiFi Profile Sync Protocol GUID variable.
> +//
> +extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
> +
> +/**
> +  Used by the WiFi connection manager to get the WiFi profile that 
> +AMT shared
> +  and was stored in WiFi profile protocol. Aligns the AMT WiFi 
> +profile data to
> +  the WiFi connection manager profile structure fo connection use.
> +
> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile
> structure
> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC
> MAC address
> +
> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned
> succefully
> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or
> enabled
> +  @retval EFI_NOT_FOUND             No profiles to returned
> +  @retval Others                    Error Occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_PROFILE_GET)(
> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
> +  );
> +
> +/**
> +  Saves the WiFi connection status recieved by the 
> +WiFiConnectionManager when
> +  in a KVM OR One Click Recovery WLAN recovery flow. Input as
> +  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and
> stored as EFI_STATUS type.
> +
> +  @param[in] ConnectionStatus     WiFi connection attempt results
> +**/
> +typedef
> +VOID
> +(EFIAPI *WIFI_SET_CONNECT_STATE)(
> +  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
> +  );
> +
> +/**
> +  Retrieves the stored WiFi connection status when in either KVM OR 
> +One Click
> +  Recovery WLAN recovery flow.
> +
> +  @retval EFI_SUCCESS               WiFi connection completed succesfully
> +  @retval Others                    Connection failure occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_GET_CONNECT_STATE)(
> +  VOID
> +  );
> +
> +//
> +//  WiFi Profile Sync Protocol structure.
> +//
> +typedef struct {
> +  UINT32                    Revision;
> +  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;
> +  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;
> +  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;
> +} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
> +
> +/**
> +  WiFi Profile Protocol revision number.
> +
> +  Revision 1:   Initial version
> +**/
> +#define EFI_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
> +
> +#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
> diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec 
> index 5e43ebf8c5..53fb34c4a0 100644
> --- a/NetworkPkg/NetworkPkg.dec
> +++ b/NetworkPkg/NetworkPkg.dec
> @@ -91,6 +91,9 @@
>    ## Include/Protocol/HttpCallback.h
>    gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, 
> {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
> 
> +  ## Include/Protocol/WiFiProfileSyncProtocol.h
> +  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, 
> + {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
> +
>  [PcdsFixedAtBuild]
>    ## The max attempt number will be created by iSCSI driver.
>    # @Prompt Max attempt number.
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> index 4394b6f4bb..7e36016cf8 100644
> ---
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> +++
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> @@ -9,7 +9,7 @@
>  #  2). WPA2 Personal Network
>  #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2) 
> # -#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2019 - 2022, Intel Corporation. All rights 
> +reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -71,6 +71,7 @@
>    gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
>    gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
>    gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
> +  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
> 
>  [Guids]
>    gWifiConfigGuid                               ## PRODUCES  ## GUID
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> index 67a01ca058..65df5b2c8a 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> @@ -1,7 +1,7 @@
>  /** @file
>    The driver binding protocol for the WiFi Connection Manager.
> 
> -  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2019 - 2022, Intel Corporation. All rights 
> + reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid = 
> WIFI_CONFIG_NETWORK_LIST_REFRESH_G
>  EFI_GUID  mWifiConfigConnectFormRefreshGuid = 
> WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
>  EFI_GUID  mWifiConfigMainFormRefreshGuid    =
> WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
> 
> +//
> +// Wifi connection attempt counter for retries // extern UINT8 
> +WifiConnectionCount;
> +
>  /**
>    Tests to see if this driver supports a given controller. If a child 
> device is provided,
>    it further tests to see if this driver supports creating a handle 
> for the specified child device.
> @@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
>    EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
>    EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
>    EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;
> 
> -  Nic = NULL;
> +  WifiConnectionCount = 0;
> +  Nic                 = NULL;
> 
>    //
>    // Open Protocols
> @@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
>    InitializeListHead (&Nic->ProfileList);
> 
>    //
> -  // Record the MAC address of the incoming NIC.
> +  // WiFi profile sync protocol installation check for OS recovery flow.
>    //
> -  Status = NetLibGetMacAddress (
> -             ControllerHandle,
> -             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> -             &AddressSize
> -             );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> -
> -  //
> -  // Create and start the timer for the status check
> -  //
> -  Status = gBS->CreateEvent (
> -                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
> -                  TPL_CALLBACK,
> -                  WifiMgrOnTimerTick,
> -                  Nic,
> -                  &Nic->TickTimer
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
>                    );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> +  if (!EFI_ERROR (Status)) {
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ERROR1;
> +    }
> 
> -  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, 
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR3;
> -  }
> +    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);
> +    if (Nic->ConnectPendingNetwork != NULL) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
> +      if (EFI_ERROR (Status)) {
> +        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
> +      }
> +    } else {
> +      goto ERROR1;
> +    }
> +  } else {
> +    //
> +    // Record the MAC address of the incoming NIC.
> +    //
> +    Status = NetLibGetMacAddress (
> +               ControllerHandle,
> +               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> +               &AddressSize
> +               );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  Nic->ConnectState = WifiMgrDisconnected;
> -  Nic->ScanState    = WifiMgrScanFinished;
> +    //
> +    // Create and start the timer for the status check
> +    //
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
> +                    TPL_CALLBACK,
> +                    WifiMgrOnTimerTick,
> +                    Nic,
> +                    &Nic->TickTimer
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> -  InsertTailList (&mPrivate->NicList, &Nic->Link);
> -  Nic->NicIndex = mPrivate->NicCount++;
> -  if (mPrivate->CurrentNic == NULL) {
> -    mPrivate->CurrentNic = Nic;
> -  }
> +    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR3;
> +    }
> 
> -  gBS->RestoreTPL (OldTpl);
> +    Nic->ConnectState = WifiMgrDisconnected;
> +    Nic->ScanState    = WifiMgrScanFinished;
> +
> +    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +    InsertTailList (&mPrivate->NicList, &Nic->Link);
> +    Nic->NicIndex = mPrivate->NicCount++;
> +    if (mPrivate->CurrentNic == NULL) {
> +      mPrivate->CurrentNic = Nic;
> +    }
> +
> +    gBS->RestoreTPL (OldTpl);
> +  }
> 
>    Status = gBS->InstallProtocolInterface (
>                    &ControllerHandle,
> @@ -385,10 +418,11 @@ WifiMgrDxeDriverBindingStop (
>    IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
>    )
>  {
> -  EFI_STATUS                 Status;
> -  EFI_TPL                    OldTpl;
> -  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
> -  WIFI_MGR_DEVICE_DATA       *Nic;
> +  EFI_STATUS                      Status;
> +  EFI_TPL                         OldTpl;
> +  WIFI_MGR_PRIVATE_PROTOCOL       *WifiMgrIdentifier;
> +  WIFI_MGR_DEVICE_DATA            *Nic;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    Status = gBS->OpenProtocol (
>                    ControllerHandle,
> @@ -481,7 +515,15 @@ WifiMgrDxeDriverBindingStop (
>    //
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> -  RemoveEntryList (&Nic->Link);
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    RemoveEntryList (&Nic->Link);
> +  }
> +
>    mPrivate->NicCount--;
>    if (mPrivate->CurrentNic == Nic) {
>      mPrivate->CurrentNic = NULL;
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> index 7b2e41e155..047f85dbc2 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> @@ -47,6 +47,7 @@
>  #include <Protocol/SimpleNetwork.h>
>  #include <Protocol/SimpleFileSystem.h>  #include 
> <Protocol/EapConfiguration.h>
> +#include <Protocol/WiFiProfileSyncProtocol.h>
> 
>  //
>  // Produced Protocols
> @@ -73,7 +74,8 @@
>  //
>  #define WIFI_MGR_DXE_VERSION  0xb
> 
> -#define OUI_IEEE_80211I  0xAC0F00
> +#define OUI_IEEE_80211I              0xAC0F00
> +#define MAX_WIFI_CONNETION_ATTEMPTS  3
> 
>  typedef enum {
>    Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0, diff --git 
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> index 59bac48c42..3a04b4ddb1 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> @@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
>    EFI_EAP_TYPE_MSCHAPV2
>  };
> 
> +UINT8  WifiConnectionCount = 0;
> +
>  /**
>    The callback function for scan operation. This function updates networks
>    according to the latest scan result, and trigger UI refresh.
> @@ -420,22 +422,34 @@ WifiMgrConfigPassword (
>    //
>    // Set password to supplicant
>    //
> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
> +
>    if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {
>      return EFI_NOT_FOUND;
>    }
> 
> -  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) 
> * sizeof (UINT8));
> +  if (StrLen (Profile->Password) > PASSWORD_STORAGE_SIZE) {
> +    ASSERT (EFI_INVALID_PARAMETER);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) 
> + * sizeof (CHAR8));
>    if (AsciiPassword == NULL) {
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, 
> PASSWORD_STORAGE_SIZE);
> -  Status = Supplicant->SetData (
> -                         Supplicant,
> -                         EfiSupplicant80211PskPassword,
> -                         AsciiPassword,
> -                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
> -                         );
> +  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 
> + *)AsciiPassword, ((StrLen (Profile->Password) + 1) * sizeof 
> + (CHAR8)));  if
> (!EFI_ERROR (Status)) {
> +    Status = Supplicant->SetData (
> +                           Supplicant,
> +                           EfiSupplicant80211PskPassword,
> +                           AsciiPassword,
> +                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
> +                           );
> +  }
> +
>    ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
>    FreePool (AsciiPassword);
> 
> @@ -466,6 +480,7 @@ WifiMgrConfigEap (
>    )
>  {
>    EFI_STATUS                      Status;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
>    EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
>    EFI_EAP_TYPE                    EapAuthMethod;
>    EFI_EAP_TYPE                    EapSecondAuthMethod;
> @@ -567,7 +582,13 @@ WifiMgrConfigEap (
>        return EFI_OUT_OF_RESOURCES;
>      }
> 
> -    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, 
> + NULL,
> (VOID **)&WiFiProfileSyncProtocol);
> +    if (!EFI_ERROR (Status)) {
> +      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
> +    } else {
> +      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    }
> +
>      Status = EapConfig->SetData (
>                            EapConfig,
>                            EFI_EAP_TYPE_IDENTITY, @@ -892,6 +913,133 
> @@ WifiMgrPrepareConnection (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Will reset NiC data, get profile from profile sync driver, and send 
> +for
> +  another connection attempt.This function should not be called more 
> +than
> +  3 times.
> +
> +  @param[in]  WiFiProfileSyncProtocol  The target network profile to
> connect.
> +
> +  @retval EFI_SUCCESS                  The operation is completed.
> +  @retval other                        Operation failure.
> +
> +**/
> +EFI_STATUS
> +ConnectionRetry (
> +  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
> +  )
> +{
> +  EFI_STATUS                               Status;
> +  WIFI_MGR_DEVICE_DATA                     *Nic;
> +  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
> +  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
> +  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +
> +  Nic = NULL;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFi2ProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Wmp
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSupplicantProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Supplicant
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Supplicant = NULL;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiEapConfigurationProtocolGuid,
> +                  NULL,
> +                  (VOID **)&EapConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    EapConfig = NULL;
> +  }
> +
> +  //
> +  // Initialize Nic device data
> +  //
> +  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));  if (Nic ==
> + NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    return Status;
> +  }
> +
> +  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
> +  Nic->Private             = mPrivate;
> +  Nic->Wmp                 = Wmp;
> +  Nic->Supplicant          = Supplicant;
> +  Nic->EapConfig           = EapConfig;
> +  Nic->UserSelectedProfile = NULL;
> +  Nic->OneTimeScanRequest  = FALSE;
> +
> +  if (Nic->Supplicant != NULL) {
> +    Status = WifiMgrGetSupportedSuites (Nic);  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    InitializeListHead (&Nic->ProfileList);
> +
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to 
> + allocate
> memory for ConnectPendingNetwork\n"));
> +      goto ERROR;
> +    }
> +
> +    Status = WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);
> +    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
> +      if (!EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get 
> + WiFi
> profile with status %r\n", Status));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get 
> + Supported suites with status %r\n", Status));  }
> +
> +  if (Nic->ConnectPendingNetwork != NULL) {
> +    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
> +    }
> +
> +    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
> +    }
> +
> +    FreePool (Nic->ConnectPendingNetwork);  }
> +
> +ERROR:
> +  if (Nic->Supplicant != NULL) {
> +    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
> +    }
> +  }
> +
> +  FreePool (Nic);
> +
> +  return Status;
> +}
> +
>  /**
>    The callback function for connect operation.
> 
> @@ -908,12 +1056,13 @@ WifiMgrOnConnectFinished (
>    IN  VOID       *Context
>    )
>  {
> -  EFI_STATUS                 Status;
> -  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
> -  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
> -  UINT8                      SecurityType;
> -  UINT8                      SSIdLen;
> -  CHAR8                      *AsciiSSId;
> +  EFI_STATUS                      Status;
> +  WIFI_MGR_MAC_CONFIG_TOKEN       *ConfigToken;
> +  WIFI_MGR_NETWORK_PROFILE        *ConnectedProfile;
> +  UINT8                           SecurityType;
> +  UINT8                           SSIdLen;
> +  CHAR8                           *AsciiSSId;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    ASSERT (Context != NULL);
> 
> @@ -925,6 +1074,24 @@ WifiMgrOnConnectFinished (
>    ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
> 
>    ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
> +
> +  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, 
> + NULL, (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
> +    WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState 
> + (ConfigToken-
> >Token.ConnectNetworkToken->ResultCode);
> +    if ((WifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
> +        (ConfigToken->Token.ConnectNetworkToken->ResultCode !=
> ConnectSuccess))
> +    {
> +      WifiConnectionCount++;
> +      gBS->CloseEvent (Event);
> +      Status = ConnectionRetry (WiFiProfileSyncProtocol);
> +      if (!EFI_ERROR (Status)) {
> +        return;
> +      }
> +
> +      WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
> +    }
> +  }
> +
>    if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
>      if (ConfigToken->Nic->OneTimeConnectRequest) {
>        //
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> index 4ad5643c24..87adfc5033 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> @@ -672,10 +672,23 @@ WifiMgrCleanProfileSecrets (
>    IN  WIFI_MGR_NETWORK_PROFILE  *Profile
>    )
>  {
> +  EFI_STATUS                      Status;
> +  EFI_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 (&gEfiWiFiProfileSyncProtocolGuid, 
> + NULL, (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
> +    return;
> +  }
> +
>    if (Profile->CACertData != NULL) {
>      ZeroMem (Profile->CACertData, Profile->CACertSize);
>      FreePool (Profile->CACertData);
> --
> 2.26.2.windows.1
> 
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2022-09-26 15:39   ` Clark-williams, Zachary
@ 2022-09-26 16:27     ` Michael Brown
  2022-09-26 17:39       ` Clark-williams, Zachary
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Brown @ 2022-09-26 16:27 UTC (permalink / raw)
  To: devel, zachary.clark-williams, Luo, Heng
  Cc: Zachary Clark-Williams, Maciej Rabeda

On 26/09/2022 16:39, Clark-williams, Zachary wrote:
>>> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
>>> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
>>> +
>> I don't understand this change, StrLen returns the length of a Null-terminated Unicode string, it means "Profile->Password[StrLen (Profile->Password)]" should always be 0. Did you see exceptional case?
> Yes this is checking if the users entered password had a terminator on the end, if it doesn't we are adding it.
> During dev and testing we found a failure case if this was not tested and fixed.

No.  StrLen() works by scanning the string until it finds a L'\0' 
terminator.  Your code is provably wrong.

I would suggest that you retest, and find the mistake in your testing 
process.

Michael

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2022-09-26 16:27     ` Michael Brown
@ 2022-09-26 17:39       ` Clark-williams, Zachary
  0 siblings, 0 replies; 11+ messages in thread
From: Clark-williams, Zachary @ 2022-09-26 17:39 UTC (permalink / raw)
  To: Michael Brown, devel@edk2.groups.io, Luo, Heng
  Cc: Zachary Clark-Williams, Maciej Rabeda

After reviewing the code that provides the password from AMT to the connection manager, in a later revision after this line was added, the password is assigned a null terminator in its conversion.
Meaning, these lines are no longer necessary. 

I  will update the patch and resend for submission.

Please feel free to review the rest of this patch in the mean time and provide feedback of any other misalignments to be changed.

Thanks,
Zack

-----Original Message-----
From: Michael Brown <mcb30@ipxe.org> 
Sent: Monday, September 26, 2022 9:27 AM
To: devel@edk2.groups.io; Clark-williams, Zachary <zachary.clark-williams@intel.com>; Luo, Heng <heng.luo@intel.com>
Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Maciej Rabeda <maciej.rabeda@linux.intel.com>
Subject: Re: [edk2-devel] [PATCH] NetworkPkg: Add WiFi profile sync protocol support

On 26/09/2022 16:39, Clark-williams, Zachary wrote:
>>> +  if (Profile->Password[StrLen (Profile->Password)] != '\0') {
>>> +    Profile->Password[StrLen (Profile->Password)] = L'\0';  }
>>> +
>> I don't understand this change, StrLen returns the length of a Null-terminated Unicode string, it means "Profile->Password[StrLen (Profile->Password)]" should always be 0. Did you see exceptional case?
> Yes this is checking if the users entered password had a terminator on the end, if it doesn't we are adding it.
> During dev and testing we found a failure case if this was not tested and fixed.

No.  StrLen() works by scanning the string until it finds a L'\0' 
terminator.  Your code is provably wrong.

I would suggest that you retest, and find the mistake in your testing process.

Michael

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] NetworkPkg: Add WiFi profile sync protocol support
@ 2022-11-14 18:11 Clark-williams, Zachary
  2023-01-06  5:09 ` Wu, Jiaxin
  0 siblings, 1 reply; 11+ messages in thread
From: Clark-williams, Zachary @ 2022-11-14 18:11 UTC (permalink / raw)
  To: devel
  Cc: Zachary Clark-Williams, Maciej Rabeda, Wu Jiaxin,
	Andrei Otcheretianski, Zachary Clark-Williams

From: Zachary Clark-Williams <zclarkw112@gmail.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845

Enables KVM and One Click Recovery WLAN capability with WiFi Profile
Sync feature and protocol. Adding WiFiProfileSyncProtocol, which
supports the profilesync driver operations for transferring WiFi profiles
from AMT to the Supplicant. WiFiConnectionManager will check for the
WifiProfileSyncProtocol and if found will operate on the premise of a
One Click Recovery, or KVM flow with a Wifi profile provided by AMT.

Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
---
 .../Protocol/WiFiProfileSyncProtocol.h        |  86 ++++++++
 NetworkPkg/NetworkPkg.dec                     |   3 +
 .../WifiConnectionManagerDxe.inf              |   3 +-
 .../WifiConnectionMgrConfigNVDataStruct.h     |   2 +-
 .../WifiConnectionMgrDriver.c                 | 126 ++++++++----
 .../WifiConnectionMgrDxe.h                    |   4 +-
 .../WifiConnectionMgrImpl.c                   | 193 ++++++++++++++++--
 .../WifiConnectionMgrMisc.c                   |  13 ++
 8 files changed, 370 insertions(+), 60 deletions(-)
 create mode 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h

diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
new file mode 100644
index 0000000000..bc8f58784e
--- /dev/null
+++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
@@ -0,0 +1,86 @@
+/** @file
+  WiFi profile sync protocol. Supports One Click Recovery or KVM OS recovery
+  boot flow over WiFi.
+
+  Pulbic links to speficiation document for KVM and One Click Recovery feature.
+  https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Foneclickrecovery.htm
+
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
+#define WIFI_PROFILE_SYNC_PROTOCOL_H_
+
+#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
+
+//
+//  WiFi Profile Sync Protocol GUID variable.
+//
+extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
+
+/**
+  Used by the WiFi connection manager to get the WiFi profile that AMT shared
+  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
+  the WiFi connection manager profile structure fo connection use.
+
+  @param[in, out]  WcmProfile       WiFi Connection Manager profile structure
+  @param[in, out]  MacAddress       MAC address from AMT saved to NiC MAC address
+
+  @retval EFI_SUCCESS               Stored WiFi profile converted and returned succefully
+  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or enabled
+  @retval EFI_NOT_FOUND             No profiles to returned
+  @retval Others                    Error Occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_PROFILE_GET)(
+  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
+  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
+  );
+
+/**
+  Saves the WiFi connection status recieved by the WiFiConnectionManager when
+  in a KVM OR One Click Recovery WLAN recovery flow. Input as
+  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and stored as EFI_STATUS type.
+
+  @param[in] ConnectionStatus     WiFi connection attempt results
+**/
+typedef
+VOID
+(EFIAPI *WIFI_SET_CONNECT_STATE)(
+  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
+  );
+
+/**
+  Retrieves the stored WiFi connection status when in either KVM OR One Click
+  Recovery WLAN recovery flow.
+
+  @retval EFI_SUCCESS               WiFi connection completed succesfully
+  @retval Others                    Connection failure occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_GET_CONNECT_STATE)(
+  VOID
+  );
+
+//
+//  WiFi Profile Sync Protocol structure.
+//
+typedef struct {
+  UINT32                    Revision;
+  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;
+  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;
+  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;
+} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
+
+/**
+  WiFi Profile Protocol revision number.
+
+  Revision 1:   Initial version
+**/
+#define EFI_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
+
+#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 5e43ebf8c5..53fb34c4a0 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -91,6 +91,9 @@
   ## Include/Protocol/HttpCallback.h
   gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
 
+  ## Include/Protocol/WiFiProfileSyncProtocol.h
+  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
+
 [PcdsFixedAtBuild]
   ## The max attempt number will be created by iSCSI driver.
   # @Prompt Max attempt number.
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
index 4394b6f4bb..7e36016cf8 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
@@ -9,7 +9,7 @@
 #  2). WPA2 Personal Network
 #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
 #
-#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -71,6 +71,7 @@
   gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
   gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
 
 [Guids]
   gWifiConfigGuid                               ## PRODUCES  ## GUID
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
index b5518a74d8..dcc4bf7e27 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
@@ -25,7 +25,7 @@
 
 #define PASSWORD_MIN_LEN       8
 #define PASSWORD_MAX_LEN       63
-#define PASSWORD_STORAGE_SIZE  64
+#define PASSWORD_STORAGE_SIZE  65
 
 #define EAP_IDENTITY_LEN   63
 #define EAP_IDENTITY_SIZE  64
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
index 67a01ca058..97ca7a9f0b 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
@@ -1,7 +1,7 @@
 /** @file
   The driver binding protocol for the WiFi Connection Manager.
 
-  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_G
 EFI_GUID  mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
 EFI_GUID  mWifiConfigMainFormRefreshGuid    = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
 
+//
+// Wifi connection attempt counter for retries
+//
+extern UINT8  mWifiConnectionCount;
+
 /**
   Tests to see if this driver supports a given controller. If a child device is provided,
   it further tests to see if this driver supports creating a handle for the specified child device.
@@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
   EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
   EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
   EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;
 
-  Nic = NULL;
+  mWifiConnectionCount = 0;
+  Nic                  = NULL;
 
   //
   // Open Protocols
@@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
   InitializeListHead (&Nic->ProfileList);
 
   //
-  // Record the MAC address of the incoming NIC.
+  // WiFi profile sync protocol installation check for OS recovery flow.
   //
-  Status = NetLibGetMacAddress (
-             ControllerHandle,
-             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
-             &AddressSize
-             );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
-
-  //
-  // Create and start the timer for the status check
-  //
-  Status = gBS->CreateEvent (
-                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
-                  TPL_CALLBACK,
-                  WifiMgrOnTimerTick,
-                  Nic,
-                  &Nic->TickTimer
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
                   );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
+  if (!EFI_ERROR (Status)) {
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ERROR1;
+    }
 
-  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
-  if (EFI_ERROR (Status)) {
-    goto ERROR3;
-  }
+    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (Nic->ConnectPendingNetwork != NULL) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (EFI_ERROR (Status)) {
+        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+      }
+    } else {
+      goto ERROR1;
+    }
+  } else {
+    //
+    // Record the MAC address of the incoming NIC.
+    //
+    Status = NetLibGetMacAddress (
+               ControllerHandle,
+               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
+               &AddressSize
+               );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  Nic->ConnectState = WifiMgrDisconnected;
-  Nic->ScanState    = WifiMgrScanFinished;
+    //
+    // Create and start the timer for the status check
+    //
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
+                    TPL_CALLBACK,
+                    WifiMgrOnTimerTick,
+                    Nic,
+                    &Nic->TickTimer
+                    );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-  InsertTailList (&mPrivate->NicList, &Nic->Link);
-  Nic->NicIndex = mPrivate->NicCount++;
-  if (mPrivate->CurrentNic == NULL) {
-    mPrivate->CurrentNic = Nic;
-  }
+    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
+    if (EFI_ERROR (Status)) {
+      goto ERROR3;
+    }
 
-  gBS->RestoreTPL (OldTpl);
+    Nic->ConnectState = WifiMgrDisconnected;
+    Nic->ScanState    = WifiMgrScanFinished;
+
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+    InsertTailList (&mPrivate->NicList, &Nic->Link);
+    Nic->NicIndex = mPrivate->NicCount++;
+    if (mPrivate->CurrentNic == NULL) {
+      mPrivate->CurrentNic = Nic;
+    }
+
+    gBS->RestoreTPL (OldTpl);
+  }
 
   Status = gBS->InstallProtocolInterface (
                   &ControllerHandle,
@@ -385,10 +418,11 @@ WifiMgrDxeDriverBindingStop (
   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
   )
 {
-  EFI_STATUS                 Status;
-  EFI_TPL                    OldTpl;
-  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
-  WIFI_MGR_DEVICE_DATA       *Nic;
+  EFI_STATUS                      Status;
+  EFI_TPL                         OldTpl;
+  WIFI_MGR_PRIVATE_PROTOCOL       *WifiMgrIdentifier;
+  WIFI_MGR_DEVICE_DATA            *Nic;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   Status = gBS->OpenProtocol (
                   ControllerHandle,
@@ -481,7 +515,15 @@ WifiMgrDxeDriverBindingStop (
   //
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
-  RemoveEntryList (&Nic->Link);
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    RemoveEntryList (&Nic->Link);
+  }
+
   mPrivate->NicCount--;
   if (mPrivate->CurrentNic == Nic) {
     mPrivate->CurrentNic = NULL;
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
index 7b2e41e155..047f85dbc2 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
@@ -47,6 +47,7 @@
 #include <Protocol/SimpleNetwork.h>
 #include <Protocol/SimpleFileSystem.h>
 #include <Protocol/EapConfiguration.h>
+#include <Protocol/WiFiProfileSyncProtocol.h>
 
 //
 // Produced Protocols
@@ -73,7 +74,8 @@
 //
 #define WIFI_MGR_DXE_VERSION  0xb
 
-#define OUI_IEEE_80211I  0xAC0F00
+#define OUI_IEEE_80211I              0xAC0F00
+#define MAX_WIFI_CONNETION_ATTEMPTS  3
 
 typedef enum {
   Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0,
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
index 59bac48c42..a73ab9f710 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
@@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
   EFI_EAP_TYPE_MSCHAPV2
 };
 
+UINT8  mWifiConnectionCount = 0;
+
 /**
   The callback function for scan operation. This function updates networks
   according to the latest scan result, and trigger UI refresh.
@@ -424,18 +426,26 @@ WifiMgrConfigPassword (
     return EFI_NOT_FOUND;
   }
 
-  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
+  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
+    ASSERT (EFI_INVALID_PARAMETER);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));
   if (AsciiPassword == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
-  Status = Supplicant->SetData (
-                         Supplicant,
-                         EfiSupplicant80211PskPassword,
-                         AsciiPassword,
-                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
-                         );
+  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, (StrLen (Profile->Password) + 1));
+  if (!EFI_ERROR (Status)) {
+    Status = Supplicant->SetData (
+                           Supplicant,
+                           EfiSupplicant80211PskPassword,
+                           AsciiPassword,
+                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
+                           );
+  }
+
   ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
   FreePool (AsciiPassword);
 
@@ -466,6 +476,7 @@ WifiMgrConfigEap (
   )
 {
   EFI_STATUS                      Status;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
   EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
   EFI_EAP_TYPE                    EapAuthMethod;
   EFI_EAP_TYPE                    EapSecondAuthMethod;
@@ -567,7 +578,13 @@ WifiMgrConfigEap (
       return EFI_OUT_OF_RESOURCES;
     }
 
-    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+    if (!EFI_ERROR (Status)) {
+      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
+    } else {
+      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    }
+
     Status = EapConfig->SetData (
                           EapConfig,
                           EFI_EAP_TYPE_IDENTITY,
@@ -892,6 +909,133 @@ WifiMgrPrepareConnection (
   return EFI_SUCCESS;
 }
 
+/**
+  Will reset NiC data, get profile from profile sync driver, and send for
+  another connection attempt.This function should not be called more than
+  3 times.
+
+  @param[in]  WiFiProfileSyncProtocol  The target network profile to connect.
+
+  @retval EFI_SUCCESS                  The operation is completed.
+  @retval other                        Operation failure.
+
+**/
+EFI_STATUS
+ConnectionRetry (
+  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
+  )
+{
+  EFI_STATUS                               Status;
+  WIFI_MGR_DEVICE_DATA                     *Nic;
+  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
+  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
+  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+
+  Nic = NULL;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFi2ProtocolGuid,
+                  NULL,
+                  (VOID **)&Wmp
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSupplicantProtocolGuid,
+                  NULL,
+                  (VOID **)&Supplicant
+                  );
+  if (EFI_ERROR (Status)) {
+    Supplicant = NULL;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiEapConfigurationProtocolGuid,
+                  NULL,
+                  (VOID **)&EapConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    EapConfig = NULL;
+  }
+
+  //
+  // Initialize Nic device data
+  //
+  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
+  if (Nic == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    return Status;
+  }
+
+  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
+  Nic->Private             = mPrivate;
+  Nic->Wmp                 = Wmp;
+  Nic->Supplicant          = Supplicant;
+  Nic->EapConfig           = EapConfig;
+  Nic->UserSelectedProfile = NULL;
+  Nic->OneTimeScanRequest  = FALSE;
+
+  if (Nic->Supplicant != NULL) {
+    Status = WifiMgrGetSupportedSuites (Nic);
+  }
+
+  if (!EFI_ERROR (Status)) {
+    InitializeListHead (&Nic->ProfileList);
+
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
+      goto ERROR;
+    }
+
+    Status = WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        return Status;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));
+  }
+
+  if (Nic->ConnectPendingNetwork != NULL) {
+    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
+    }
+
+    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
+    }
+
+    FreePool (Nic->ConnectPendingNetwork);
+  }
+
+ERROR:
+  if (Nic->Supplicant != NULL) {
+    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
+    }
+  }
+
+  FreePool (Nic);
+
+  return Status;
+}
+
 /**
   The callback function for connect operation.
 
@@ -908,12 +1052,13 @@ WifiMgrOnConnectFinished (
   IN  VOID       *Context
   )
 {
-  EFI_STATUS                 Status;
-  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
-  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
-  UINT8                      SecurityType;
-  UINT8                      SSIdLen;
-  CHAR8                      *AsciiSSId;
+  EFI_STATUS                      Status;
+  WIFI_MGR_MAC_CONFIG_TOKEN       *ConfigToken;
+  WIFI_MGR_NETWORK_PROFILE        *ConnectedProfile;
+  UINT8                           SecurityType;
+  UINT8                           SSIdLen;
+  CHAR8                           *AsciiSSId;
+  EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   ASSERT (Context != NULL);
 
@@ -925,6 +1070,24 @@ WifiMgrOnConnectFinished (
   ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
 
   ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
+
+  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
+    if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
+        (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
+    {
+      mWifiConnectionCount++;
+      gBS->CloseEvent (Event);
+      Status = ConnectionRetry (WiFiProfileSyncProtocol);
+      if (!EFI_ERROR (Status)) {
+        return;
+      }
+
+      WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+    }
+  }
+
   if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
     if (ConfigToken->Nic->OneTimeConnectRequest) {
       //
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
index 4ad5643c24..87adfc5033 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
@@ -672,10 +672,23 @@ WifiMgrCleanProfileSecrets (
   IN  WIFI_MGR_NETWORK_PROFILE  *Profile
   )
 {
+  EFI_STATUS                      Status;
+  EFI_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 (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    return;
+  }
+
   if (Profile->CACertData != NULL) {
     ZeroMem (Profile->CACertData, Profile->CACertSize);
     FreePool (Profile->CACertData);
-- 
2.37.3.windows.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2022-11-14 18:11 Clark-williams, Zachary
@ 2023-01-06  5:09 ` Wu, Jiaxin
  2023-01-07  1:17   ` Clark-williams, Zachary
  0 siblings, 1 reply; 11+ messages in thread
From: Wu, Jiaxin @ 2023-01-06  5:09 UTC (permalink / raw)
  To: Clark-williams, Zachary, devel@edk2.groups.io, Kinney, Michael D
  Cc: Zachary Clark-Williams, Maciej Rabeda, Otcheretianski, Andrei,
	Zeng, Star

Hi Zachary,

Insert all my comments as below.

Besides: where defined this protocol (EFI_WIFI_PROFILE_SYNC_PROTOCOL)? I didn't find in the UEFI spec, in such a case, could we named it as EDKII_WIFI_PROFILE_SYNC_PROTOCOL? please add more description about the protocol usage.

Thanks,
Jiaxin


> +/**
> +  Used by the WiFi connection manager to get the WiFi profile that AMT
> shared
> +  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
> +  the WiFi connection manager profile structure fo connection use.
> +
> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile
> structure
> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC
> MAC address
> +
> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned
> succefully
> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or
> enabled
> +  @retval EFI_NOT_FOUND             No profiles to returned
> +  @retval Others                    Error Occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_PROFILE_GET)(
> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
> +  );

Does it mean the returned Profile is only for the returned MacAddress? Does it must 1:1 mapping??

Think more, Does AMT support maintain multiple mappings? Image we have multiple network socket, how AMT handle such case?  




> +
> +/**
> +  Saves the WiFi connection status recieved by the WiFiConnectionManager
> when
> +  in a KVM OR One Click Recovery WLAN recovery flow. Input as
> +  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and
> stored as EFI_STATUS type.
> +

Why need stored as EFI_STATUS type since we have defined the EFI_80211_CONNECT_NETWORK_RESULT_CODE???




> +  @param[in] ConnectionStatus     WiFi connection attempt results
> +**/
> +typedef
> +VOID
> +(EFIAPI *WIFI_SET_CONNECT_STATE)(
> +  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
> +  );
> +
> +/**
> +  Retrieves the stored WiFi connection status when in either KVM OR One
> Click
> +  Recovery WLAN recovery flow.
> +
> +  @retval EFI_SUCCESS               WiFi connection completed succesfully
> +  @retval Others                    Connection failure occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_GET_CONNECT_STATE)(
> +  VOID
> +  );


What's the output? Only EFI_STATUS? why not return the EFI_80211_CONNECT_NETWORK_RESULT_CODE? We should not mix the EFI_80211_CONNECT_NETWORK_RESULT_CODE & EFI_STATUS.



> +
> +//
> +//  WiFi Profile Sync Protocol structure.
> +//
> +typedef struct {
> +  UINT32                    Revision;
> +  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;
> +  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;
> +  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;
> +} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
> +


Could we remove the prefix -- WifiProfileSync?



>    Tests to see if this driver supports a given controller. If a child device is
> provided,
>    it further tests to see if this driver supports creating a handle for the
> specified child device.
> @@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
>    EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
>    EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
>    EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;
> 
> -  Nic = NULL;
> +  mWifiConnectionCount = 0;
> +  Nic                  = NULL;
> 
>    //
>    // Open Protocols
> @@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
>    InitializeListHead (&Nic->ProfileList);
> 
>    //
> -  // Record the MAC address of the incoming NIC.
> +  // WiFi profile sync protocol installation check for OS recovery flow.
>    //
> -  Status = NetLibGetMacAddress (
> -             ControllerHandle,
> -             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> -             &AddressSize
> -             );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> -
> -  //
> -  // Create and start the timer for the status check
> -  //
> -  Status = gBS->CreateEvent (
> -                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
> -                  TPL_CALLBACK,
> -                  WifiMgrOnTimerTick,
> -                  Nic,
> -                  &Nic->TickTimer
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
>                    );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> +  if (!EFI_ERROR (Status)) {
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ERROR1;
> +    }
> 
> -  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR3;
> -  }
> +    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);



This is incorrect! With this change, you might map the profile to the wrong ControllerHandle with incorrect Nic->MacAddress since this is called in the driver binging start, each NIC device will map to the same the MacAddress from the WifiProfileSync protocol!





> +    if (Nic->ConnectPendingNetwork != NULL) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic-
> >ConnectPendingNetwork);


Why we need do this? because we have defined the timer for the connection. See the WifiMgrOnTimerTick().



> +      if (EFI_ERROR (Status)) {
> +        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
> +      }
> +    } else {
> +      goto ERROR1;
> +    }

Could we refine the if... else logic? For example,
If (Error) {
	goto ERROR1;
}
Then do the right things. Existing patch has too much if else condition.



> +  } else {
> +    //
> +    // Record the MAC address of the incoming NIC.
> +    //




>    }
> 
> -  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof
> (UINT8));
> +  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
> +    ASSERT (EFI_INVALID_PARAMETER);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) *
> sizeof (CHAR8));
>    if (AsciiPassword == NULL) {
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword,
> PASSWORD_STORAGE_SIZE);
> -  Status = Supplicant->SetData (
> -                         Supplicant,
> -                         EfiSupplicant80211PskPassword,
> -                         AsciiPassword,
> -                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
> -                         );
> +  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8
> *)AsciiPassword, (StrLen (Profile->Password) + 1));
> +  if (!EFI_ERROR (Status)) {
> +    Status = Supplicant->SetData (
> +                           Supplicant,
> +                           EfiSupplicant80211PskPassword,
> +                           AsciiPassword,
> +                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
> +                           );
> +  }
> +
>    ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
>    FreePool (AsciiPassword);
> 


Looks above change is not related to the changes! could we separate to another patch?



> +
> +**/
> +EFI_STATUS
> + ConnectionRetry (
> +  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
> +  )
> +{

Why need ConnectionRetry?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2023-01-06  5:09 ` Wu, Jiaxin
@ 2023-01-07  1:17   ` Clark-williams, Zachary
  0 siblings, 0 replies; 11+ messages in thread
From: Clark-williams, Zachary @ 2023-01-07  1:17 UTC (permalink / raw)
  To: Wu, Jiaxin, devel@edk2.groups.io, Kinney, Michael D
  Cc: Zachary Clark-Williams, Maciej Rabeda, Otcheretianski, Andrei,
	Zeng, Star

[-- Attachment #1: Type: text/plain, Size: 10783 bytes --]

Thank you Jiaxin,



Find my responses inline.



An updated patch with requested changes is in route today.



Thanks,

Zack



-----Original Message-----
From: Wu, Jiaxin <jiaxin.wu@intel.com>
Sent: Thursday, January 5, 2023 9:09 PM
To: Clark-williams, Zachary <zachary.clark-williams@intel.com>; devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Maciej Rabeda <maciej.rabeda@linux.intel.com>; Otcheretianski, Andrei <andrei.otcheretianski@intel.com>; Zeng, Star <star.zeng@intel.com>
Subject: RE: [PATCH] NetworkPkg: Add WiFi profile sync protocol support



Hi Zachary,



Insert all my comments as below.



Besides: where defined this protocol (EFI_WIFI_PROFILE_SYNC_PROTOCOL)? I didn't find in the UEFI spec, in such a case, could we named it as EDKII_WIFI_PROFILE_SYNC_PROTOCOL? please add more description about the protocol usage.



-                      Yes, Will update naming convention



Thanks,

Jiaxin





> +/**

> +  Used by the WiFi connection manager to get the WiFi profile that

> +AMT

> shared

> +  and was stored in WiFi profile protocol. Aligns the AMT WiFi

> + profile data to  the WiFi connection manager profile structure fo connection use.

> +

> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile

> structure

> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC

> MAC address

> +

> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned

> succefully

> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or

> enabled

> +  @retval EFI_NOT_FOUND             No profiles to returned

> +  @retval Others                    Error Occurred

> +**/

> +typedef

> +EFI_STATUS

> +(EFIAPI *WIFI_PROFILE_GET)(

> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,

> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress

> +  );



Does it mean the returned Profile is only for the returned MacAddress? Does it must 1:1 mapping??

  *   No, this is an Input and Output because we are both fulfilling the WiFi profile data, converting it from the AMT structure to the WifiConnectionManager structure. The MAC address is stored in a separate place In the Nic than the profile data so we pass both locations so we don't need to send the full Nic just these 2 data structure locations.

This is necessary as we need consistency in the MAC from AMT  to correspond with the Profile data.

Think more, Does AMT support maintain multiple mappings? Image we have multiple network socket, how AMT handle such case?

  *   At this point the AMT and CSME doe not support multiple NiC's, or WiFi cards for this process. There will be one NiC, 1 Card and 1 Profile used to keep secrets secure.









> +

> +/**

> +  Saves the WiFi connection status recieved by the

> +WiFiConnectionManager

> when

> +  in a KVM OR One Click Recovery WLAN recovery flow. Input as

> + EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and

> stored as EFI_STATUS type.

> +



Why need stored as EFI_STATUS type since we have defined the EFI_80211_CONNECT_NETWORK_RESULT_CODE???

  *   This is necessary to decouple the code for more modularity, otherwise we would have cross-repo dependencies and very very ugly mess of code. This conversion is simpler and cleaner.







> +  @param[in] ConnectionStatus     WiFi connection attempt results

> +**/

> +typedef

> +VOID

> +(EFIAPI *WIFI_SET_CONNECT_STATE)(

> +  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus

> +  );

> +

> +/**

> +  Retrieves the stored WiFi connection status when in either KVM OR

> +One

> Click

> +  Recovery WLAN recovery flow.

> +

> +  @retval EFI_SUCCESS               WiFi connection completed succesfully

> +  @retval Others                    Connection failure occurred

> +**/

> +typedef

> +EFI_STATUS

> +(EFIAPI *WIFI_GET_CONNECT_STATE)(

> +  VOID

> +  );





What's the output? Only EFI_STATUS? why not return the EFI_80211_CONNECT_NETWORK_RESULT_CODE? We should not mix the EFI_80211_CONNECT_NETWORK_RESULT_CODE & EFI_STATUS.

  *   See answer to previous





> +

> +//

> +//  WiFi Profile Sync Protocol structure.

> +//

> +typedef struct {

> +  UINT32                    Revision;

> +  WIFI_SET_CONNECT_STATE    WifiProfileSyncSetConnectState;

> +  WIFI_GET_CONNECT_STATE    WifiProfileSyncGetConnectState;

> +  WIFI_PROFILE_GET          WifiProfileSyncGetProfile;

> +} EFI_WIFI_PROFILE_SYNC_PROTOCOL;

> +





Could we remove the prefix -- WifiProfileSync?

  *   Great call, update and in next patch





>    Tests to see if this driver supports a given controller. If a child

> device is provided,

>    it further tests to see if this driver supports creating a handle

> for the specified child device.

> @@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (

>    EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;

>    EFI_SUPPLICANT_PROTOCOL                  *Supplicant;

>    EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;

> +  EFI_WIFI_PROFILE_SYNC_PROTOCOL           *WiFiProfileSyncProtocol;

>

> -  Nic = NULL;

> +  mWifiConnectionCount = 0;

> +  Nic                  = NULL;

>

>    //

>    // Open Protocols

> @@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (

>    InitializeListHead (&Nic->ProfileList);

>

>    //

> -  // Record the MAC address of the incoming NIC.

> +  // WiFi profile sync protocol installation check for OS recovery flow.

>    //

> -  Status = NetLibGetMacAddress (

> -             ControllerHandle,

> -             (EFI_MAC_ADDRESS *)&Nic->MacAddress,

> -             &AddressSize

> -             );

> -  if (EFI_ERROR (Status)) {

> -    goto ERROR2;

> -  }

> -

> -  //

> -  // Create and start the timer for the status check

> -  //

> -  Status = gBS->CreateEvent (

> -                  EVT_NOTIFY_SIGNAL | EVT_TIMER,

> -                  TPL_CALLBACK,

> -                  WifiMgrOnTimerTick,

> -                  Nic,

> -                  &Nic->TickTimer

> +  Status = gBS->LocateProtocol (

> +                  &gEfiWiFiProfileSyncProtocolGuid,

> +                  NULL,

> +                  (VOID **)&WiFiProfileSyncProtocol

>                    );

> -  if (EFI_ERROR (Status)) {

> -    goto ERROR2;

> -  }

> +  if (!EFI_ERROR (Status)) {

> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE

> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));

> +    if (Nic->ConnectPendingNetwork == NULL) {

> +      Status = EFI_OUT_OF_RESOURCES;

> +      goto ERROR1;

> +    }

>

> -  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,

> EFI_TIMER_PERIOD_MILLISECONDS (500));

> -  if (EFI_ERROR (Status)) {

> -    goto ERROR3;

> -  }

> +    WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic-

> >ConnectPendingNetwork, Nic->MacAddress);







This is incorrect! With this change, you might map the profile to the wrong ControllerHandle with incorrect Nic->MacAddress since this is called in the driver binging start, each NIC device will map to the same the MacAddress from the WifiProfileSync protocol!

  *   There will only be 1 NiC in this operation and so no miss-mapping will occur.











> +    if (Nic->ConnectPendingNetwork != NULL) {

> +      Status = WifiMgrConnectToNetwork (Nic, Nic-

> >ConnectPendingNetwork);





Why we need do this? because we have defined the timer for the connection. See the WifiMgrOnTimerTick().

  *   We do not want to scan for a profile, we only want to use the profile provided by AMT. so we bypass the timer scanning and jump to the connection with the profile.





> +      if (EFI_ERROR (Status)) {

> +        WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);

> +      }

> +    } else {

> +      goto ERROR1;

> +    }



Could we refine the if... else logic? For example, If (Error) {

                goto ERROR1;

}

Then do the right things. Existing patch has too much if else condition.

  *   Great coding improvement point, updated and in next patch





> +  } else {

> +    //

> +    // Record the MAC address of the incoming NIC.

> +    //









>    }

>

> -  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1)

> * sizeof (UINT8));

> +  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {

> +    ASSERT (EFI_INVALID_PARAMETER);

> +    return EFI_INVALID_PARAMETER;

> +  }

> +

> +  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1)

> + *

> sizeof (CHAR8));

>    if (AsciiPassword == NULL) {

>      return EFI_OUT_OF_RESOURCES;

>    }

>

> -  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword,

> PASSWORD_STORAGE_SIZE);

> -  Status = Supplicant->SetData (

> -                         Supplicant,

> -                         EfiSupplicant80211PskPassword,

> -                         AsciiPassword,

> -                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)

> -                         );

> +  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8

> *)AsciiPassword, (StrLen (Profile->Password) + 1));

> +  if (!EFI_ERROR (Status)) {

> +    Status = Supplicant->SetData (

> +                           Supplicant,

> +                           EfiSupplicant80211PskPassword,

> +                           AsciiPassword,

> +                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)

> +                           );

> +  }

> +

>    ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);

>    FreePool (AsciiPassword);

>





Looks above change is not related to the changes! could we separate to another patch?

  *   These status checks and alignments are necessary for proper operating functionality. They've been tested and validated with this code. It can and should be merged here as it was changed and tested with this feature change.





> +

> +**/

> +EFI_STATUS

> + ConnectionRetry (

> +  IN   EFI_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol

> +  )

> +{



Why need ConnectionRetry?

  *   This is a feature definition addition to the flow of the WLAN recovery. If an error occurs the system will retry connection 3 times incase of connection interruption.





[-- Attachment #2: Type: text/html, Size: 31656 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] NetworkPkg: Add WiFi profile sync protocol support
@ 2023-01-07  1:31 Clark-williams, Zachary
  2023-01-09 17:43 ` Clark-williams, Zachary
  2023-01-10  3:02 ` Wu, Jiaxin
  0 siblings, 2 replies; 11+ messages in thread
From: Clark-williams, Zachary @ 2023-01-07  1:31 UTC (permalink / raw)
  To: devel
  Cc: Zachary Clark-Williams, Maciej Rabeda, Wu Jiaxin,
	Andrei Otcheretianski, Zachary Clark-Williams

From: Zachary Clark-Williams <zclarkw112@gmail.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845

Enables KVM and One Click Recovery WLAN capability with WiFi Profile
Sync feature and protocol. Adding WiFiProfileSyncProtocol, which
supports the profilesync driver operations for transferring WiFi profiles
from AMT to the Supplicant. WiFiConnectionManager will check for the
WifiProfileSyncProtocol and if found will operate on the premise of a
One Click Recovery, or KVM flow with a Wifi profile provided by AMT.

Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
---
 .../Protocol/WiFiProfileSyncProtocol.h        |  90 +++++++
 NetworkPkg/NetworkPkg.dec                     |   3 +
 .../WifiConnectionManagerDxe.inf              |   3 +-
 .../WifiConnectionMgrConfigNVDataStruct.h     |   2 +-
 .../WifiConnectionMgrDriver.c                 | 125 ++++++----
 .../WifiConnectionMgrDxe.h                    |   4 +-
 .../WifiConnectionMgrImpl.c                   | 219 +++++++++++++++---
 .../WifiConnectionMgrMisc.c                   |  13 ++
 8 files changed, 386 insertions(+), 73 deletions(-)
 create mode 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h

diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
new file mode 100644
index 0000000000..90523e30fa
--- /dev/null
+++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
@@ -0,0 +1,90 @@
+/** @file
+  WiFi profile sync protocol. Supports One Click Recovery or KVM OS recovery
+  boot flow over WiFi. This protocol will hold the WiFi profile provided by AMT
+  in its original structure, then convert the profile when the WifiConnectionManager
+  is attempting a connection during a system recovery reboot, OCR or KVM. These
+  converstion and operations are found in the WifiProfileSync driver and in
+  the link provided below.
+
+  Pulbic links to speficiation document for KVM and One Click Recovery feature.
+  https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Foneclickrecovery.htm
+
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
+#define WIFI_PROFILE_SYNC_PROTOCOL_H_
+
+#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
+
+//
+//  WiFi Profile Sync Protocol GUID variable.
+//
+extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
+
+/**
+  Used by the WiFi connection manager to get the WiFi profile that AMT shared
+  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
+  the WiFi connection manager profile structure fo connection use.
+
+  @param[in, out]  WcmProfile       WiFi Connection Manager profile structure
+  @param[in, out]  MacAddress       MAC address from AMT saved to NiC MAC address
+
+  @retval EFI_SUCCESS               Stored WiFi profile converted and returned succefully
+  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or enabled
+  @retval EFI_NOT_FOUND             No profiles to returned
+  @retval Others                    Error Occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_PROFILE_GET)(
+  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
+  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
+  );
+
+/**
+  Saves the WiFi connection status recieved by the WiFiConnectionManager when
+  in a KVM OR One Click Recovery WLAN recovery flow. Input as
+  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and stored as EFI_STATUS type.
+
+  @param[in] ConnectionStatus     WiFi connection attempt results
+**/
+typedef
+VOID
+(EFIAPI *WIFI_SET_CONNECT_STATE)(
+  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
+  );
+
+/**
+  Retrieves the stored WiFi connection status when in either KVM OR One Click
+  Recovery WLAN recovery flow.
+
+  @retval EFI_SUCCESS               WiFi connection completed succesfully
+  @retval Others                    Connection failure occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_GET_CONNECT_STATE)(
+  VOID
+  );
+
+//
+//  WiFi Profile Sync Protocol structure.
+//
+typedef struct {
+  UINT32                    Revision;
+  WIFI_SET_CONNECT_STATE    SetConnectState;
+  WIFI_GET_CONNECT_STATE    GetConnectState;
+  WIFI_PROFILE_GET          GetProfile;
+} EDKII_WIFI_PROFILE_SYNC_PROTOCOL;
+
+/**
+  WiFi Profile Protocol revision number.
+
+  Revision 1:   Initial version
+**/
+#define EDKII_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
+
+#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 5e43ebf8c5..53fb34c4a0 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -91,6 +91,9 @@
   ## Include/Protocol/HttpCallback.h
   gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
 
+  ## Include/Protocol/WiFiProfileSyncProtocol.h
+  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
+
 [PcdsFixedAtBuild]
   ## The max attempt number will be created by iSCSI driver.
   # @Prompt Max attempt number.
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
index 4394b6f4bb..7e36016cf8 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
@@ -9,7 +9,7 @@
 #  2). WPA2 Personal Network
 #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
 #
-#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -71,6 +71,7 @@
   gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
   gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
 
 [Guids]
   gWifiConfigGuid                               ## PRODUCES  ## GUID
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
index b5518a74d8..dcc4bf7e27 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
@@ -25,7 +25,7 @@
 
 #define PASSWORD_MIN_LEN       8
 #define PASSWORD_MAX_LEN       63
-#define PASSWORD_STORAGE_SIZE  64
+#define PASSWORD_STORAGE_SIZE  65
 
 #define EAP_IDENTITY_LEN   63
 #define EAP_IDENTITY_SIZE  64
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
index 67a01ca058..0af55db599 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
@@ -1,7 +1,7 @@
 /** @file
   The driver binding protocol for the WiFi Connection Manager.
 
-  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_G
 EFI_GUID  mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
 EFI_GUID  mWifiConfigMainFormRefreshGuid    = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
 
+//
+// Wifi connection attempt counter for retries
+//
+extern UINT8  mWifiConnectionCount;
+
 /**
   Tests to see if this driver supports a given controller. If a child device is provided,
   it further tests to see if this driver supports creating a handle for the specified child device.
@@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
   EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
   EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
   EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL         *WiFiProfileSyncProtocol;
 
-  Nic = NULL;
+  mWifiConnectionCount = 0;
+  Nic                  = NULL;
 
   //
   // Open Protocols
@@ -236,47 +243,72 @@ WifiMgrDxeDriverBindingStart (
   InitializeListHead (&Nic->ProfileList);
 
   //
-  // Record the MAC address of the incoming NIC.
+  // WiFi profile sync protocol installation check for OS recovery flow.
   //
-  Status = NetLibGetMacAddress (
-             ControllerHandle,
-             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
-             &AddressSize
-             );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
-
-  //
-  // Create and start the timer for the status check
-  //
-  Status = gBS->CreateEvent (
-                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
-                  TPL_CALLBACK,
-                  WifiMgrOnTimerTick,
-                  Nic,
-                  &Nic->TickTimer
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
                   );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
+  if (!EFI_ERROR (Status)) {
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ERROR1;
+    }
 
-  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
-  if (EFI_ERROR (Status)) {
-    goto ERROR3;
-  }
+    WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (Nic->ConnectPendingNetwork != NULL) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        goto ERROR1;
+      }
+      WiFiProfileSyncProtocol->SetConnectState (Status);
+    }
+  } else {
+    //
+    // Record the MAC address of the incoming NIC.
+    //
+    Status = NetLibGetMacAddress (
+               ControllerHandle,
+               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
+               &AddressSize
+               );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  Nic->ConnectState = WifiMgrDisconnected;
-  Nic->ScanState    = WifiMgrScanFinished;
+    //
+    // Create and start the timer for the status check
+    //
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
+                    TPL_CALLBACK,
+                    WifiMgrOnTimerTick,
+                    Nic,
+                    &Nic->TickTimer
+                    );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-  InsertTailList (&mPrivate->NicList, &Nic->Link);
-  Nic->NicIndex = mPrivate->NicCount++;
-  if (mPrivate->CurrentNic == NULL) {
-    mPrivate->CurrentNic = Nic;
-  }
+    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
+    if (EFI_ERROR (Status)) {
+      goto ERROR3;
+    }
 
-  gBS->RestoreTPL (OldTpl);
+    Nic->ConnectState = WifiMgrDisconnected;
+    Nic->ScanState    = WifiMgrScanFinished;
+
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+    InsertTailList (&mPrivate->NicList, &Nic->Link);
+    Nic->NicIndex = mPrivate->NicCount++;
+    if (mPrivate->CurrentNic == NULL) {
+      mPrivate->CurrentNic = Nic;
+    }
+
+    gBS->RestoreTPL (OldTpl);
+  }
 
   Status = gBS->InstallProtocolInterface (
                   &ControllerHandle,
@@ -385,10 +417,11 @@ WifiMgrDxeDriverBindingStop (
   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
   )
 {
-  EFI_STATUS                 Status;
-  EFI_TPL                    OldTpl;
-  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
-  WIFI_MGR_DEVICE_DATA       *Nic;
+  EFI_STATUS                        Status;
+  EFI_TPL                           OldTpl;
+  WIFI_MGR_PRIVATE_PROTOCOL         *WifiMgrIdentifier;
+  WIFI_MGR_DEVICE_DATA              *Nic;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   Status = gBS->OpenProtocol (
                   ControllerHandle,
@@ -481,7 +514,15 @@ WifiMgrDxeDriverBindingStop (
   //
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
-  RemoveEntryList (&Nic->Link);
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    RemoveEntryList (&Nic->Link);
+  }
+
   mPrivate->NicCount--;
   if (mPrivate->CurrentNic == Nic) {
     mPrivate->CurrentNic = NULL;
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
index 7b2e41e155..047f85dbc2 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
@@ -47,6 +47,7 @@
 #include <Protocol/SimpleNetwork.h>
 #include <Protocol/SimpleFileSystem.h>
 #include <Protocol/EapConfiguration.h>
+#include <Protocol/WiFiProfileSyncProtocol.h>
 
 //
 // Produced Protocols
@@ -73,7 +74,8 @@
 //
 #define WIFI_MGR_DXE_VERSION  0xb
 
-#define OUI_IEEE_80211I  0xAC0F00
+#define OUI_IEEE_80211I              0xAC0F00
+#define MAX_WIFI_CONNETION_ATTEMPTS  3
 
 typedef enum {
   Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0,
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
index 59bac48c42..7d471e7591 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
@@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
   EFI_EAP_TYPE_MSCHAPV2
 };
 
+UINT8  mWifiConnectionCount = 0;
+
 /**
   The callback function for scan operation. This function updates networks
   according to the latest scan result, and trigger UI refresh.
@@ -424,18 +426,26 @@ WifiMgrConfigPassword (
     return EFI_NOT_FOUND;
   }
 
-  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
+  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
+    ASSERT (EFI_INVALID_PARAMETER);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));
   if (AsciiPassword == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
-  Status = Supplicant->SetData (
-                         Supplicant,
-                         EfiSupplicant80211PskPassword,
-                         AsciiPassword,
-                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
-                         );
+  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, (StrLen (Profile->Password) + 1));
+  if (!EFI_ERROR (Status)) {
+    Status = Supplicant->SetData (
+                           Supplicant,
+                           EfiSupplicant80211PskPassword,
+                           AsciiPassword,
+                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
+                           );
+  }
+
   ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
   FreePool (AsciiPassword);
 
@@ -465,19 +475,20 @@ WifiMgrConfigEap (
   IN    WIFI_MGR_NETWORK_PROFILE  *Profile
   )
 {
-  EFI_STATUS                      Status;
-  EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
-  EFI_EAP_TYPE                    EapAuthMethod;
-  EFI_EAP_TYPE                    EapSecondAuthMethod;
-  EFI_EAP_TYPE                    *AuthMethodList;
-  CHAR8                           *Identity;
-  UINTN                           IdentitySize;
-  CHAR16                          *Password;
-  UINTN                           PasswordSize;
-  UINTN                           EncryptPasswordLen;
-  CHAR8                           *AsciiEncryptPassword;
-  UINTN                           AuthMethodListSize;
-  UINTN                           Index;
+  EFI_STATUS                        Status;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
+  EFI_EAP_CONFIGURATION_PROTOCOL    *EapConfig;
+  EFI_EAP_TYPE                      EapAuthMethod;
+  EFI_EAP_TYPE                      EapSecondAuthMethod;
+  EFI_EAP_TYPE                      *AuthMethodList;
+  CHAR8                             *Identity;
+  UINTN                             IdentitySize;
+  CHAR16                            *Password;
+  UINTN                             PasswordSize;
+  UINTN                             EncryptPasswordLen;
+  CHAR8                             *AsciiEncryptPassword;
+  UINTN                             AuthMethodListSize;
+  UINTN                             Index;
 
   if ((Nic == NULL) || (Nic->EapConfig == NULL) || (Profile == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -567,7 +578,13 @@ WifiMgrConfigEap (
       return EFI_OUT_OF_RESOURCES;
     }
 
-    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+    if (!EFI_ERROR (Status)) {
+      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
+    } else {
+      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    }
+
     Status = EapConfig->SetData (
                           EapConfig,
                           EFI_EAP_TYPE_IDENTITY,
@@ -892,6 +909,133 @@ WifiMgrPrepareConnection (
   return EFI_SUCCESS;
 }
 
+/**
+  Will reset NiC data, get profile from profile sync driver, and send for
+  another connection attempt.This function should not be called more than
+  3 times.
+
+  @param[in]  WiFiProfileSyncProtocol  The target network profile to connect.
+
+  @retval EFI_SUCCESS                  The operation is completed.
+  @retval other                        Operation failure.
+
+**/
+EFI_STATUS
+ConnectionRetry (
+  IN   EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
+  )
+{
+  EFI_STATUS                               Status;
+  WIFI_MGR_DEVICE_DATA                     *Nic;
+  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
+  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
+  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+
+  Nic = NULL;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFi2ProtocolGuid,
+                  NULL,
+                  (VOID **)&Wmp
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSupplicantProtocolGuid,
+                  NULL,
+                  (VOID **)&Supplicant
+                  );
+  if (EFI_ERROR (Status)) {
+    Supplicant = NULL;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiEapConfigurationProtocolGuid,
+                  NULL,
+                  (VOID **)&EapConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    EapConfig = NULL;
+  }
+
+  //
+  // Initialize Nic device data
+  //
+  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
+  if (Nic == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    return Status;
+  }
+
+  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
+  Nic->Private             = mPrivate;
+  Nic->Wmp                 = Wmp;
+  Nic->Supplicant          = Supplicant;
+  Nic->EapConfig           = EapConfig;
+  Nic->UserSelectedProfile = NULL;
+  Nic->OneTimeScanRequest  = FALSE;
+
+  if (Nic->Supplicant != NULL) {
+    Status = WifiMgrGetSupportedSuites (Nic);
+  }
+
+  if (!EFI_ERROR (Status)) {
+    InitializeListHead (&Nic->ProfileList);
+
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
+      goto ERROR;
+    }
+
+    Status = WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        return Status;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));
+  }
+
+  if (Nic->ConnectPendingNetwork != NULL) {
+    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
+    }
+
+    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
+    }
+
+    FreePool (Nic->ConnectPendingNetwork);
+  }
+
+ERROR:
+  if (Nic->Supplicant != NULL) {
+    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
+    }
+  }
+
+  FreePool (Nic);
+
+  return Status;
+}
+
 /**
   The callback function for connect operation.
 
@@ -908,12 +1052,13 @@ WifiMgrOnConnectFinished (
   IN  VOID       *Context
   )
 {
-  EFI_STATUS                 Status;
-  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
-  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
-  UINT8                      SecurityType;
-  UINT8                      SSIdLen;
-  CHAR8                      *AsciiSSId;
+  EFI_STATUS                        Status;
+  WIFI_MGR_MAC_CONFIG_TOKEN         *ConfigToken;
+  WIFI_MGR_NETWORK_PROFILE          *ConnectedProfile;
+  UINT8                             SecurityType;
+  UINT8                             SSIdLen;
+  CHAR8                             *AsciiSSId;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   ASSERT (Context != NULL);
 
@@ -925,6 +1070,24 @@ WifiMgrOnConnectFinished (
   ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
 
   ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
+
+  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    WiFiProfileSyncProtocol->SetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
+    if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
+        (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
+    {
+      mWifiConnectionCount++;
+      gBS->CloseEvent (Event);
+      Status = ConnectionRetry (WiFiProfileSyncProtocol);
+      if (!EFI_ERROR (Status)) {
+        return;
+      }
+
+      WiFiProfileSyncProtocol->SetConnectState (Status);
+    }
+  }
+
   if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
     if (ConfigToken->Nic->OneTimeConnectRequest) {
       //
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
index 4ad5643c24..518572922f 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
@@ -672,10 +672,23 @@ 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 (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+  if (!EFI_ERROR (Status)) {
+    return;
+  }
+
   if (Profile->CACertData != NULL) {
     ZeroMem (Profile->CACertData, Profile->CACertSize);
     FreePool (Profile->CACertData);
-- 
2.37.3.windows.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2023-01-07  1:31 Clark-williams, Zachary
@ 2023-01-09 17:43 ` Clark-williams, Zachary
  2023-01-10  3:02 ` Wu, Jiaxin
  1 sibling, 0 replies; 11+ messages in thread
From: Clark-williams, Zachary @ 2023-01-09 17:43 UTC (permalink / raw)
  To: devel@edk2.groups.io
  Cc: Zachary Clark-Williams, Maciej Rabeda, Wu, Jiaxin,
	Otcheretianski, Andrei

Hey Jiaxin,

Please rind my updated patch below. Let me know when you get this reviewed so I can get it merged as soon as possible. 

Thank you,
Zack

-----Original Message-----
From: Clark-williams, Zachary <zachary.clark-williams@intel.com> 
Sent: Friday, January 6, 2023 5:31 PM
To: devel@edk2.groups.io
Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Maciej Rabeda <maciej.rabeda@linux.intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>; Otcheretianski, Andrei <andrei.otcheretianski@intel.com>; Clark-williams, Zachary <zachary.clark-williams@intel.com>
Subject: [PATCH] NetworkPkg: Add WiFi profile sync protocol support

From: Zachary Clark-Williams <zclarkw112@gmail.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845

Enables KVM and One Click Recovery WLAN capability with WiFi Profile Sync feature and protocol. Adding WiFiProfileSyncProtocol, which supports the profilesync driver operations for transferring WiFi profiles from AMT to the Supplicant. WiFiConnectionManager will check for the WifiProfileSyncProtocol and if found will operate on the premise of a One Click Recovery, or KVM flow with a Wifi profile provided by AMT.

Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
---
 .../Protocol/WiFiProfileSyncProtocol.h        |  90 +++++++
 NetworkPkg/NetworkPkg.dec                     |   3 +
 .../WifiConnectionManagerDxe.inf              |   3 +-
 .../WifiConnectionMgrConfigNVDataStruct.h     |   2 +-
 .../WifiConnectionMgrDriver.c                 | 125 ++++++----
 .../WifiConnectionMgrDxe.h                    |   4 +-
 .../WifiConnectionMgrImpl.c                   | 219 +++++++++++++++---
 .../WifiConnectionMgrMisc.c                   |  13 ++
 8 files changed, 386 insertions(+), 73 deletions(-)  create mode 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h

diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
new file mode 100644
index 0000000000..90523e30fa
--- /dev/null
+++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
@@ -0,0 +1,90 @@
+/** @file
+  WiFi profile sync protocol. Supports One Click Recovery or KVM OS 
+recovery
+  boot flow over WiFi. This protocol will hold the WiFi profile 
+provided by AMT
+  in its original structure, then convert the profile when the 
+WifiConnectionManager
+  is attempting a connection during a system recovery reboot, OCR or 
+KVM. These
+  converstion and operations are found in the WifiProfileSync driver 
+and in
+  the link provided below.
+
+  Pulbic links to speficiation document for KVM and One Click Recovery feature.
+  
+ https://software.intel.com/sites/manageability/AMT_Implementation_and_
+ Reference_Guide/default.htm?turl=WordDocuments%2Foneclickrecovery.htm
+
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
+#define WIFI_PROFILE_SYNC_PROTOCOL_H_
+
+#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
+
+//
+//  WiFi Profile Sync Protocol GUID variable.
+//
+extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
+
+/**
+  Used by the WiFi connection manager to get the WiFi profile that AMT 
+shared
+  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile 
+data to
+  the WiFi connection manager profile structure fo connection use.
+
+  @param[in, out]  WcmProfile       WiFi Connection Manager profile structure
+  @param[in, out]  MacAddress       MAC address from AMT saved to NiC MAC address
+
+  @retval EFI_SUCCESS               Stored WiFi profile converted and returned succefully
+  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or enabled
+  @retval EFI_NOT_FOUND             No profiles to returned
+  @retval Others                    Error Occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_PROFILE_GET)(
+  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
+  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
+  );
+
+/**
+  Saves the WiFi connection status recieved by the 
+WiFiConnectionManager when
+  in a KVM OR One Click Recovery WLAN recovery flow. Input as
+  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and stored as EFI_STATUS type.
+
+  @param[in] ConnectionStatus     WiFi connection attempt results
+**/
+typedef
+VOID
+(EFIAPI *WIFI_SET_CONNECT_STATE)(
+  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
+  );
+
+/**
+  Retrieves the stored WiFi connection status when in either KVM OR One 
+Click
+  Recovery WLAN recovery flow.
+
+  @retval EFI_SUCCESS               WiFi connection completed succesfully
+  @retval Others                    Connection failure occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_GET_CONNECT_STATE)(
+  VOID
+  );
+
+//
+//  WiFi Profile Sync Protocol structure.
+//
+typedef struct {
+  UINT32                    Revision;
+  WIFI_SET_CONNECT_STATE    SetConnectState;
+  WIFI_GET_CONNECT_STATE    GetConnectState;
+  WIFI_PROFILE_GET          GetProfile;
+} EDKII_WIFI_PROFILE_SYNC_PROTOCOL;
+
+/**
+  WiFi Profile Protocol revision number.
+
+  Revision 1:   Initial version
+**/
+#define EDKII_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
+
+#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index 5e43ebf8c5..53fb34c4a0 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -91,6 +91,9 @@
   ## Include/Protocol/HttpCallback.h
   gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
 
+  ## Include/Protocol/WiFiProfileSyncProtocol.h
+  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 
+ 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
+
 [PcdsFixedAtBuild]
   ## The max attempt number will be created by iSCSI driver.
   # @Prompt Max attempt number.
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
index 4394b6f4bb..7e36016cf8 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
@@ -9,7 +9,7 @@
 #  2). WPA2 Personal Network
 #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)  # -#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2019 - 2022, Intel Corporation. All rights 
+reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -71,6 +71,7 @@
   gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
   gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
 
 [Guids]
   gWifiConfigGuid                               ## PRODUCES  ## GUID
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
index b5518a74d8..dcc4bf7e27 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataS
+++ truct.h
@@ -25,7 +25,7 @@
 
 #define PASSWORD_MIN_LEN       8
 #define PASSWORD_MAX_LEN       63
-#define PASSWORD_STORAGE_SIZE  64
+#define PASSWORD_STORAGE_SIZE  65
 
 #define EAP_IDENTITY_LEN   63
 #define EAP_IDENTITY_SIZE  64
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
index 67a01ca058..0af55db599 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
@@ -1,7 +1,7 @@
 /** @file
   The driver binding protocol for the WiFi Connection Manager.
 
-  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019 - 2022, Intel Corporation. All rights 
+ reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_G
 EFI_GUID  mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
 EFI_GUID  mWifiConfigMainFormRefreshGuid    = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
 
+//
+// Wifi connection attempt counter for retries // extern UINT8  
+mWifiConnectionCount;
+
 /**
   Tests to see if this driver supports a given controller. If a child device is provided,
   it further tests to see if this driver supports creating a handle for the specified child device.
@@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
   EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
   EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
   EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL         *WiFiProfileSyncProtocol;
 
-  Nic = NULL;
+  mWifiConnectionCount = 0;
+  Nic                  = NULL;
 
   //
   // Open Protocols
@@ -236,47 +243,72 @@ WifiMgrDxeDriverBindingStart (
   InitializeListHead (&Nic->ProfileList);
 
   //
-  // Record the MAC address of the incoming NIC.
+  // WiFi profile sync protocol installation check for OS recovery flow.
   //
-  Status = NetLibGetMacAddress (
-             ControllerHandle,
-             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
-             &AddressSize
-             );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
-
-  //
-  // Create and start the timer for the status check
-  //
-  Status = gBS->CreateEvent (
-                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
-                  TPL_CALLBACK,
-                  WifiMgrOnTimerTick,
-                  Nic,
-                  &Nic->TickTimer
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
                   );
-  if (EFI_ERROR (Status)) {
-    goto ERROR2;
-  }
+  if (!EFI_ERROR (Status)) {
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ERROR1;
+    }
 
-  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
-  if (EFI_ERROR (Status)) {
-    goto ERROR3;
-  }
+    WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (Nic->ConnectPendingNetwork != NULL) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        goto ERROR1;
+      }
+      WiFiProfileSyncProtocol->SetConnectState (Status);
+    }
+  } else {
+    //
+    // Record the MAC address of the incoming NIC.
+    //
+    Status = NetLibGetMacAddress (
+               ControllerHandle,
+               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
+               &AddressSize
+               );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  Nic->ConnectState = WifiMgrDisconnected;
-  Nic->ScanState    = WifiMgrScanFinished;
+    //
+    // Create and start the timer for the status check
+    //
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
+                    TPL_CALLBACK,
+                    WifiMgrOnTimerTick,
+                    Nic,
+                    &Nic->TickTimer
+                    );
+    if (EFI_ERROR (Status)) {
+      goto ERROR2;
+    }
 
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-  InsertTailList (&mPrivate->NicList, &Nic->Link);
-  Nic->NicIndex = mPrivate->NicCount++;
-  if (mPrivate->CurrentNic == NULL) {
-    mPrivate->CurrentNic = Nic;
-  }
+    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
+    if (EFI_ERROR (Status)) {
+      goto ERROR3;
+    }
 
-  gBS->RestoreTPL (OldTpl);
+    Nic->ConnectState = WifiMgrDisconnected;
+    Nic->ScanState    = WifiMgrScanFinished;
+
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+    InsertTailList (&mPrivate->NicList, &Nic->Link);
+    Nic->NicIndex = mPrivate->NicCount++;
+    if (mPrivate->CurrentNic == NULL) {
+      mPrivate->CurrentNic = Nic;
+    }
+
+    gBS->RestoreTPL (OldTpl);
+  }
 
   Status = gBS->InstallProtocolInterface (
                   &ControllerHandle,
@@ -385,10 +417,11 @@ WifiMgrDxeDriverBindingStop (
   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
   )
 {
-  EFI_STATUS                 Status;
-  EFI_TPL                    OldTpl;
-  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
-  WIFI_MGR_DEVICE_DATA       *Nic;
+  EFI_STATUS                        Status;
+  EFI_TPL                           OldTpl;
+  WIFI_MGR_PRIVATE_PROTOCOL         *WifiMgrIdentifier;
+  WIFI_MGR_DEVICE_DATA              *Nic;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   Status = gBS->OpenProtocol (
                   ControllerHandle,
@@ -481,7 +514,15 @@ WifiMgrDxeDriverBindingStop (
   //
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
-  RemoveEntryList (&Nic->Link);
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFiProfileSyncProtocolGuid,
+                  NULL,
+                  (VOID **)&WiFiProfileSyncProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    RemoveEntryList (&Nic->Link);
+  }
+
   mPrivate->NicCount--;
   if (mPrivate->CurrentNic == Nic) {
     mPrivate->CurrentNic = NULL;
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
index 7b2e41e155..047f85dbc2 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
@@ -47,6 +47,7 @@
 #include <Protocol/SimpleNetwork.h>
 #include <Protocol/SimpleFileSystem.h>
 #include <Protocol/EapConfiguration.h>
+#include <Protocol/WiFiProfileSyncProtocol.h>
 
 //
 // Produced Protocols
@@ -73,7 +74,8 @@
 //
 #define WIFI_MGR_DXE_VERSION  0xb
 
-#define OUI_IEEE_80211I  0xAC0F00
+#define OUI_IEEE_80211I              0xAC0F00
+#define MAX_WIFI_CONNETION_ATTEMPTS  3
 
 typedef enum {
   Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0, diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
index 59bac48c42..7d471e7591 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
@@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
   EFI_EAP_TYPE_MSCHAPV2
 };
 
+UINT8  mWifiConnectionCount = 0;
+
 /**
   The callback function for scan operation. This function updates networks
   according to the latest scan result, and trigger UI refresh.
@@ -424,18 +426,26 @@ WifiMgrConfigPassword (
     return EFI_NOT_FOUND;
   }
 
-  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
+  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
+    ASSERT (EFI_INVALID_PARAMETER);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * 
+ sizeof (CHAR8));
   if (AsciiPassword == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
-  Status = Supplicant->SetData (
-                         Supplicant,
-                         EfiSupplicant80211PskPassword,
-                         AsciiPassword,
-                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
-                         );
+  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 
+ *)AsciiPassword, (StrLen (Profile->Password) + 1));  if (!EFI_ERROR (Status)) {
+    Status = Supplicant->SetData (
+                           Supplicant,
+                           EfiSupplicant80211PskPassword,
+                           AsciiPassword,
+                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
+                           );
+  }
+
   ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
   FreePool (AsciiPassword);
 
@@ -465,19 +475,20 @@ WifiMgrConfigEap (
   IN    WIFI_MGR_NETWORK_PROFILE  *Profile
   )
 {
-  EFI_STATUS                      Status;
-  EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
-  EFI_EAP_TYPE                    EapAuthMethod;
-  EFI_EAP_TYPE                    EapSecondAuthMethod;
-  EFI_EAP_TYPE                    *AuthMethodList;
-  CHAR8                           *Identity;
-  UINTN                           IdentitySize;
-  CHAR16                          *Password;
-  UINTN                           PasswordSize;
-  UINTN                           EncryptPasswordLen;
-  CHAR8                           *AsciiEncryptPassword;
-  UINTN                           AuthMethodListSize;
-  UINTN                           Index;
+  EFI_STATUS                        Status;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
+  EFI_EAP_CONFIGURATION_PROTOCOL    *EapConfig;
+  EFI_EAP_TYPE                      EapAuthMethod;
+  EFI_EAP_TYPE                      EapSecondAuthMethod;
+  EFI_EAP_TYPE                      *AuthMethodList;
+  CHAR8                             *Identity;
+  UINTN                             IdentitySize;
+  CHAR16                            *Password;
+  UINTN                             PasswordSize;
+  UINTN                             EncryptPasswordLen;
+  CHAR8                             *AsciiEncryptPassword;
+  UINTN                             AuthMethodListSize;
+  UINTN                             Index;
 
   if ((Nic == NULL) || (Nic->EapConfig == NULL) || (Profile == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -567,7 +578,13 @@ WifiMgrConfigEap (
       return EFI_OUT_OF_RESOURCES;
     }
 
-    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+    if (!EFI_ERROR (Status)) {
+      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
+    } else {
+      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+    }
+
     Status = EapConfig->SetData (
                           EapConfig,
                           EFI_EAP_TYPE_IDENTITY, @@ -892,6 +909,133 @@ WifiMgrPrepareConnection (
   return EFI_SUCCESS;
 }
 
+/**
+  Will reset NiC data, get profile from profile sync driver, and send 
+for
+  another connection attempt.This function should not be called more 
+than
+  3 times.
+
+  @param[in]  WiFiProfileSyncProtocol  The target network profile to connect.
+
+  @retval EFI_SUCCESS                  The operation is completed.
+  @retval other                        Operation failure.
+
+**/
+EFI_STATUS
+ConnectionRetry (
+  IN   EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
+  )
+{
+  EFI_STATUS                               Status;
+  WIFI_MGR_DEVICE_DATA                     *Nic;
+  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
+  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
+  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
+
+  Nic = NULL;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiWiFi2ProtocolGuid,
+                  NULL,
+                  (VOID **)&Wmp
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSupplicantProtocolGuid,
+                  NULL,
+                  (VOID **)&Supplicant
+                  );
+  if (EFI_ERROR (Status)) {
+    Supplicant = NULL;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiEapConfigurationProtocolGuid,
+                  NULL,
+                  (VOID **)&EapConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    EapConfig = NULL;
+  }
+
+  //
+  // Initialize Nic device data
+  //
+  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));  if (Nic == 
+ NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    return Status;
+  }
+
+  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
+  Nic->Private             = mPrivate;
+  Nic->Wmp                 = Wmp;
+  Nic->Supplicant          = Supplicant;
+  Nic->EapConfig           = EapConfig;
+  Nic->UserSelectedProfile = NULL;
+  Nic->OneTimeScanRequest  = FALSE;
+
+  if (Nic->Supplicant != NULL) {
+    Status = WifiMgrGetSupportedSuites (Nic);  }
+
+  if (!EFI_ERROR (Status)) {
+    InitializeListHead (&Nic->ProfileList);
+
+    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+    if (Nic->ConnectPendingNetwork == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
+      goto ERROR;
+    }
+
+    Status = WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
+      Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+      if (!EFI_ERROR (Status)) {
+        return Status;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get 
+ Supported suites with status %r\n", Status));  }
+
+  if (Nic->ConnectPendingNetwork != NULL) {
+    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
+    }
+
+    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
+      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
+    }
+
+    FreePool (Nic->ConnectPendingNetwork);  }
+
+ERROR:
+  if (Nic->Supplicant != NULL) {
+    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
+    }
+
+    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
+      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
+    }
+  }
+
+  FreePool (Nic);
+
+  return Status;
+}
+
 /**
   The callback function for connect operation.
 
@@ -908,12 +1052,13 @@ WifiMgrOnConnectFinished (
   IN  VOID       *Context
   )
 {
-  EFI_STATUS                 Status;
-  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
-  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
-  UINT8                      SecurityType;
-  UINT8                      SSIdLen;
-  CHAR8                      *AsciiSSId;
+  EFI_STATUS                        Status;
+  WIFI_MGR_MAC_CONFIG_TOKEN         *ConfigToken;
+  WIFI_MGR_NETWORK_PROFILE          *ConnectedProfile;
+  UINT8                             SecurityType;
+  UINT8                             SSIdLen;
+  CHAR8                             *AsciiSSId;
+  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
 
   ASSERT (Context != NULL);
 
@@ -925,6 +1070,24 @@ WifiMgrOnConnectFinished (
   ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
 
   ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
+
+  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, 
+ (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
+    WiFiProfileSyncProtocol->SetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
+    if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
+        (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
+    {
+      mWifiConnectionCount++;
+      gBS->CloseEvent (Event);
+      Status = ConnectionRetry (WiFiProfileSyncProtocol);
+      if (!EFI_ERROR (Status)) {
+        return;
+      }
+
+      WiFiProfileSyncProtocol->SetConnectState (Status);
+    }
+  }
+
   if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
     if (ConfigToken->Nic->OneTimeConnectRequest) {
       //
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
index 4ad5643c24..518572922f 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
@@ -672,10 +672,23 @@ 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 (&gEfiWiFiProfileSyncProtocolGuid, NULL, 
+ (VOID **)&WiFiProfileSyncProtocol);  if (!EFI_ERROR (Status)) {
+    return;
+  }
+
   if (Profile->CACertData != NULL) {
     ZeroMem (Profile->CACertData, Profile->CACertSize);
     FreePool (Profile->CACertData);
--
2.37.3.windows.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] NetworkPkg: Add WiFi profile sync protocol support
  2023-01-07  1:31 Clark-williams, Zachary
  2023-01-09 17:43 ` Clark-williams, Zachary
@ 2023-01-10  3:02 ` Wu, Jiaxin
  1 sibling, 0 replies; 11+ messages in thread
From: Wu, Jiaxin @ 2023-01-10  3:02 UTC (permalink / raw)
  To: Clark-williams, Zachary, devel@edk2.groups.io
  Cc: Zachary Clark-Williams, Maciej Rabeda, Otcheretianski, Andrei

One comment as below, Others good to me. 

Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>


> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile
> structure
> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC
> MAC address
> +
> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned
> succefully
> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or
> enabled
> +  @retval EFI_NOT_FOUND             No profiles to returned
> +  @retval Others                    Error Occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_PROFILE_GET)(
> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
> +  );

Does it make sense remove the OUT declaring since this is just to get the corresponding MacAddress Profile? For OUT, we expect there will be changed when return but here it's not.

Thanks,
Jiaxin 

> -----Original Message-----
> From: Clark-williams, Zachary <zachary.clark-williams@intel.com>
> Sent: Saturday, January 7, 2023 9:31 AM
> To: devel@edk2.groups.io
> Cc: Zachary Clark-Williams <zclarkw112@gmail.com>; Maciej Rabeda
> <maciej.rabeda@linux.intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>;
> Otcheretianski, Andrei <andrei.otcheretianski@intel.com>; Clark-williams,
> Zachary <zachary.clark-williams@intel.com>
> Subject: [PATCH] NetworkPkg: Add WiFi profile sync protocol support
> 
> From: Zachary Clark-Williams <zclarkw112@gmail.com>
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3845
> 
> Enables KVM and One Click Recovery WLAN capability with WiFi Profile
> Sync feature and protocol. Adding WiFiProfileSyncProtocol, which
> supports the profilesync driver operations for transferring WiFi profiles
> from AMT to the Supplicant. WiFiConnectionManager will check for the
> WifiProfileSyncProtocol and if found will operate on the premise of a
> One Click Recovery, or KVM flow with a Wifi profile provided by AMT.
> 
> Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
> Cc: Wu Jiaxin <jiaxin.wu@intel.com>
> Cc: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
> 
> Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@intel.com>
> ---
>  .../Protocol/WiFiProfileSyncProtocol.h        |  90 +++++++
>  NetworkPkg/NetworkPkg.dec                     |   3 +
>  .../WifiConnectionManagerDxe.inf              |   3 +-
>  .../WifiConnectionMgrConfigNVDataStruct.h     |   2 +-
>  .../WifiConnectionMgrDriver.c                 | 125 ++++++----
>  .../WifiConnectionMgrDxe.h                    |   4 +-
>  .../WifiConnectionMgrImpl.c                   | 219 +++++++++++++++---
>  .../WifiConnectionMgrMisc.c                   |  13 ++
>  8 files changed, 386 insertions(+), 73 deletions(-)
>  create mode 100644
> NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> 
> diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> new file mode 100644
> index 0000000000..90523e30fa
> --- /dev/null
> +++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  WiFi profile sync protocol. Supports One Click Recovery or KVM OS
> recovery
> +  boot flow over WiFi. This protocol will hold the WiFi profile provided by
> AMT
> +  in its original structure, then convert the profile when the
> WifiConnectionManager
> +  is attempting a connection during a system recovery reboot, OCR or KVM.
> These
> +  converstion and operations are found in the WifiProfileSync driver and in
> +  the link provided below.
> +
> +  Pulbic links to speficiation document for KVM and One Click Recovery
> feature.
> +
> https://software.intel.com/sites/manageability/AMT_Implementation_and_
> Reference_Guide/default.htm?turl=WordDocuments%2Foneclickrecovery.h
> tm
> +
> +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
> +#define WIFI_PROFILE_SYNC_PROTOCOL_H_
> +
> +#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
> +
> +//
> +//  WiFi Profile Sync Protocol GUID variable.
> +//
> +extern EFI_GUID  gEfiWiFiProfileSyncProtocolGuid;
> +
> +/**
> +  Used by the WiFi connection manager to get the WiFi profile that AMT
> shared
> +  and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
> +  the WiFi connection manager profile structure fo connection use.
> +
> +  @param[in, out]  WcmProfile       WiFi Connection Manager profile
> structure
> +  @param[in, out]  MacAddress       MAC address from AMT saved to NiC
> MAC address
> +
> +  @retval EFI_SUCCESS               Stored WiFi profile converted and returned
> succefully
> +  @retval EFI_UNSUPPORTED           Profile protocol sharing not supported or
> enabled
> +  @retval EFI_NOT_FOUND             No profiles to returned
> +  @retval Others                    Error Occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_PROFILE_GET)(
> +  IN OUT  WIFI_MGR_NETWORK_PROFILE  *Profile,
> +  IN OUT  EFI_80211_MAC_ADDRESS     MacAddress
> +  );
> +
> +/**
> +  Saves the WiFi connection status recieved by the WiFiConnectionManager
> when
> +  in a KVM OR One Click Recovery WLAN recovery flow. Input as
> +  EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and
> stored as EFI_STATUS type.
> +
> +  @param[in] ConnectionStatus     WiFi connection attempt results
> +**/
> +typedef
> +VOID
> +(EFIAPI *WIFI_SET_CONNECT_STATE)(
> +  IN  EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
> +  );
> +
> +/**
> +  Retrieves the stored WiFi connection status when in either KVM OR One
> Click
> +  Recovery WLAN recovery flow.
> +
> +  @retval EFI_SUCCESS               WiFi connection completed succesfully
> +  @retval Others                    Connection failure occurred
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WIFI_GET_CONNECT_STATE)(
> +  VOID
> +  );
> +
> +//
> +//  WiFi Profile Sync Protocol structure.
> +//
> +typedef struct {
> +  UINT32                    Revision;
> +  WIFI_SET_CONNECT_STATE    SetConnectState;
> +  WIFI_GET_CONNECT_STATE    GetConnectState;
> +  WIFI_PROFILE_GET          GetProfile;
> +} EDKII_WIFI_PROFILE_SYNC_PROTOCOL;
> +
> +/**
> +  WiFi Profile Protocol revision number.
> +
> +  Revision 1:   Initial version
> +**/
> +#define EDKII_WIFI_PROFILE_SYNC_PROTOCOL_REVISION  1
> +
> +#endif //  WIFI_PROFILE_SYNC_PROTOCOL_H_
> diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
> index 5e43ebf8c5..53fb34c4a0 100644
> --- a/NetworkPkg/NetworkPkg.dec
> +++ b/NetworkPkg/NetworkPkg.dec
> @@ -91,6 +91,9 @@
>    ## Include/Protocol/HttpCallback.h
>    gEdkiiHttpCallbackProtocolGuid  = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36,
> 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}
> 
> +  ## Include/Protocol/WiFiProfileSyncProtocol.h
> +  gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a,
> 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
> +
>  [PcdsFixedAtBuild]
>    ## The max attempt number will be created by iSCSI driver.
>    # @Prompt Max attempt number.
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> index 4394b6f4bb..7e36016cf8 100644
> ---
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> +++
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
> @@ -9,7 +9,7 @@
>  #  2). WPA2 Personal Network
>  #  3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
>  #
> -#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -71,6 +71,7 @@
>    gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
>    gEfiSupplicantProtocolGuid                    ## SOMETIMES_CONSUMES
>    gEfiEapConfigurationProtocolGuid              ## SOMETIMES_CONSUMES
> +  gEfiWiFiProfileSyncProtocolGuid               ## SOMETIMES_CONSUMES
> 
>  [Guids]
>    gWifiConfigGuid                               ## PRODUCES  ## GUID
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDa
> taStruct.h
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDa
> taStruct.h
> index b5518a74d8..dcc4bf7e27 100644
> ---
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDa
> taStruct.h
> +++
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDa
> taStruct.h
> @@ -25,7 +25,7 @@
> 
>  #define PASSWORD_MIN_LEN       8
>  #define PASSWORD_MAX_LEN       63
> -#define PASSWORD_STORAGE_SIZE  64
> +#define PASSWORD_STORAGE_SIZE  65
> 
>  #define EAP_IDENTITY_LEN   63
>  #define EAP_IDENTITY_SIZE  64
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> index 67a01ca058..0af55db599 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
> @@ -1,7 +1,7 @@
>  /** @file
>    The driver binding protocol for the WiFi Connection Manager.
> 
> -  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -39,6 +39,11 @@ EFI_GUID  mWifiConfigNetworkListRefreshGuid =
> WIFI_CONFIG_NETWORK_LIST_REFRESH_G
>  EFI_GUID  mWifiConfigConnectFormRefreshGuid =
> WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
>  EFI_GUID  mWifiConfigMainFormRefreshGuid    =
> WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
> 
> +//
> +// Wifi connection attempt counter for retries
> +//
> +extern UINT8  mWifiConnectionCount;
> +
>  /**
>    Tests to see if this driver supports a given controller. If a child device is
> provided,
>    it further tests to see if this driver supports creating a handle for the
> specified child device.
> @@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
>    EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
>    EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
>    EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +  EDKII_WIFI_PROFILE_SYNC_PROTOCOL         *WiFiProfileSyncProtocol;
> 
> -  Nic = NULL;
> +  mWifiConnectionCount = 0;
> +  Nic                  = NULL;
> 
>    //
>    // Open Protocols
> @@ -236,47 +243,72 @@ WifiMgrDxeDriverBindingStart (
>    InitializeListHead (&Nic->ProfileList);
> 
>    //
> -  // Record the MAC address of the incoming NIC.
> +  // WiFi profile sync protocol installation check for OS recovery flow.
>    //
> -  Status = NetLibGetMacAddress (
> -             ControllerHandle,
> -             (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> -             &AddressSize
> -             );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> -
> -  //
> -  // Create and start the timer for the status check
> -  //
> -  Status = gBS->CreateEvent (
> -                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
> -                  TPL_CALLBACK,
> -                  WifiMgrOnTimerTick,
> -                  Nic,
> -                  &Nic->TickTimer
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
>                    );
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR2;
> -  }
> +  if (!EFI_ERROR (Status)) {
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ERROR1;
> +    }
> 
> -  Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> -  if (EFI_ERROR (Status)) {
> -    goto ERROR3;
> -  }
> +    WiFiProfileSyncProtocol->GetProfile (Nic->ConnectPendingNetwork, Nic-
> >MacAddress);
> +    if (Nic->ConnectPendingNetwork != NULL) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic-
> >ConnectPendingNetwork);
> +      if (!EFI_ERROR (Status)) {
> +        goto ERROR1;
> +      }
> +      WiFiProfileSyncProtocol->SetConnectState (Status);
> +    }
> +  } else {
> +    //
> +    // Record the MAC address of the incoming NIC.
> +    //
> +    Status = NetLibGetMacAddress (
> +               ControllerHandle,
> +               (EFI_MAC_ADDRESS *)&Nic->MacAddress,
> +               &AddressSize
> +               );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  Nic->ConnectState = WifiMgrDisconnected;
> -  Nic->ScanState    = WifiMgrScanFinished;
> +    //
> +    // Create and start the timer for the status check
> +    //
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL | EVT_TIMER,
> +                    TPL_CALLBACK,
> +                    WifiMgrOnTimerTick,
> +                    Nic,
> +                    &Nic->TickTimer
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR2;
> +    }
> 
> -  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> -  InsertTailList (&mPrivate->NicList, &Nic->Link);
> -  Nic->NicIndex = mPrivate->NicCount++;
> -  if (mPrivate->CurrentNic == NULL) {
> -    mPrivate->CurrentNic = Nic;
> -  }
> +    Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic,
> EFI_TIMER_PERIOD_MILLISECONDS (500));
> +    if (EFI_ERROR (Status)) {
> +      goto ERROR3;
> +    }
> 
> -  gBS->RestoreTPL (OldTpl);
> +    Nic->ConnectState = WifiMgrDisconnected;
> +    Nic->ScanState    = WifiMgrScanFinished;
> +
> +    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +    InsertTailList (&mPrivate->NicList, &Nic->Link);
> +    Nic->NicIndex = mPrivate->NicCount++;
> +    if (mPrivate->CurrentNic == NULL) {
> +      mPrivate->CurrentNic = Nic;
> +    }
> +
> +    gBS->RestoreTPL (OldTpl);
> +  }
> 
>    Status = gBS->InstallProtocolInterface (
>                    &ControllerHandle,
> @@ -385,10 +417,11 @@ WifiMgrDxeDriverBindingStop (
>    IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
>    )
>  {
> -  EFI_STATUS                 Status;
> -  EFI_TPL                    OldTpl;
> -  WIFI_MGR_PRIVATE_PROTOCOL  *WifiMgrIdentifier;
> -  WIFI_MGR_DEVICE_DATA       *Nic;
> +  EFI_STATUS                        Status;
> +  EFI_TPL                           OldTpl;
> +  WIFI_MGR_PRIVATE_PROTOCOL         *WifiMgrIdentifier;
> +  WIFI_MGR_DEVICE_DATA              *Nic;
> +  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    Status = gBS->OpenProtocol (
>                    ControllerHandle,
> @@ -481,7 +514,15 @@ WifiMgrDxeDriverBindingStop (
>    //
>    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> 
> -  RemoveEntryList (&Nic->Link);
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFiProfileSyncProtocolGuid,
> +                  NULL,
> +                  (VOID **)&WiFiProfileSyncProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    RemoveEntryList (&Nic->Link);
> +  }
> +
>    mPrivate->NicCount--;
>    if (mPrivate->CurrentNic == Nic) {
>      mPrivate->CurrentNic = NULL;
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> index 7b2e41e155..047f85dbc2 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
> @@ -47,6 +47,7 @@
>  #include <Protocol/SimpleNetwork.h>
>  #include <Protocol/SimpleFileSystem.h>
>  #include <Protocol/EapConfiguration.h>
> +#include <Protocol/WiFiProfileSyncProtocol.h>
> 
>  //
>  // Produced Protocols
> @@ -73,7 +74,8 @@
>  //
>  #define WIFI_MGR_DXE_VERSION  0xb
> 
> -#define OUI_IEEE_80211I  0xAC0F00
> +#define OUI_IEEE_80211I              0xAC0F00
> +#define MAX_WIFI_CONNETION_ATTEMPTS  3
> 
>  typedef enum {
>    Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0,
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> index 59bac48c42..7d471e7591 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
> @@ -19,6 +19,8 @@ EFI_EAP_TYPE  mEapSecondAuthMethod[] = {
>    EFI_EAP_TYPE_MSCHAPV2
>  };
> 
> +UINT8  mWifiConnectionCount = 0;
> +
>  /**
>    The callback function for scan operation. This function updates networks
>    according to the latest scan result, and trigger UI refresh.
> @@ -424,18 +426,26 @@ WifiMgrConfigPassword (
>      return EFI_NOT_FOUND;
>    }
> 
> -  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof
> (UINT8));
> +  if (StrLen (Profile->Password) >= PASSWORD_STORAGE_SIZE) {
> +    ASSERT (EFI_INVALID_PARAMETER);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) *
> sizeof (CHAR8));
>    if (AsciiPassword == NULL) {
>      return EFI_OUT_OF_RESOURCES;
>    }
> 
> -  UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword,
> PASSWORD_STORAGE_SIZE);
> -  Status = Supplicant->SetData (
> -                         Supplicant,
> -                         EfiSupplicant80211PskPassword,
> -                         AsciiPassword,
> -                         (StrLen (Profile->Password) + 1) * sizeof (UINT8)
> -                         );
> +  Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8
> *)AsciiPassword, (StrLen (Profile->Password) + 1));
> +  if (!EFI_ERROR (Status)) {
> +    Status = Supplicant->SetData (
> +                           Supplicant,
> +                           EfiSupplicant80211PskPassword,
> +                           AsciiPassword,
> +                           (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
> +                           );
> +  }
> +
>    ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
>    FreePool (AsciiPassword);
> 
> @@ -465,19 +475,20 @@ WifiMgrConfigEap (
>    IN    WIFI_MGR_NETWORK_PROFILE  *Profile
>    )
>  {
> -  EFI_STATUS                      Status;
> -  EFI_EAP_CONFIGURATION_PROTOCOL  *EapConfig;
> -  EFI_EAP_TYPE                    EapAuthMethod;
> -  EFI_EAP_TYPE                    EapSecondAuthMethod;
> -  EFI_EAP_TYPE                    *AuthMethodList;
> -  CHAR8                           *Identity;
> -  UINTN                           IdentitySize;
> -  CHAR16                          *Password;
> -  UINTN                           PasswordSize;
> -  UINTN                           EncryptPasswordLen;
> -  CHAR8                           *AsciiEncryptPassword;
> -  UINTN                           AuthMethodListSize;
> -  UINTN                           Index;
> +  EFI_STATUS                        Status;
> +  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> +  EFI_EAP_CONFIGURATION_PROTOCOL    *EapConfig;
> +  EFI_EAP_TYPE                      EapAuthMethod;
> +  EFI_EAP_TYPE                      EapSecondAuthMethod;
> +  EFI_EAP_TYPE                      *AuthMethodList;
> +  CHAR8                             *Identity;
> +  UINTN                             IdentitySize;
> +  CHAR16                            *Password;
> +  UINTN                             PasswordSize;
> +  UINTN                             EncryptPasswordLen;
> +  CHAR8                             *AsciiEncryptPassword;
> +  UINTN                             AuthMethodListSize;
> +  UINTN                             Index;
> 
>    if ((Nic == NULL) || (Nic->EapConfig == NULL) || (Profile == NULL)) {
>      return EFI_INVALID_PARAMETER;
> @@ -567,7 +578,13 @@ WifiMgrConfigEap (
>        return EFI_OUT_OF_RESOURCES;
>      }
> 
> -    UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> (VOID **)&WiFiProfileSyncProtocol);
> +    if (!EFI_ERROR (Status)) {
> +      CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
> +    } else {
> +      UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
> +    }
> +
>      Status = EapConfig->SetData (
>                            EapConfig,
>                            EFI_EAP_TYPE_IDENTITY,
> @@ -892,6 +909,133 @@ WifiMgrPrepareConnection (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Will reset NiC data, get profile from profile sync driver, and send for
> +  another connection attempt.This function should not be called more than
> +  3 times.
> +
> +  @param[in]  WiFiProfileSyncProtocol  The target network profile to
> connect.
> +
> +  @retval EFI_SUCCESS                  The operation is completed.
> +  @retval other                        Operation failure.
> +
> +**/
> +EFI_STATUS
> +ConnectionRetry (
> +  IN   EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol
> +  )
> +{
> +  EFI_STATUS                               Status;
> +  WIFI_MGR_DEVICE_DATA                     *Nic;
> +  EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL  *Wmp;
> +  EFI_SUPPLICANT_PROTOCOL                  *Supplicant;
> +  EFI_EAP_CONFIGURATION_PROTOCOL           *EapConfig;
> +
> +  Nic = NULL;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiWiFi2ProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Wmp
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSupplicantProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Supplicant
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Supplicant = NULL;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiEapConfigurationProtocolGuid,
> +                  NULL,
> +                  (VOID **)&EapConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    EapConfig = NULL;
> +  }
> +
> +  //
> +  // Initialize Nic device data
> +  //
> +  Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
> +  if (Nic == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    return Status;
> +  }
> +
> +  Nic->Signature           = WIFI_MGR_DEVICE_DATA_SIGNATURE;
> +  Nic->Private             = mPrivate;
> +  Nic->Wmp                 = Wmp;
> +  Nic->Supplicant          = Supplicant;
> +  Nic->EapConfig           = EapConfig;
> +  Nic->UserSelectedProfile = NULL;
> +  Nic->OneTimeScanRequest  = FALSE;
> +
> +  if (Nic->Supplicant != NULL) {
> +    Status = WifiMgrGetSupportedSuites (Nic);
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    InitializeListHead (&Nic->ProfileList);
> +
> +    Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE
> *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
> +    if (Nic->ConnectPendingNetwork == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate
> memory for ConnectPendingNetwork\n"));
> +      goto ERROR;
> +    }
> +
> +    Status = WiFiProfileSyncProtocol->GetProfile (Nic-
> >ConnectPendingNetwork, Nic->MacAddress);
> +    if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
> +      Status = WifiMgrConnectToNetwork (Nic, Nic-
> >ConnectPendingNetwork);
> +      if (!EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi
> profile with status %r\n", Status));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get
> Supported suites with status %r\n", Status));
> +  }
> +
> +  if (Nic->ConnectPendingNetwork != NULL) {
> +    if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
> +    }
> +
> +    if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
> +      FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
> +    }
> +
> +    FreePool (Nic->ConnectPendingNetwork);
> +  }
> +
> +ERROR:
> +  if (Nic->Supplicant != NULL) {
> +    if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedAKMSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
> +    }
> +
> +    if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
> +      FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
> +    }
> +  }
> +
> +  FreePool (Nic);
> +
> +  return Status;
> +}
> +
>  /**
>    The callback function for connect operation.
> 
> @@ -908,12 +1052,13 @@ WifiMgrOnConnectFinished (
>    IN  VOID       *Context
>    )
>  {
> -  EFI_STATUS                 Status;
> -  WIFI_MGR_MAC_CONFIG_TOKEN  *ConfigToken;
> -  WIFI_MGR_NETWORK_PROFILE   *ConnectedProfile;
> -  UINT8                      SecurityType;
> -  UINT8                      SSIdLen;
> -  CHAR8                      *AsciiSSId;
> +  EFI_STATUS                        Status;
> +  WIFI_MGR_MAC_CONFIG_TOKEN         *ConfigToken;
> +  WIFI_MGR_NETWORK_PROFILE          *ConnectedProfile;
> +  UINT8                             SecurityType;
> +  UINT8                             SSIdLen;
> +  CHAR8                             *AsciiSSId;
> +  EDKII_WIFI_PROFILE_SYNC_PROTOCOL  *WiFiProfileSyncProtocol;
> 
>    ASSERT (Context != NULL);
> 
> @@ -925,6 +1070,24 @@ WifiMgrOnConnectFinished (
>    ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);
> 
>    ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
> +
> +  Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> (VOID **)&WiFiProfileSyncProtocol);
> +  if (!EFI_ERROR (Status)) {
> +    WiFiProfileSyncProtocol->SetConnectState (ConfigToken-
> >Token.ConnectNetworkToken->ResultCode);
> +    if ((mWifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
> +        (ConfigToken->Token.ConnectNetworkToken->ResultCode !=
> ConnectSuccess))
> +    {
> +      mWifiConnectionCount++;
> +      gBS->CloseEvent (Event);
> +      Status = ConnectionRetry (WiFiProfileSyncProtocol);
> +      if (!EFI_ERROR (Status)) {
> +        return;
> +      }
> +
> +      WiFiProfileSyncProtocol->SetConnectState (Status);
> +    }
> +  }
> +
>    if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
>      if (ConfigToken->Nic->OneTimeConnectRequest) {
>        //
> diff --git
> a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> index 4ad5643c24..518572922f 100644
> --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
> @@ -672,10 +672,23 @@ 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 (&gEfiWiFiProfileSyncProtocolGuid, NULL,
> (VOID **)&WiFiProfileSyncProtocol);
> +  if (!EFI_ERROR (Status)) {
> +    return;
> +  }
> +
>    if (Profile->CACertData != NULL) {
>      ZeroMem (Profile->CACertData, Profile->CACertSize);
>      FreePool (Profile->CACertData);
> --
> 2.37.3.windows.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-01-10  3:02 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-14 19:42 [PATCH] NetworkPkg: Add WiFi profile sync protocol support Clark-williams, Zachary
2022-09-26  7:37 ` [edk2-devel] " Heng Luo
2022-09-26 15:39   ` Clark-williams, Zachary
2022-09-26 16:27     ` Michael Brown
2022-09-26 17:39       ` Clark-williams, Zachary
  -- strict thread matches above, loose matches on Subject: below --
2022-11-14 18:11 Clark-williams, Zachary
2023-01-06  5:09 ` Wu, Jiaxin
2023-01-07  1:17   ` Clark-williams, Zachary
2023-01-07  1:31 Clark-williams, Zachary
2023-01-09 17:43 ` Clark-williams, Zachary
2023-01-10  3:02 ` Wu, Jiaxin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox