]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/Ikev2/Utility.c
NetworkPkg: Remove IpSec driver and application
[mirror_edk2.git] / NetworkPkg / IpSecDxe / Ikev2 / Utility.c
diff --git a/NetworkPkg/IpSecDxe/Ikev2/Utility.c b/NetworkPkg/IpSecDxe/Ikev2/Utility.c
deleted file mode 100644 (file)
index 87ec0bf..0000000
+++ /dev/null
@@ -1,2738 +0,0 @@
-/** @file\r
-  The Common operations used by IKE Exchange Process.\r
-\r
-  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Utility.h"\r
-#include "IpSecDebug.h"\r
-#include "IkeService.h"\r
-#include "IpSecConfigImpl.h"\r
-\r
-UINT16 mIkev2EncryptAlgorithmList[IKEV2_SUPPORT_ENCRYPT_ALGORITHM_NUM] = {\r
-  IKEV2_TRANSFORM_ID_ENCR_3DES,\r
-  IKEV2_TRANSFORM_ID_ENCR_AES_CBC,\r
-};\r
-\r
-UINT16 mIkev2PrfAlgorithmList[IKEV2_SUPPORT_PRF_ALGORITHM_NUM] = {\r
-  IKEV2_TRANSFORM_ID_PRF_HMAC_SHA1,\r
-};\r
-\r
-UINT16 mIkev2DhGroupAlgorithmList[IKEV2_SUPPORT_DH_ALGORITHM_NUM] = {\r
-  IKEV2_TRANSFORM_ID_DH_1024MODP,\r
-  IKEV2_TRANSFORM_ID_DH_2048MODP,\r
-};\r
-\r
-UINT16 mIkev2AuthAlgorithmList[IKEV2_SUPPORT_AUTH_ALGORITHM_NUM] = {\r
-  IKEV2_TRANSFORM_ID_AUTH_HMAC_SHA1_96,\r
-};\r
-\r
-/**\r
-  Allocate buffer for IKEV2_SA_SESSION and initialize it.\r
-\r
-  @param[in] Private        Pointer to IPSEC_PRIVATE_DATA.\r
-  @param[in] UdpService     Pointer to IKE_UDP_SERVICE related to this IKE SA Session.\r
-\r
-  @return Pointer to IKEV2_SA_SESSION or NULL.\r
-\r
-**/\r
-IKEV2_SA_SESSION *\r
-Ikev2SaSessionAlloc (\r
-  IN IPSEC_PRIVATE_DATA       *Private,\r
-  IN IKE_UDP_SERVICE          *UdpService\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  IKEV2_SESSION_COMMON  *SessionCommon;\r
-  IKEV2_SA_SESSION      *IkeSaSession;\r
-\r
-  IkeSaSession = AllocateZeroPool (sizeof (IKEV2_SA_SESSION));\r
-  if (IkeSaSession == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Initialize the fields of IkeSaSession and its SessionCommon.\r
-  //\r
-  IkeSaSession->NCookie              = NULL;\r
-  IkeSaSession->Signature            = IKEV2_SA_SESSION_SIGNATURE;\r
-  IkeSaSession->InitiatorCookie      = IkeGenerateCookie ();\r
-  IkeSaSession->ResponderCookie      = 0;\r
-  //\r
-  // BUGBUG: Message ID starts from 2 is to match the OpenSwan requirement, but it\r
-  // might not match the IPv6 Logo. In its test specification, it mentions that\r
-  // the Message ID should start from zero after the IKE_SA_INIT exchange.\r
-  //\r
-  IkeSaSession->MessageId            = 2;\r
-  SessionCommon                      = &IkeSaSession->SessionCommon;\r
-  SessionCommon->UdpService          = UdpService;\r
-  SessionCommon->Private             = Private;\r
-  SessionCommon->IkeSessionType      = IkeSessionTypeIkeSa;\r
-  SessionCommon->IkeVer              = 2;\r
-  SessionCommon->AfterEncodePayload  = NULL;\r
-  SessionCommon->BeforeDecodePayload = NULL;\r
-\r
-  //\r
-  // Create a resend notfiy event for retry.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Ikev2ResendNotify,\r
-                  SessionCommon,\r
-                  &SessionCommon->TimeoutEvent\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (IkeSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Initialize the lists in IkeSaSession.\r
-  //\r
-  InitializeListHead (&IkeSaSession->ChildSaSessionList);\r
-  InitializeListHead (&IkeSaSession->ChildSaEstablishSessionList);\r
-  InitializeListHead (&IkeSaSession->InfoMIDList);\r
-  InitializeListHead (&IkeSaSession->DeleteSaList);\r
-\r
-  return IkeSaSession;\r
-}\r
-\r
-/**\r
-  Register the established IKEv2 SA into Private->Ikev2EstablishedList. If there is\r
-  IKEV2_SA_SESSION with same remote peer IP, remove the old one then register the\r
-  new one.\r
-\r
-  @param[in]  IkeSaSession  Pointer to IKEV2_SA_SESSION to be registered.\r
-  @param[in]  Private       Pointer to IPSEC_PRAVATE_DATA.\r
-\r
-**/\r
-VOID\r
-Ikev2SaSessionReg (\r
-  IN IKEV2_SA_SESSION          *IkeSaSession,\r
-  IN IPSEC_PRIVATE_DATA        *Private\r
-  )\r
-{\r
-  IKEV2_SESSION_COMMON         *SessionCommon;\r
-  IKEV2_SA_SESSION             *OldIkeSaSession;\r
-  EFI_STATUS                   Status;\r
-  UINT64                       Lifetime;\r
-\r
-  //\r
-  // Keep IKE SA exclusive to remote ip address.\r
-  //\r
-  SessionCommon   = &IkeSaSession->SessionCommon;\r
-  OldIkeSaSession = Ikev2SaSessionRemove (&Private->Ikev2EstablishedList, &SessionCommon->RemotePeerIp);\r
-  if (OldIkeSaSession != NULL) {\r
-    //\r
-    // TODO: It should delete all child SAs if rekey the IKE SA.\r
-    //\r
-    Ikev2SaSessionFree (OldIkeSaSession);\r
-  }\r
-\r
-  //\r
-  // Cleanup the fields of SessionCommon for processing.\r
-  //\r
-  Ikev2SessionCommonRefresh (SessionCommon);\r
-\r
-  //\r
-  // Insert the ready IKE SA session into established list.\r
-  //\r
-  Ikev2SaSessionInsert (&Private->Ikev2EstablishedList, IkeSaSession, &SessionCommon->RemotePeerIp);\r
-\r
-  //\r
-  // Create a notfiy event for the IKE SA life time counting.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Ikev2LifetimeNotify,\r
-                  SessionCommon,\r
-                  &SessionCommon->TimeoutEvent\r
-                  );\r
-  if (EFI_ERROR(Status)){\r
-    //\r
-    // If TimerEvent creation failed, the SA will be alive untill user disable it or\r
-    // receiving a Delete Payload from peer.\r
-    //\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Start to count the lifetime of the IKE SA.\r
-  //\r
-  if (IkeSaSession->Spd->Data->ProcessingPolicy->SaLifetime.HardLifetime == 0) {\r
-    Lifetime = IKE_SA_DEFAULT_LIFETIME;\r
-  } else {\r
-    Lifetime = IkeSaSession->Spd->Data->ProcessingPolicy->SaLifetime.HardLifetime;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  SessionCommon->TimeoutEvent,\r
-                  TimerRelative,\r
-                  MultU64x32(Lifetime, 10000000) // ms->100ns\r
-                  );\r
-  if (EFI_ERROR(Status)){\r
-    //\r
-    // If SetTimer failed, the SA will be alive untill user disable it or\r
-    // receiving a Delete Payload from peer.\r
-    //\r
-    return ;\r
-  }\r
-\r
-  DEBUG ((\r
-    DEBUG_INFO,\r
-    "\n------IkeSa established and start to count down %d seconds lifetime\n",\r
-    Lifetime\r
-    ));\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Find a IKEV2_SA_SESSION by the remote peer IP.\r
-\r
-  @param[in]  SaSessionList     SaSession List to be searched.\r
-  @param[in]  RemotePeerIp      Pointer to specified IP address.\r
-\r
-  @return Pointer to IKEV2_SA_SESSION if find one or NULL.\r
-\r
-**/\r
-IKEV2_SA_SESSION *\r
-Ikev2SaSessionLookup (\r
-  IN LIST_ENTRY           *SaSessionList,\r
-  IN EFI_IP_ADDRESS       *RemotePeerIp\r
-  )\r
-{\r
-  LIST_ENTRY        *Entry;\r
-  IKEV2_SA_SESSION  *IkeSaSession;\r
-\r
-  NET_LIST_FOR_EACH (Entry, SaSessionList) {\r
-    IkeSaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
-\r
-    if (CompareMem (\r
-          &IkeSaSession->SessionCommon.RemotePeerIp,\r
-          RemotePeerIp,\r
-          sizeof (EFI_IP_ADDRESS)\r
-          ) == 0) {\r
-\r
-      return IkeSaSession;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Insert a IKE_SA_SESSION into IkeSaSession list. The IkeSaSession list is either\r
-  Private->Ikev2SaSession list or Private->Ikev2EstablishedList list.\r
-\r
-  @param[in]  SaSessionList   Pointer to list to be inserted into.\r
-  @param[in]  IkeSaSession    Pointer to IKEV2_SA_SESSION to be inserted.\r
-  @param[in]  RemotePeerIp    Pointer to EFI_IP_ADDRESSS to indicate the\r
-                              unique IKEV2_SA_SESSION.\r
-\r
-**/\r
-VOID\r
-Ikev2SaSessionInsert (\r
-  IN LIST_ENTRY           *SaSessionList,\r
-  IN IKEV2_SA_SESSION     *IkeSaSession,\r
-  IN EFI_IP_ADDRESS       *RemotePeerIp\r
-  )\r
-{\r
-  Ikev2SaSessionRemove (SaSessionList, RemotePeerIp);\r
-  InsertTailList (SaSessionList, &IkeSaSession->BySessionTable);\r
-}\r
-\r
-/**\r
-  Remove the SA Session by Remote Peer IP.\r
-\r
-  @param[in]  SaSessionList   Pointer to list to be searched.\r
-  @param[in]  RemotePeerIp    Pointer to EFI_IP_ADDRESS to use for SA Session search.\r
-\r
-  @retval Pointer to IKEV2_SA_SESSION with the specified remote IP address or NULL.\r
-\r
-**/\r
-IKEV2_SA_SESSION *\r
-Ikev2SaSessionRemove (\r
-  IN LIST_ENTRY           *SaSessionList,\r
-  IN EFI_IP_ADDRESS       *RemotePeerIp\r
-  )\r
-{\r
-  LIST_ENTRY        *Entry;\r
-  IKEV2_SA_SESSION  *IkeSaSession;\r
-\r
-  NET_LIST_FOR_EACH (Entry, SaSessionList) {\r
-    IkeSaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
-\r
-    if (CompareMem (\r
-          &IkeSaSession->SessionCommon.RemotePeerIp,\r
-          RemotePeerIp,\r
-          sizeof (EFI_IP_ADDRESS)\r
-          ) == 0) {\r
-\r
-      RemoveEntryList (Entry);\r
-      return IkeSaSession;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Free specified Seession Common. The session common would belong to a IKE SA or\r
-  a Child SA.\r
-\r
-  @param[in]   SessionCommon   Pointer to a Session Common.\r
-\r
-**/\r
-VOID\r
-Ikev2SaSessionCommonFree (\r
-  IN IKEV2_SESSION_COMMON      *SessionCommon\r
-  )\r
-{\r
-\r
-  ASSERT (SessionCommon != NULL);\r
-\r
-  if (SessionCommon->LastSentPacket != NULL) {\r
-    IkePacketFree (SessionCommon->LastSentPacket);\r
-  }\r
-\r
-  if (SessionCommon->SaParams != NULL) {\r
-    FreePool (SessionCommon->SaParams);\r
-  }\r
-  if (SessionCommon->TimeoutEvent != NULL) {\r
-    gBS->CloseEvent (SessionCommon->TimeoutEvent);\r
-  }\r
-}\r
-\r
-/**\r
-  After IKE/Child SA is estiblished, close the time event and free sent packet.\r
-\r
-  @param[in]   SessionCommon   Pointer to a Session Common.\r
-\r
-**/\r
-VOID\r
-Ikev2SessionCommonRefresh (\r
-  IN IKEV2_SESSION_COMMON      *SessionCommon\r
-  )\r
-{\r
-  ASSERT (SessionCommon != NULL);\r
-\r
-  gBS->CloseEvent (SessionCommon->TimeoutEvent);\r
-  SessionCommon->TimeoutEvent     = NULL;\r
-  SessionCommon->TimeoutInterval  = 0;\r
-  SessionCommon->RetryCount       = 0;\r
-  if (SessionCommon->LastSentPacket != NULL) {\r
-    IkePacketFree (SessionCommon->LastSentPacket);\r
-    SessionCommon->LastSentPacket = NULL;\r
-  }\r
-\r
-  return ;\r
-}\r
-/**\r
-  Free specified IKEV2 SA Session.\r
-\r
-  @param[in]    IkeSaSession   Pointer to IKEV2_SA_SESSION to be freed.\r
-\r
-**/\r
-VOID\r
-Ikev2SaSessionFree (\r
-  IN IKEV2_SA_SESSION         *IkeSaSession\r
-  )\r
-{\r
-  IKEV2_SESSION_KEYS      *IkeKeys;\r
-  LIST_ENTRY              *Entry;\r
-  IKEV2_CHILD_SA_SESSION  *ChildSa;\r
-  IKEV2_DH_BUFFER         *DhBuffer;\r
-\r
-  ASSERT (IkeSaSession != NULL);\r
-\r
-  //\r
-  // Delete Common Session\r
-  //\r
-  Ikev2SaSessionCommonFree (&IkeSaSession->SessionCommon);\r
-\r
-  //\r
-  // Delete ChildSaEstablish List and SAD\r
-  //\r
-  for (Entry = IkeSaSession->ChildSaEstablishSessionList.ForwardLink;\r
-       Entry != &IkeSaSession->ChildSaEstablishSessionList;\r
-      ) {\r
-\r
-    ChildSa = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
-    Entry   = Entry->ForwardLink;\r
-    Ikev2ChildSaSilentDelete (ChildSa->IkeSaSession, ChildSa->LocalPeerSpi);\r
-\r
-  }\r
-\r
-  //\r
-  // Delete ChildSaSessionList\r
-  //\r
-  for ( Entry  = IkeSaSession->ChildSaSessionList.ForwardLink;\r
-        Entry != &IkeSaSession->ChildSaSessionList;\r
-        ){\r
-    ChildSa = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
-    Entry   = Entry->ForwardLink;\r
-    RemoveEntryList (Entry->BackLink);\r
-    Ikev2ChildSaSessionFree (ChildSa);\r
-  }\r
-\r
-  //\r
-  // Delete DhBuffer and Keys\r
-  //\r
-  if (IkeSaSession->IkeKeys != NULL) {\r
-    IkeKeys  = IkeSaSession->IkeKeys;\r
-    DhBuffer = IkeKeys->DhBuffer;\r
-\r
-    //\r
-    // Delete DhBuffer\r
-    //\r
-    Ikev2DhBufferFree (DhBuffer);\r
-\r
-    //\r
-    // Delete Keys\r
-    //\r
-    if (IkeKeys->SkAiKey != NULL) {\r
-      FreePool (IkeKeys->SkAiKey);\r
-    }\r
-    if (IkeKeys->SkArKey != NULL) {\r
-      FreePool (IkeKeys->SkArKey);\r
-    }\r
-    if (IkeKeys->SkdKey != NULL) {\r
-      FreePool (IkeKeys->SkdKey);\r
-    }\r
-    if (IkeKeys->SkEiKey != NULL) {\r
-      FreePool (IkeKeys->SkEiKey);\r
-    }\r
-    if (IkeKeys->SkErKey != NULL) {\r
-      FreePool (IkeKeys->SkErKey);\r
-    }\r
-    if (IkeKeys->SkPiKey != NULL) {\r
-      FreePool (IkeKeys->SkPiKey);\r
-    }\r
-    if (IkeKeys->SkPrKey != NULL) {\r
-      FreePool (IkeKeys->SkPrKey);\r
-    }\r
-    FreePool (IkeKeys);\r
-  }\r
-\r
-  if (IkeSaSession->SaData != NULL) {\r
-    FreePool (IkeSaSession->SaData);\r
-  }\r
-\r
-  if (IkeSaSession->NiBlock != NULL) {\r
-    FreePool (IkeSaSession->NiBlock);\r
-  }\r
-\r
-  if (IkeSaSession->NrBlock != NULL) {\r
-    FreePool (IkeSaSession->NrBlock);\r
-  }\r
-\r
-  if (IkeSaSession->NCookie != NULL) {\r
-    FreePool (IkeSaSession->NCookie);\r
-  }\r
-\r
-  if (IkeSaSession->InitPacket != NULL) {\r
-    FreePool (IkeSaSession->InitPacket);\r
-  }\r
-\r
-  if (IkeSaSession->RespPacket != NULL) {\r
-    FreePool (IkeSaSession->RespPacket);\r
-  }\r
-\r
-  FreePool (IkeSaSession);\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Increase the MessageID in IkeSaSession.\r
-\r
-  @param[in] IkeSaSession Pointer to a specified IKEV2_SA_SESSION.\r
-\r
-**/\r
-VOID\r
-Ikev2SaSessionIncreaseMessageId (\r
-  IN IKEV2_SA_SESSION         *IkeSaSession\r
-  )\r
-{\r
-  if (IkeSaSession->MessageId < 0xffffffff) {\r
-    IkeSaSession->MessageId ++;\r
-  } else {\r
-    //\r
-    // TODO: Trigger Rekey process.\r
-    //\r
-  }\r
-}\r
-\r
-/**\r
-  Allocate memory for IKEV2 Child SA Session.\r
-\r
-  @param[in]   UdpService     Pointer to IKE_UDP_SERVICE.\r
-  @param[in]   IkeSaSession   Pointer to IKEV2_SA_SESSION related to this Child SA\r
-                              Session.\r
-\r
-  @retval  Pointer of a new created IKEV2 Child SA Session or NULL.\r
-\r
-**/\r
-IKEV2_CHILD_SA_SESSION *\r
-Ikev2ChildSaSessionAlloc (\r
-  IN IKE_UDP_SERVICE          *UdpService,\r
-  IN IKEV2_SA_SESSION         *IkeSaSession\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  IKEV2_CHILD_SA_SESSION      *ChildSaSession;\r
-  IKEV2_SESSION_COMMON        *ChildSaCommon;\r
-  IKEV2_SESSION_COMMON        *SaCommon;\r
-\r
-  ChildSaSession = AllocateZeroPool (sizeof (IKEV2_CHILD_SA_SESSION));\r
-  if (ChildSaSession == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Initialize the fields of ChildSaSession and its SessionCommon.\r
-  //\r
-  ChildSaSession->Signature          = IKEV2_CHILD_SA_SESSION_SIGNATURE;\r
-  ChildSaSession->IkeSaSession       = IkeSaSession;\r
-  ChildSaSession->MessageId          = IkeSaSession->MessageId;\r
-\r
-  //\r
-  // Generate an new SPI.\r
-  //\r
-  Status = IkeGenerateSpi (IkeSaSession, &(ChildSaSession->LocalPeerSpi));\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (ChildSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  ChildSaCommon                      = &ChildSaSession->SessionCommon;\r
-  ChildSaCommon->UdpService          = UdpService;\r
-  ChildSaCommon->Private             = IkeSaSession->SessionCommon.Private;\r
-  ChildSaCommon->IkeSessionType      = IkeSessionTypeChildSa;\r
-  ChildSaCommon->IkeVer              = 2;\r
-  ChildSaCommon->AfterEncodePayload  = Ikev2ChildSaAfterEncodePayload;\r
-  ChildSaCommon->BeforeDecodePayload = Ikev2ChildSaBeforeDecodePayload;\r
-  SaCommon = &ChildSaSession->IkeSaSession->SessionCommon;\r
-\r
-  //\r
-  // Create a resend notfiy event for retry.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Ikev2ResendNotify,\r
-                  ChildSaCommon,\r
-                  &ChildSaCommon->TimeoutEvent\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (ChildSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  CopyMem (&ChildSaCommon->LocalPeerIp, &SaCommon->LocalPeerIp, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&ChildSaCommon->RemotePeerIp, &SaCommon->RemotePeerIp, sizeof (EFI_IP_ADDRESS));\r
-\r
-  return ChildSaSession;\r
-}\r
-\r
-/**\r
-  Register a established IKEv2 Child SA into IkeSaSession->ChildSaEstablishSessionList.\r
-  If the there is IKEV2_CHILD_SA_SESSION with same remote peer IP, remove the old one\r
-  then register the new one.\r
-\r
-  @param[in]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION to be registered.\r
-  @param[in]  Private         Pointer to IPSEC_PRAVATE_DATA.\r
-\r
-**/\r
-VOID\r
-Ikev2ChildSaSessionReg (\r
-  IN IKEV2_CHILD_SA_SESSION    *ChildSaSession,\r
-  IN IPSEC_PRIVATE_DATA        *Private\r
-  )\r
-{\r
-  IKEV2_SESSION_COMMON         *SessionCommon;\r
-  IKEV2_CHILD_SA_SESSION       *OldChildSaSession;\r
-  IKEV2_SA_SESSION             *IkeSaSession;\r
-  EFI_STATUS                   Status;\r
-  UINT64                       Lifetime;\r
-\r
-  //\r
-  // Keep the IKE SA exclusive.\r
-  //\r
-  SessionCommon     = &ChildSaSession->SessionCommon;\r
-  IkeSaSession      = ChildSaSession->IkeSaSession;\r
-  OldChildSaSession = Ikev2ChildSaSessionRemove (\r
-                        &IkeSaSession->ChildSaEstablishSessionList,\r
-                        ChildSaSession->LocalPeerSpi,\r
-                        IKEV2_ESTABLISHED_CHILDSA_LIST\r
-                        );\r
-  if (OldChildSaSession != NULL) {\r
-    //\r
-    // Free the old one.\r
-    //\r
-    Ikev2ChildSaSessionFree (OldChildSaSession);\r
-  }\r
-\r
-  //\r
-  // Store the ready child SA into SAD.\r
-  //\r
-  Ikev2StoreSaData (ChildSaSession);\r
-\r
-  //\r
-  // Cleanup the fields of SessionCommon for processing.\r
-  //\r
-  Ikev2SessionCommonRefresh (SessionCommon);\r
-\r
-  //\r
-  // Insert the ready child SA session into established list.\r
-  //\r
-  Ikev2ChildSaSessionInsert (&IkeSaSession->ChildSaEstablishSessionList, ChildSaSession);\r
-\r
-  //\r
-  // Create a Notify event for the IKE SA life time counting.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Ikev2LifetimeNotify,\r
-                  SessionCommon,\r
-                  &SessionCommon->TimeoutEvent\r
-                  );\r
-  if (EFI_ERROR(Status)){\r
-    return ;\r
-  }\r
-\r
-  //\r
-  // Start to count the lifetime of the IKE SA.\r
-  //\r
-  if (ChildSaSession->Spd->Data->ProcessingPolicy->SaLifetime.HardLifetime != 0){\r
-    Lifetime = ChildSaSession->Spd->Data->ProcessingPolicy->SaLifetime.HardLifetime;\r
-  } else {\r
-    Lifetime = CHILD_SA_DEFAULT_LIFETIME;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  SessionCommon->TimeoutEvent,\r
-                  TimerRelative,\r
-                  MultU64x32(Lifetime, 10000000) // ms->100ns\r
-                  );\r
-  if (EFI_ERROR(Status)){\r
-    return ;\r
-  }\r
-\r
-  DEBUG ((\r
-    DEBUG_INFO,\r
-    "\n------ChildSa established and start to count down %d seconds lifetime\n",\r
-    Lifetime\r
-    ));\r
-\r
-  return ;\r
-}\r
-\r
-\r
-/**\r
-  This function find the Child SA by the specified SPI.\r
-\r
-  This functin find a ChildSA session by searching the ChildSaSessionlist of\r
-  the input IKEV2_SA_SESSION by specified MessageID.\r
-\r
-  @param[in]  SaSessionList      Pointer to List to be searched.\r
-  @param[in]  Spi                Specified SPI.\r
-\r
-  @return Pointer to IKEV2_CHILD_SA_SESSION or NULL.\r
-\r
-**/\r
-IKEV2_CHILD_SA_SESSION *\r
-Ikev2ChildSaSessionLookupBySpi (\r
-  IN LIST_ENTRY           *SaSessionList,\r
-  IN UINT32               Spi\r
-  )\r
-{\r
-  LIST_ENTRY              *Entry;\r
-  IKEV2_CHILD_SA_SESSION  *ChildSaSession;\r
-\r
-  NET_LIST_FOR_EACH (Entry, SaSessionList) {\r
-    ChildSaSession  = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
-\r
-    if (ChildSaSession->RemotePeerSpi == Spi || ChildSaSession->LocalPeerSpi == Spi) {\r
-      return ChildSaSession;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Insert a Child SA Session into the specified ChildSa list.\r
-\r
-  @param[in]  SaSessionList   Pointer to list to be inserted in.\r
-  @param[in]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION to be inserted.\r
-\r
-**/\r
-VOID\r
-Ikev2ChildSaSessionInsert (\r
-  IN LIST_ENTRY               *SaSessionList,\r
-  IN IKEV2_CHILD_SA_SESSION   *ChildSaSession\r
-  )\r
-{\r
- InsertTailList (SaSessionList, &ChildSaSession->ByIkeSa);\r
-}\r
-\r
-/**\r
-  Remove the IKEV2_CHILD_SA_SESSION from IkeSaSessionList.\r
-\r
-  @param[in]  SaSessionList      The SA Session List to be iterated.\r
-  @param[in]  Spi                Spi used to identified the IKEV2_CHILD_SA_SESSION.\r
-  @param[in]  ListType           The type of the List to indicate whether it is a\r
-                                 Established.\r
-\r
-  @return The point to IKEV2_CHILD_SA_SESSION or NULL.\r
-\r
-**/\r
-IKEV2_CHILD_SA_SESSION *\r
-Ikev2ChildSaSessionRemove (\r
-  IN LIST_ENTRY           *SaSessionList,\r
-  IN UINT32               Spi,\r
-  IN UINT8                ListType\r
-  )\r
-{\r
-  LIST_ENTRY              *Entry;\r
-  LIST_ENTRY              *NextEntry;\r
-  IKEV2_CHILD_SA_SESSION  *ChildSaSession;\r
-\r
-  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SaSessionList) {\r
-\r
-    if (ListType == IKEV2_ESTABLISHED_CHILDSA_LIST || ListType == IKEV2_ESTABLISHING_CHILDSA_LIST) {\r
-      ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
-    } else if (ListType == IKEV2_DELET_CHILDSA_LIST) {\r
-      ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_DEL_SA (Entry);\r
-    } else {\r
-      return NULL;\r
-    }\r
-\r
-    if (ChildSaSession->RemotePeerSpi == Spi || ChildSaSession->LocalPeerSpi == Spi) {\r
-      RemoveEntryList (Entry);\r
-      return ChildSaSession;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Free the memory located for the specified IKEV2_CHILD_SA_SESSION.\r
-\r
-  @param[in]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION.\r
-\r
-**/\r
-VOID\r
-Ikev2ChildSaSessionFree (\r
-  IN IKEV2_CHILD_SA_SESSION   *ChildSaSession\r
-  )\r
-{\r
-  IKEV2_SESSION_COMMON  *SessionCommon;\r
-\r
-  SessionCommon = &ChildSaSession->SessionCommon;\r
-  if (ChildSaSession->SaData != NULL) {\r
-    FreePool (ChildSaSession->SaData);\r
-  }\r
-\r
-  if (ChildSaSession->NiBlock != NULL) {\r
-    FreePool (ChildSaSession->NiBlock);\r
-  }\r
-\r
-  if (ChildSaSession->NrBlock != NULL) {\r
-    FreePool (ChildSaSession->NrBlock);\r
-  }\r
-\r
-  if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey != NULL) {\r
-    FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey);\r
-  }\r
-\r
-  if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey != NULL) {\r
-    FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey);\r
-  }\r
-\r
-  if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey != NULL) {\r
-    FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey);\r
-  }\r
-\r
-  if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey != NULL) {\r
-    FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey);\r
-  }\r
-\r
-  //\r
-  // Delete DhBuffer\r
-  //\r
-  Ikev2DhBufferFree (ChildSaSession->DhBuffer);\r
-\r
-  //\r
-  // Delete SpdSelector\r
-  //\r
-  if (ChildSaSession->SpdSelector != NULL) {\r
-    if (ChildSaSession->SpdSelector->LocalAddress != NULL) {\r
-      FreePool (ChildSaSession->SpdSelector->LocalAddress);\r
-    }\r
-    if (ChildSaSession->SpdSelector->RemoteAddress != NULL) {\r
-      FreePool (ChildSaSession->SpdSelector->RemoteAddress);\r
-    }\r
-    FreePool (ChildSaSession->SpdSelector);\r
-  }\r
-  Ikev2SaSessionCommonFree (SessionCommon);\r
-  FreePool (ChildSaSession);\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Delete the specified established Child SA.\r
-\r
-  This function delete the Child SA directly and don't send the Information Packet to\r
-  remote peer.\r
-\r
-  @param[in]  IkeSaSession   Pointer to a IKE SA Session used to be searched for.\r
-  @param[in]  Spi            SPI used to find the Child SA.\r
-\r
-  @retval     EFI_NOT_FOUND  Pointer of IKE SA Session is NULL.\r
-  @retval     EFI_NOT_FOUND  There is no specified Child SA related with the input\r
-                             SPI under this IKE SA Session.\r
-  @retval     EFI_SUCCESS    Delete the Child SA successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2ChildSaSilentDelete (\r
-  IN IKEV2_SA_SESSION       *IkeSaSession,\r
-  IN UINT32                 Spi\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_IPSEC_CONFIG_SELECTOR *Selector;\r
-  UINTN                     SelectorSize;\r
-  BOOLEAN                   IsLocalFound;\r
-  BOOLEAN                   IsRemoteFound;\r
-  UINT32                    LocalSpi;\r
-  UINT32                    RemoteSpi;\r
-  IKEV2_CHILD_SA_SESSION    *ChildSession;\r
-  EFI_IPSEC_CONFIG_SELECTOR *LocalSelector;\r
-  EFI_IPSEC_CONFIG_SELECTOR *RemoteSelector;\r
-  IPSEC_PRIVATE_DATA        *Private;\r
-\r
-  if (IkeSaSession == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  IsLocalFound    = FALSE;\r
-  IsRemoteFound   = FALSE;\r
-  ChildSession    = NULL;\r
-  LocalSelector   = NULL;\r
-  RemoteSelector  = NULL;\r
-\r
-  Private = IkeSaSession->SessionCommon.Private;\r
-\r
-  //\r
-  // Remove the Established SA from ChildSaEstablishlist.\r
-  //\r
-  ChildSession = Ikev2ChildSaSessionRemove(\r
-                   &(IkeSaSession->ChildSaEstablishSessionList),\r
-                   Spi,\r
-                   IKEV2_ESTABLISHED_CHILDSA_LIST\r
-                   );\r
-  if (ChildSession == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  LocalSpi  = ChildSession->LocalPeerSpi;\r
-  RemoteSpi = ChildSession->RemotePeerSpi;\r
-\r
-  SelectorSize  = sizeof (EFI_IPSEC_CONFIG_SELECTOR);\r
-  Selector      = AllocateZeroPool (SelectorSize);\r
-  if (Selector == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  while (1) {\r
-    Status = EfiIpSecConfigGetNextSelector (\r
-               &Private->IpSecConfig,\r
-               IPsecConfigDataTypeSad,\r
-               &SelectorSize,\r
-               Selector\r
-               );\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      FreePool (Selector);\r
-\r
-      Selector = AllocateZeroPool (SelectorSize);\r
-      if (Selector == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        break;\r
-      }\r
-\r
-      Status   = EfiIpSecConfigGetNextSelector (\r
-                   &Private->IpSecConfig,\r
-                   IPsecConfigDataTypeSad,\r
-                   &SelectorSize,\r
-                   Selector\r
-                   );\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-\r
-    if (Selector->SaId.Spi == RemoteSpi) {\r
-      //\r
-      // SPI is unique. There is only one SAD whose SPI is\r
-      // same with RemoteSpi.\r
-      //\r
-      IsRemoteFound   = TRUE;\r
-      RemoteSelector  = AllocateZeroPool (SelectorSize);\r
-      if (RemoteSelector == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        break;\r
-      }\r
-\r
-      CopyMem (RemoteSelector, Selector, SelectorSize);\r
-    }\r
-\r
-    if (Selector->SaId.Spi == LocalSpi) {\r
-      //\r
-      // SPI is unique. There is only one SAD whose SPI is\r
-      // same with LocalSpi.\r
-      //\r
-      IsLocalFound  = TRUE;\r
-      LocalSelector = AllocateZeroPool (SelectorSize);\r
-      if (LocalSelector == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        break;\r
-      }\r
-\r
-      CopyMem (LocalSelector, Selector, SelectorSize);\r
-    }\r
-  }\r
-  //\r
-  // Delete SA from the Variable.\r
-  //\r
-  if (IsLocalFound) {\r
-    Status = EfiIpSecConfigSetData (\r
-               &Private->IpSecConfig,\r
-               IPsecConfigDataTypeSad,\r
-               LocalSelector,\r
-               NULL,\r
-               NULL\r
-               );\r
-  }\r
-\r
-  if (IsRemoteFound) {\r
-    Status = EfiIpSecConfigSetData (\r
-               &Private->IpSecConfig,\r
-               IPsecConfigDataTypeSad,\r
-               RemoteSelector,\r
-               NULL,\r
-               NULL\r
-               );\r
-\r
-  }\r
-\r
-  DEBUG (\r
-    (DEBUG_INFO,\r
-    "\n------IKEV2 deleted ChildSa(local spi, remote spi):(0x%x, 0x%x)------\n",\r
-    LocalSpi,\r
-    RemoteSpi)\r
-    );\r
-  Ikev2ChildSaSessionFree (ChildSession);\r
-\r
-  if (RemoteSelector != NULL) {\r
-    FreePool (RemoteSelector);\r
-  }\r
-\r
-  if (LocalSelector != NULL) {\r
-    FreePool (LocalSelector);\r
-  }\r
-\r
-  if (Selector != NULL) {\r
-    FreePool (Selector);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Free the specified DhBuffer.\r
-\r
-  @param[in] DhBuffer   Pointer to IKEV2_DH_BUFFER to be freed.\r
-\r
-**/\r
-VOID\r
-Ikev2DhBufferFree (\r
-  IKEV2_DH_BUFFER *DhBuffer\r
-)\r
-{\r
-  if (DhBuffer != NULL) {\r
-    if (DhBuffer->GxBuffer != NULL) {\r
-      FreePool (DhBuffer->GxBuffer);\r
-    }\r
-    if (DhBuffer->GyBuffer != NULL) {\r
-      FreePool (DhBuffer->GyBuffer);\r
-    }\r
-    if (DhBuffer->GxyBuffer != NULL) {\r
-      FreePool (DhBuffer->GxyBuffer);\r
-    }\r
-    if (DhBuffer->DhContext != NULL) {\r
-      IpSecCryptoIoFreeDh (&DhBuffer->DhContext);\r
-    }\r
-    FreePool (DhBuffer);\r
-  }\r
-}\r
-\r
-/**\r
-  This function is to parse a request IKE packet and return its request type.\r
-  The request type is one of IKE CHILD SA creation, IKE SA rekeying and\r
-  IKE CHILD SA rekeying.\r
-\r
-  @param[in] IkePacket  IKE packet to be prased.\r
-\r
-  return the type of the IKE packet.\r
-\r
-**/\r
-IKEV2_CREATE_CHILD_REQUEST_TYPE\r
-Ikev2ChildExchangeRequestType(\r
-  IN IKE_PACKET               *IkePacket\r
-  )\r
-{\r
-  BOOLEAN       Flag;\r
-  LIST_ENTRY    *Entry;\r
-  IKE_PAYLOAD   *IkePayload;\r
-\r
-  Flag            = FALSE;\r
-\r
-  NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
-    IkePayload  = IKE_PAYLOAD_BY_PACKET (Entry);\r
-    if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) {\r
-      //\r
-      // Packet with Ts Payload means it is for either CHILD_SA_CREATE or CHILD_SA_REKEY.\r
-      //\r
-      Flag = TRUE;\r
-    }\r
-    if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NOTIFY) {\r
-      if (((IKEV2_NOTIFY*)IkePayload)->MessageType == IKEV2_NOTIFICATION_REKEY_SA) {\r
-        //\r
-        // If notify payload with REKEY_SA message type, the IkePacket is for\r
-        // rekeying Child SA.\r
-        //\r
-        return IkeRequestTypeRekeyChildSa;\r
-      }\r
-    }\r
-  };\r
-\r
-  if (!Flag){\r
-    //\r
-    // The Create Child Exchange is for IKE SA rekeying.\r
-    //\r
-    return IkeRequestTypeRekeyIkeSa;\r
-  } else {\r
-    //\r
-    // If the Notify payloaad with transport mode message type, the IkePacket is\r
-    // for create Child SA.\r
-    //\r
-    return IkeRequestTypeCreateChildSa;\r
-  }\r
-}\r
-\r
-/**\r
-  Associate a SPD selector to the Child SA Session.\r
-\r
-  This function is called when the Child SA is not the first child SA of its\r
-  IKE SA. It associate a SPD to this Child SA.\r
-\r
-  @param[in, out]  ChildSaSession     Pointer to the Child SA Session to be associated to\r
-                                      a SPD selector.\r
-\r
-  @retval EFI_SUCCESS        Associate one SPD selector to this Child SA Session successfully.\r
-  @retval EFI_NOT_FOUND      Can't find the related SPD selector.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2ChildSaAssociateSpdEntry (\r
-  IN OUT IKEV2_CHILD_SA_SESSION *ChildSaSession\r
-  )\r
-{\r
-  IpSecVisitConfigData (IPsecConfigDataTypeSpd, Ikev2MatchSpdEntry, ChildSaSession);\r
-  if (ChildSaSession->Spd != NULL) {\r
-    return EFI_SUCCESS;\r
-  } else {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-}\r
-\r
-\r
-\r
-/**\r
-  Validate the IKE header of received IKE packet.\r
-\r
-  @param[in]   IkeSaSession  Pointer to IKEV2_SA_SESSION related to this IKE packet.\r
-  @param[in]   IkeHdr        Pointer to IKE header of received IKE packet.\r
-\r
-  @retval TRUE   If the IKE header is valid.\r
-  @retval FALSE  If the IKE header is invalid.\r
-\r
-**/\r
-BOOLEAN\r
-Ikev2ValidateHeader (\r
-  IN IKEV2_SA_SESSION         *IkeSaSession,\r
-  IN IKE_HEADER               *IkeHdr\r
-  )\r
-{\r
-\r
-  IKEV2_SESSION_STATE State;\r
-\r
-  State = IkeSaSession->SessionCommon.State;\r
-  if (State == IkeStateInit) {\r
-    //\r
-    // For the IKE Initial Exchange, the MessagId should be zero.\r
-    //\r
-    if (IkeHdr->MessageId != 0) {\r
-      return FALSE;\r
-    }\r
-  } else {\r
-    if (State == IkeStateAuth) {\r
-      if (IkeHdr->MessageId != 1) {\r
-        return FALSE;\r
-      }\r
-    }\r
-    if (IkeHdr->InitiatorCookie != IkeSaSession->InitiatorCookie ||\r
-        IkeHdr->ResponderCookie != IkeSaSession->ResponderCookie\r
-        ) {\r
-      //\r
-      // TODO: send notification INVALID-COOKIE\r
-      //\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Information Exchagne and Create Child Exchange can be started from each part.\r
-  //\r
-  if (IkeHdr->ExchangeType != IKEV2_EXCHANGE_TYPE_INFO &&\r
-      IkeHdr->ExchangeType != IKEV2_EXCHANGE_TYPE_CREATE_CHILD\r
-      ) {\r
-    if (IkeSaSession->SessionCommon.IsInitiator) {\r
-      if (IkeHdr->InitiatorCookie != IkeSaSession->InitiatorCookie) {\r
-        //\r
-        // TODO: send notification INVALID-COOKIE\r
-        //\r
-        return FALSE;\r
-      }\r
-      if (IkeHdr->Flags != IKE_HEADER_FLAGS_RESPOND) {\r
-        return FALSE;\r
-      }\r
-    } else {\r
-      if (IkeHdr->Flags != IKE_HEADER_FLAGS_INIT) {\r
-        return FALSE;\r
-      }\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Create and intialize IKEV2_SA_DATA for speicifed IKEV2_SESSION_COMMON.\r
-\r
-  This function will be only called by the initiator. The responder's IKEV2_SA_DATA\r
-  will be generated during parsed the initiator packet.\r
-\r
-  @param[in]  SessionCommon  Pointer to IKEV2_SESSION_COMMON related to.\r
-\r
-  @retval a Pointer to a new IKEV2_SA_DATA or NULL.\r
-\r
-**/\r
-IKEV2_SA_DATA *\r
-Ikev2InitializeSaData (\r
-  IN IKEV2_SESSION_COMMON     *SessionCommon\r
-  )\r
-{\r
-  IKEV2_CHILD_SA_SESSION      *ChildSaSession;\r
-  IKEV2_SA_DATA               *SaData;\r
-  IKEV2_PROPOSAL_DATA         *ProposalData;\r
-  IKEV2_TRANSFORM_DATA        *TransformData;\r
-  IKE_SA_ATTRIBUTE            *Attribute;\r
-\r
-  ASSERT (SessionCommon != NULL);\r
-  //\r
-  // TODO: Remove the hard code of the support Alogrithm. Those data should be\r
-  // get from the SPD/PAD data.\r
-  //\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    SaData = AllocateZeroPool (\r
-               sizeof (IKEV2_SA_DATA) +\r
-               sizeof (IKEV2_PROPOSAL_DATA) * 2 +\r
-               sizeof (IKEV2_TRANSFORM_DATA) * 4 * 2\r
-               );\r
-  } else {\r
-    SaData = AllocateZeroPool (\r
-               sizeof (IKEV2_SA_DATA) +\r
-               sizeof (IKEV2_PROPOSAL_DATA) * 2 +\r
-               sizeof (IKEV2_TRANSFORM_DATA) * 3 * 2\r
-               );\r
-  }\r
-  if (SaData == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // First proposal payload: 3DES + SHA1 + DH\r
-  //\r
-  SaData->NumProposals          = 2;\r
-  ProposalData                  = (IKEV2_PROPOSAL_DATA *) (SaData + 1);\r
-  ProposalData->ProposalIndex   = 1;\r
-\r
-  //\r
-  // If SA data for IKE_SA_INIT exchage, contains 4 transforms. If SA data for\r
-  // IKE_AUTH exchange contains 3 transforms.\r
-  //\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    ProposalData->NumTransforms   = 4;\r
-  } else {\r
-    ProposalData->NumTransforms   = 3;\r
-  }\r
-\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    ProposalData->ProtocolId    = IPSEC_PROTO_ISAKMP;\r
-  } else {\r
-    ChildSaSession              = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    ProposalData->ProtocolId    = IPSEC_PROTO_IPSEC_ESP;\r
-    ProposalData->Spi           = AllocateZeroPool (sizeof (ChildSaSession->LocalPeerSpi));\r
-    if (ProposalData->Spi == NULL) {\r
-      FreePool (SaData);\r
-      return NULL;\r
-    }\r
-\r
-    CopyMem (\r
-      ProposalData->Spi,\r
-      &ChildSaSession->LocalPeerSpi,\r
-      sizeof(ChildSaSession->LocalPeerSpi)\r
-    );\r
-  }\r
-\r
-  //\r
-  // Set transform attribute for Encryption Algorithm - 3DES\r
-  //\r
-  TransformData                 = (IKEV2_TRANSFORM_DATA *) (ProposalData + 1);\r
-  TransformData->TransformIndex = 0;\r
-  TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_ENCR;\r
-  TransformData->TransformId    = IKEV2_TRANSFORM_ID_ENCR_3DES;\r
-\r
-  //\r
-  // Set transform attribute for Integrity Algorithm - SHA1_96\r
-  //\r
-  TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-  TransformData->TransformIndex = 1;\r
-  TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_INTEG;\r
-  TransformData->TransformId    = IKEV2_TRANSFORM_ID_AUTH_HMAC_SHA1_96;\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    //\r
-    // Set transform attribute for Pseduo-Random Function - HAMC_SHA1\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 2;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_PRF;\r
-    TransformData->TransformId    = IKEV2_TRANSFORM_ID_PRF_HMAC_SHA1;\r
-  }\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    //\r
-    // Set transform attribute for DH Group - DH 1024\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 3;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_DH;\r
-    TransformData->TransformId    = IKEV2_TRANSFORM_ID_DH_1024MODP;\r
-  } else {\r
-    //\r
-    // Transform type for Extended Sequence Numbers. Currently not support Extended\r
-    // Sequence Number.\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 2;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_ESN;\r
-    TransformData->TransformId    = 0;\r
-  }\r
-\r
-  //\r
-  // Second proposal payload: 3DES + SHA1 + DH\r
-  //\r
-  ProposalData                  = (IKEV2_PROPOSAL_DATA *) (TransformData + 1);\r
-  ProposalData->ProposalIndex   = 2;\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    ProposalData->ProtocolId      = IPSEC_PROTO_ISAKMP;\r
-    ProposalData->NumTransforms   = 4;\r
-  } else {\r
-\r
-    ChildSaSession              = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    ProposalData->ProtocolId    = IPSEC_PROTO_IPSEC_ESP;\r
-    ProposalData->NumTransforms = 3;\r
-    ProposalData->Spi           = AllocateZeroPool (sizeof (ChildSaSession->LocalPeerSpi));\r
-    if (ProposalData->Spi == NULL) {\r
-      FreePool (((IKEV2_PROPOSAL_DATA *) (SaData + 1))->Spi);\r
-      FreePool (SaData);\r
-      return NULL;\r
-    }\r
-\r
-    CopyMem (\r
-      ProposalData->Spi,\r
-      &ChildSaSession->LocalPeerSpi,\r
-      sizeof(ChildSaSession->LocalPeerSpi)\r
-    );\r
-  }\r
-\r
-  //\r
-  // Set transform attribute for Encryption Algorithm - AES-CBC\r
-  //\r
-  TransformData                 = (IKEV2_TRANSFORM_DATA *) (ProposalData + 1);\r
-  TransformData->TransformIndex = 0;\r
-  TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_ENCR;\r
-  TransformData->TransformId    = IKEV2_TRANSFORM_ID_ENCR_AES_CBC;\r
-  Attribute                     = &TransformData->Attribute;\r
-  Attribute->AttrType           = IKEV2_ATTRIBUTE_TYPE_KEYLEN;\r
-  Attribute->Attr.AttrLength    = (UINT16) (8 * IpSecGetEncryptKeyLength (IKEV2_TRANSFORM_ID_ENCR_AES_CBC));\r
-\r
-  //\r
-  // Set transform attribute for Integrity Algorithm - SHA1_96\r
-  //\r
-  TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-  TransformData->TransformIndex = 1;\r
-  TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_INTEG;\r
-  TransformData->TransformId    = IKEV2_TRANSFORM_ID_AUTH_HMAC_SHA1_96;\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    //\r
-    // Set transform attribute for Pseduo-Random Function - HAMC_SHA1\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 2;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_PRF;\r
-    TransformData->TransformId    = IKEV2_TRANSFORM_ID_PRF_HMAC_SHA1;\r
-  }\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    //\r
-    // Set transform attrbiute for DH Group - DH-1024\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 3;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_DH;\r
-    TransformData->TransformId    = IKEV2_TRANSFORM_ID_DH_1024MODP;\r
-  } else {\r
-    //\r
-    // Transform type for Extended Sequence Numbers. Currently not support Extended\r
-    // Sequence Number.\r
-    //\r
-    TransformData                 = (IKEV2_TRANSFORM_DATA *) (TransformData + 1);\r
-    TransformData->TransformIndex = 2;\r
-    TransformData->TransformType  = IKEV2_TRANSFORM_TYPE_ESN;\r
-    TransformData->TransformId    = 0;\r
-  }\r
-\r
-  return SaData;\r
-}\r
-\r
-/**\r
-  Store the SA into SAD.\r
-\r
-  @param[in]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION.\r
-\r
-**/\r
-VOID\r
-Ikev2StoreSaData (\r
-  IN IKEV2_CHILD_SA_SESSION   *ChildSaSession\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_IPSEC_SA_ID             SaId;\r
-  EFI_IPSEC_SA_DATA2           SaData;\r
-  IKEV2_SESSION_COMMON        *SessionCommon;\r
-  IPSEC_PRIVATE_DATA          *Private;\r
-  UINT32                      TempAddressCount;\r
-  EFI_IP_ADDRESS_INFO         *TempAddressInfo;\r
-\r
-  SessionCommon             = &ChildSaSession->SessionCommon;\r
-  Private                   = SessionCommon->Private;\r
-\r
-  ZeroMem (&SaId, sizeof (EFI_IPSEC_SA_ID));\r
-  ZeroMem (&SaData, sizeof (EFI_IPSEC_SA_DATA2));\r
-\r
-  //\r
-  // Create a SpdSelector. In this implementation, one SPD represents\r
-  // 2 direction traffic, so in here, there needs to reverse the local address\r
-  // and remote address for Remote Peer's SA, then reverse again for the locate\r
-  // SA.\r
-  //\r
-  TempAddressCount = ChildSaSession->SpdSelector->LocalAddressCount;\r
-  TempAddressInfo  = ChildSaSession->SpdSelector->LocalAddress;\r
-\r
-  ChildSaSession->SpdSelector->LocalAddressCount = ChildSaSession->SpdSelector->RemoteAddressCount;\r
-  ChildSaSession->SpdSelector->LocalAddress      = ChildSaSession->SpdSelector->RemoteAddress;\r
-\r
-  ChildSaSession->SpdSelector->RemoteAddress     = TempAddressInfo;\r
-  ChildSaSession->SpdSelector->RemoteAddressCount= TempAddressCount;\r
-\r
-  //\r
-  // Set the SaId and SaData.\r
-  //\r
-  SaId.Spi                 = ChildSaSession->LocalPeerSpi;\r
-  SaId.Proto               = EfiIPsecESP;\r
-  SaData.AntiReplayWindows = 16;\r
-  SaData.SNCount           = 0;\r
-  SaData.Mode              = ChildSaSession->Spd->Data->ProcessingPolicy->Mode;\r
-\r
-  //\r
-  // If it is tunnel mode, should add the TunnelDest and TunnelSource for SaData.\r
-  //\r
-  if (SaData.Mode == EfiIPsecTunnel) {\r
-    CopyMem (\r
-      &SaData.TunnelSourceAddress,\r
-      &ChildSaSession->Spd->Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,\r
-      sizeof (EFI_IP_ADDRESS)\r
-      );\r
-    CopyMem (\r
-      &SaData.TunnelDestinationAddress,\r
-      &ChildSaSession->Spd->Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress,\r
-      sizeof (EFI_IP_ADDRESS)\r
-      );\r
-  }\r
-\r
-  CopyMem (&SaId.DestAddress, &ChildSaSession->SessionCommon.LocalPeerIp, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&SaData.AlgoInfo, &ChildSaSession->ChildKeymats.LocalPeerInfo, sizeof (EFI_IPSEC_ALGO_INFO));\r
-  SaData.SpdSelector = ChildSaSession->SpdSelector;\r
-\r
-  //\r
-  // Store the remote SA into SAD.\r
-  //\r
-  Status = EfiIpSecConfigSetData (\r
-             &Private->IpSecConfig,\r
-             IPsecConfigDataTypeSad,\r
-             (EFI_IPSEC_CONFIG_SELECTOR *) &SaId,\r
-             &SaData,\r
-             NULL\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Store the local SA into SAD.\r
-  //\r
-  ChildSaSession->SpdSelector->RemoteAddressCount = ChildSaSession->SpdSelector->LocalAddressCount;\r
-  ChildSaSession->SpdSelector->RemoteAddress      = ChildSaSession->SpdSelector->LocalAddress;\r
-\r
-  ChildSaSession->SpdSelector->LocalAddress       = TempAddressInfo;\r
-  ChildSaSession->SpdSelector->LocalAddressCount  = TempAddressCount;\r
-\r
-  SaId.Spi = ChildSaSession->RemotePeerSpi;\r
-\r
-  CopyMem (&SaId.DestAddress, &ChildSaSession->SessionCommon.RemotePeerIp, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&SaData.AlgoInfo, &ChildSaSession->ChildKeymats.RemotePeerInfo, sizeof (EFI_IPSEC_ALGO_INFO));\r
-  SaData.SpdSelector = ChildSaSession->SpdSelector;\r
-\r
-  //\r
-  // If it is tunnel mode, should add the TunnelDest and TunnelSource for SaData.\r
-  //\r
-  if (SaData.Mode == EfiIPsecTunnel) {\r
-    CopyMem (\r
-      &SaData.TunnelSourceAddress,\r
-      &ChildSaSession->Spd->Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress,\r
-      sizeof (EFI_IP_ADDRESS)\r
-      );\r
-    CopyMem (\r
-      &SaData.TunnelDestinationAddress,\r
-      &ChildSaSession->Spd->Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,\r
-      sizeof (EFI_IP_ADDRESS)\r
-      );\r
-  }\r
-\r
-  Status = EfiIpSecConfigSetData (\r
-             &Private->IpSecConfig,\r
-             IPsecConfigDataTypeSad,\r
-             (EFI_IPSEC_CONFIG_SELECTOR *) &SaId,\r
-             &SaData,\r
-             NULL\r
-             );\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
-/**\r
-  Call back function of the IKE life time is over.\r
-\r
-  This function will mark the related IKE SA Session as deleting and trigger a\r
-  Information negotiation.\r
-\r
-  @param[in]    Event     The signaled Event.\r
-  @param[in]    Context   Pointer to data passed by caller.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Ikev2LifetimeNotify (\r
-  IN EFI_EVENT                Event,\r
-  IN VOID                     *Context\r
-  )\r
-{\r
-  IKEV2_SA_SESSION            *IkeSaSession;\r
-  IKEV2_CHILD_SA_SESSION      *ChildSaSession;\r
-  IKEV2_SESSION_COMMON        *SessionCommon;\r
-\r
-  ASSERT (Context != NULL);\r
-  SessionCommon = (IKEV2_SESSION_COMMON *) Context;\r
-\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-    IkeSaSession = IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    DEBUG ((\r
-      DEBUG_INFO,\r
-      "\n---IkeSa Lifetime is out(cookie_i, cookie_r):(0x%lx, 0x%lx)---\n",\r
-      IkeSaSession->InitiatorCookie,\r
-      IkeSaSession->ResponderCookie\r
-      ));\r
-\r
-    //\r
-    // Change the  IKE SA Session's State to IKE_STATE_SA_DELETING.\r
-    //\r
-    IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateSaDeleting);\r
-    IkeSaSession->SessionCommon.State = IkeStateSaDeleting;\r
-\r
-  } else {\r
-    ChildSaSession = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    IkeSaSession   = ChildSaSession->IkeSaSession;\r
-\r
-    //\r
-    // Link the timeout child SA to the DeleteSaList.\r
-    //\r
-    InsertTailList (&IkeSaSession->DeleteSaList, &ChildSaSession->ByDelete);\r
-\r
-    //\r
-    // Change the Child SA Session's State to IKE_STATE_SA_DELETING.\r
-    //\r
-    DEBUG ((\r
-      DEBUG_INFO,\r
-      "\n------ChildSa Lifetime is out(SPI):(0x%x)------\n",\r
-      ChildSaSession->LocalPeerSpi\r
-      ));\r
-  }\r
-\r
-  //\r
-  // TODO: Send the delete info packet or delete silently\r
-  //\r
-  mIkev2Exchange.NegotiateInfo ((UINT8 *) IkeSaSession, NULL);\r
-}\r
-\r
-/**\r
-  This function will be called if the TimeOut Event is signaled.\r
-\r
-  @param[in]  Event      The signaled Event.\r
-  @param[in]  Context    The data passed by caller.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Ikev2ResendNotify (\r
-  IN EFI_EVENT                 Event,\r
-  IN VOID                      *Context\r
-  )\r
-{\r
-  IPSEC_PRIVATE_DATA           *Private;\r
-  IKEV2_SA_SESSION             *IkeSaSession;\r
-  IKEV2_CHILD_SA_SESSION       *ChildSaSession;\r
-  IKEV2_SESSION_COMMON         *SessionCommon;\r
-  LIST_ENTRY                   *ChildSaEntry;\r
-  UINT8                        Value;\r
-  EFI_STATUS                   Status;\r
-\r
-  ASSERT (Context != NULL);\r
-  IkeSaSession   = NULL;\r
-  ChildSaSession = NULL;\r
-  SessionCommon  = (IKEV2_SESSION_COMMON *) Context;\r
-  Private        = SessionCommon->Private;\r
-\r
-  //\r
-  // Remove the SA session from the processing list if exceed the max retry.\r
-  //\r
-  if (SessionCommon->RetryCount > IKE_MAX_RETRY) {\r
-    if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-      IkeSaSession = IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-      if (IkeSaSession->SessionCommon.State == IkeStateSaDeleting) {\r
-\r
-        //\r
-        // If the IkeSaSession is initiator, delete all its Child SAs before removing IKE SA.\r
-        // If the IkesaSession is responder, all ChildSa has been remove in Ikev2HandleInfo();\r
-        //\r
-        for (ChildSaEntry = IkeSaSession->ChildSaEstablishSessionList.ForwardLink;\r
-             ChildSaEntry != &IkeSaSession->ChildSaEstablishSessionList;\r
-        ) {\r
-          ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ChildSaEntry);\r
-          //\r
-          // Move to next ChildSa Entry.\r
-          //\r
-          ChildSaEntry = ChildSaEntry->ForwardLink;\r
-          //\r
-          // Delete LocalSpi & RemoteSpi and remove the ChildSaSession from the\r
-          // EstablishedChildSaList.\r
-          //\r
-          Ikev2ChildSaSilentDelete (IkeSaSession, ChildSaSession->LocalPeerSpi);\r
-        }\r
-\r
-        //\r
-        // If the IKE SA Delete Payload wasn't sent out successfully, Delete it from the EstablishedList.\r
-        //\r
-        Ikev2SaSessionRemove (&Private->Ikev2EstablishedList, &SessionCommon->RemotePeerIp);\r
-\r
-        if (Private != NULL && Private->IsIPsecDisabling) {\r
-            //\r
-            // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in\r
-            // IPsec status variable.\r
-            //\r
-            if (IsListEmpty (&Private->Ikev1EstablishedList) && IsListEmpty (&Private->Ikev2EstablishedList)) {\r
-              Value = IPSEC_STATUS_DISABLED;\r
-              Status = gRT->SetVariable (\r
-                              IPSECCONFIG_STATUS_NAME,\r
-                              &gEfiIpSecConfigProtocolGuid,\r
-                              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                              sizeof (Value),\r
-                              &Value\r
-                              );\r
-              if (!EFI_ERROR (Status)) {\r
-                //\r
-                // Set the Disabled Flag in Private data.\r
-                //\r
-                Private->IpSec.DisabledFlag = TRUE;\r
-                Private->IsIPsecDisabling   = FALSE;\r
-              }\r
-            }\r
-          }\r
-      } else {\r
-        Ikev2SaSessionRemove (&Private->Ikev2SessionList, &SessionCommon->RemotePeerIp);\r
-      }\r
-      Ikev2SaSessionFree (IkeSaSession);\r
-\r
-    } else {\r
-\r
-      //\r
-      // If the packet sent by Child SA.\r
-      //\r
-      ChildSaSession = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-      IkeSaSession   = ChildSaSession->IkeSaSession;\r
-      if (ChildSaSession->SessionCommon.State == IkeStateSaDeleting) {\r
-\r
-        //\r
-        // Established Child SA should be remove from the SAD entry and\r
-        // DeleteList. The function of Ikev2DeleteChildSaSilent() will remove\r
-        // the childSA from the IkeSaSession->ChildSaEstablishedList. So there\r
-        // is no need to remove it here.\r
-        //\r
-        Ikev2ChildSaSilentDelete (IkeSaSession, ChildSaSession->LocalPeerSpi);\r
-        Ikev2ChildSaSessionRemove (\r
-          &IkeSaSession->DeleteSaList,\r
-          ChildSaSession->LocalPeerSpi,\r
-          IKEV2_DELET_CHILDSA_LIST\r
-          );\r
-      } else {\r
-        Ikev2ChildSaSessionRemove (\r
-          &IkeSaSession->ChildSaSessionList,\r
-          ChildSaSession->LocalPeerSpi,\r
-          IKEV2_ESTABLISHING_CHILDSA_LIST\r
-          );\r
-      }\r
-\r
-      Ikev2ChildSaSessionFree (ChildSaSession);\r
-    }\r
-    return ;\r
-  }\r
-\r
-  //\r
-  // Increase the retry count.\r
-  //\r
-  SessionCommon->RetryCount++;\r
-  DEBUG ((DEBUG_INFO, ">>>Resending the last packet ...\n"));\r
-\r
-  //\r
-  // Resend the last packet.\r
-  //\r
-  Ikev2SendIkePacket (\r
-    SessionCommon->UdpService,\r
-    (UINT8*)SessionCommon,\r
-    SessionCommon->LastSentPacket,\r
-    0\r
-    );\r
-}\r
-\r
-/**\r
-  Copy ChildSaSession->Spd->Selector to ChildSaSession->SpdSelector.\r
-\r
-  ChildSaSession->SpdSelector stores the real Spdselector for its SA. Sometime,\r
-  the SpdSelector in ChildSaSession is more accurated or the scope is smaller\r
-  than the one in ChildSaSession->Spd, especially for the tunnel mode.\r
-\r
-  @param[in, out]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION related to.\r
-\r
-  @retval EFI_SUCCESS            The operation complete successfully.\r
-  @retval EFI_OUT_OF_RESOURCES   If the required resource can't be allocated.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2ChildSaSessionSpdSelectorCreate (\r
-  IN OUT IKEV2_CHILD_SA_SESSION *ChildSaSession\r
-  )\r
-{\r
-  EFI_STATUS          Status;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  if (ChildSaSession->Spd != NULL && ChildSaSession->Spd->Selector != NULL) {\r
-    if (ChildSaSession->SpdSelector == NULL) {\r
-      ChildSaSession->SpdSelector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR));\r
-      if (ChildSaSession->SpdSelector == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        return Status;\r
-      }\r
-    }\r
-    CopyMem (\r
-      ChildSaSession->SpdSelector,\r
-      ChildSaSession->Spd->Selector,\r
-      sizeof (EFI_IPSEC_SPD_SELECTOR)\r
-      );\r
-    ChildSaSession->SpdSelector->RemoteAddress = AllocateCopyPool (\r
-                                                   ChildSaSession->Spd->Selector->RemoteAddressCount *\r
-                                                   sizeof (EFI_IP_ADDRESS_INFO),\r
-                                                   ChildSaSession->Spd->Selector->RemoteAddress\r
-                                                   );\r
-    if (ChildSaSession->SpdSelector->RemoteAddress == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-\r
-      FreePool (ChildSaSession->SpdSelector);\r
-\r
-      return Status;\r
-    }\r
-\r
-    ChildSaSession->SpdSelector->LocalAddress = AllocateCopyPool (\r
-                                                  ChildSaSession->Spd->Selector->LocalAddressCount *\r
-                                                  sizeof (EFI_IP_ADDRESS_INFO),\r
-                                                  ChildSaSession->Spd->Selector->LocalAddress\r
-                                                  );\r
-    if (ChildSaSession->SpdSelector->LocalAddress == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-\r
-      FreePool (ChildSaSession->SpdSelector->RemoteAddress);\r
-\r
-      FreePool (ChildSaSession->SpdSelector);\r
-\r
-      return Status;\r
-    }\r
-\r
-    ChildSaSession->SpdSelector->RemoteAddressCount = ChildSaSession->Spd->Selector->RemoteAddressCount;\r
-    ChildSaSession->SpdSelector->LocalAddressCount = ChildSaSession->Spd->Selector->LocalAddressCount;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Generate a ChildSa Session and insert it into related IkeSaSession.\r
-\r
-  @param[in]  IkeSaSession    Pointer to related IKEV2_SA_SESSION.\r
-  @param[in]  UdpService      Pointer to related IKE_UDP_SERVICE.\r
-\r
-  @return pointer of IKEV2_CHILD_SA_SESSION.\r
-\r
-**/\r
-IKEV2_CHILD_SA_SESSION *\r
-Ikev2ChildSaSessionCreate (\r
-  IN IKEV2_SA_SESSION   *IkeSaSession,\r
-  IN IKE_UDP_SERVICE     *UdpService\r
-  )\r
-{\r
-  IKEV2_CHILD_SA_SESSION    *ChildSaSession;\r
-  IKEV2_SESSION_COMMON      *ChildSaCommon;\r
-\r
-  //\r
-  // Create a new ChildSaSession.Insert it into processing list and initiate the common parameters.\r
-  //\r
-  ChildSaSession = Ikev2ChildSaSessionAlloc (UdpService, IkeSaSession);\r
-  if (ChildSaSession == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Set the specific parameters.\r
-  //\r
-  ChildSaSession->Spd        = IkeSaSession->Spd;\r
-  ChildSaCommon              = &ChildSaSession->SessionCommon;\r
-  ChildSaCommon->IsInitiator = IkeSaSession->SessionCommon.IsInitiator;\r
-  if (IkeSaSession->SessionCommon.State == IkeStateAuth) {\r
-    ChildSaCommon->State     = IkeStateAuth;\r
-    IKEV2_DUMP_STATE (ChildSaCommon->State, IkeStateAuth);\r
-  } else {\r
-    ChildSaCommon->State     = IkeStateCreateChild;\r
-    IKEV2_DUMP_STATE (ChildSaCommon->State, IkeStateCreateChild);\r
-  }\r
-\r
-  //\r
-  // If SPD->Selector is not NULL, copy it to the ChildSaSession->SpdSelector.\r
-  // The ChildSaSession->SpdSelector might be changed after the traffic selector\r
-  // negoniation and it will be copied into the SAData after ChildSA established.\r
-  //\r
-  if (EFI_ERROR (Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession))) {\r
-    Ikev2ChildSaSessionFree (ChildSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Copy first NiBlock and NrBlock to ChildSa Session\r
-  //\r
-  ChildSaSession->NiBlock   = AllocateZeroPool (IkeSaSession->NiBlkSize);\r
-  if (ChildSaSession->NiBlock == NULL) {\r
-    Ikev2ChildSaSessionFree (ChildSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  ChildSaSession->NiBlkSize = IkeSaSession->NiBlkSize;\r
-  CopyMem (ChildSaSession->NiBlock, IkeSaSession->NiBlock, IkeSaSession->NiBlkSize);\r
-\r
-  ChildSaSession->NrBlock   = AllocateZeroPool (IkeSaSession->NrBlkSize);\r
-  if (ChildSaSession->NrBlock == NULL) {\r
-    Ikev2ChildSaSessionFree (ChildSaSession);\r
-    return NULL;\r
-  }\r
-\r
-  ChildSaSession->NrBlkSize = IkeSaSession->NrBlkSize;\r
-  CopyMem (ChildSaSession->NrBlock, IkeSaSession->NrBlock, IkeSaSession->NrBlkSize);\r
-\r
-  //\r
-  //  Only if the Create Child SA is called for the IKE_INIT Exchange and\r
-  //  IkeSaSession is initiator (Only Initiator's SPD is not NULL), Set the\r
-  //  Traffic Selectors related information here.\r
-  //\r
-  if (IkeSaSession->SessionCommon.State == IkeStateAuth && IkeSaSession->Spd != NULL) {\r
-    ChildSaSession->ProtoId = IkeSaSession->Spd->Selector->NextLayerProtocol;\r
-    ChildSaSession->LocalPort = IkeSaSession->Spd->Selector->LocalPort;\r
-    ChildSaSession->RemotePort = IkeSaSession->Spd->Selector->RemotePort;\r
-  }\r
-\r
-  //\r
-  // Insert the new ChildSaSession into processing child SA list.\r
-  //\r
-  Ikev2ChildSaSessionInsert (&IkeSaSession->ChildSaSessionList, ChildSaSession);\r
-  return ChildSaSession;\r
-}\r
-\r
-/**\r
-  Check if the SPD is related to the input Child SA Session.\r
-\r
-  This function is the subfunction of Ikev1AssociateSpdEntry(). It is the call\r
-  back function of IpSecVisitConfigData().\r
-\r
-\r
-  @param[in]  Type               Type of the input Config Selector.\r
-  @param[in]  Selector           Pointer to the Configure Selector to be checked.\r
-  @param[in]  Data               Pointer to the Configure Selector's Data passed\r
-                                 from the caller.\r
-  @param[in]  SelectorSize       The buffer size of Selector.\r
-  @param[in]  DataSize           The buffer size of the Data.\r
-  @param[in]  Context            The data passed from the caller. It is a Child\r
-                                 SA Session in this context.\r
-\r
-  @retval EFI_SUCCESS        The SPD Selector is not related to the Child SA Session.\r
-  @retval EFI_ABORTED        The SPD Selector is related to the Child SA session and\r
-                             set the ChildSaSession->Spd to point to this SPD Selector.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2MatchSpdEntry (\r
-  IN EFI_IPSEC_CONFIG_DATA_TYPE     Type,\r
-  IN EFI_IPSEC_CONFIG_SELECTOR      *Selector,\r
-  IN VOID                           *Data,\r
-  IN UINTN                          SelectorSize,\r
-  IN UINTN                          DataSize,\r
-  IN VOID                           *Context\r
-  )\r
-{\r
-  IKEV2_CHILD_SA_SESSION  *ChildSaSession;\r
-  EFI_IPSEC_SPD_SELECTOR  *SpdSelector;\r
-  EFI_IPSEC_SPD_DATA      *SpdData;\r
-  BOOLEAN                 IsMatch;\r
-  UINT8                   IpVersion;\r
-\r
-  ASSERT (Type == IPsecConfigDataTypeSpd);\r
-  SpdData = (EFI_IPSEC_SPD_DATA *) Data;\r
-  //\r
-  // Bypass all non-protect SPD entry first\r
-  //\r
-  if (SpdData->Action != EfiIPsecActionProtect) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  ChildSaSession  = (IKEV2_CHILD_SA_SESSION *) Context;\r
-  IpVersion       = ChildSaSession->SessionCommon.UdpService->IpVersion;\r
-  SpdSelector     = (EFI_IPSEC_SPD_SELECTOR *) Selector;\r
-  IsMatch         = TRUE;\r
-\r
-  if (SpdSelector->NextLayerProtocol == EFI_IP_PROTO_UDP &&\r
-      SpdSelector->LocalPort == IKE_DEFAULT_PORT &&\r
-      SpdSelector->LocalPortRange == 0 &&\r
-      SpdSelector->RemotePort == IKE_DEFAULT_PORT &&\r
-      SpdSelector->RemotePortRange == 0\r
-      ) {\r
-    //\r
-    // TODO: Skip IKE Policy here or set a SPD entry?\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (SpdSelector->NextLayerProtocol != EFI_IPSEC_ANY_PROTOCOL &&\r
-      SpdSelector->NextLayerProtocol != ChildSaSession->ProtoId\r
-      ) {\r
-    IsMatch = FALSE;\r
-  }\r
-\r
-  if (SpdSelector->LocalPort != EFI_IPSEC_ANY_PORT && SpdSelector->LocalPort != ChildSaSession->LocalPort) {\r
-    IsMatch = FALSE;\r
-  }\r
-\r
-  if (SpdSelector->RemotePort != EFI_IPSEC_ANY_PORT && SpdSelector->RemotePort != ChildSaSession->RemotePort) {\r
-    IsMatch = FALSE;\r
-  }\r
-\r
-  IsMatch = (BOOLEAN) (IsMatch &&\r
-                       IpSecMatchIpAddress (\r
-                         IpVersion,\r
-                         &ChildSaSession->SessionCommon.LocalPeerIp,\r
-                         SpdSelector->LocalAddress,\r
-                         SpdSelector->LocalAddressCount\r
-                         ));\r
-\r
-  IsMatch = (BOOLEAN) (IsMatch &&\r
-                       IpSecMatchIpAddress (\r
-                         IpVersion,\r
-                         &ChildSaSession->SessionCommon.RemotePeerIp,\r
-                         SpdSelector->RemoteAddress,\r
-                         SpdSelector->RemoteAddressCount\r
-                         ));\r
-\r
-  if (IsMatch) {\r
-    ChildSaSession->Spd = IkeSearchSpdEntry (SpdSelector);\r
-    return EFI_ABORTED;\r
-  } else {\r
-    return EFI_SUCCESS;\r
-  }\r
-}\r
-\r
-/**\r
-  Check if the Algorithm ID is supported.\r
-\r
-  @param[in]  AlgorithmId The specified Algorithm ID.\r
-  @param[in]  Type        The type used to indicate the Algorithm is for Encrypt or\r
-                          Authentication.\r
-\r
-  @retval     TRUE        If the Algorithm ID is supported.\r
-  @retval     FALSE       If the Algorithm ID is not supported.\r
-\r
-**/\r
-BOOLEAN\r
-Ikev2IsSupportAlg (\r
-  IN UINT16 AlgorithmId,\r
-  IN UINT8  Type\r
-  )\r
-{\r
-  UINT8 Index;\r
-  switch (Type) {\r
-  case IKE_ENCRYPT_TYPE :\r
-    for (Index = 0; Index < IKEV2_SUPPORT_ENCRYPT_ALGORITHM_NUM; Index++) {\r
-      if (mIkev2EncryptAlgorithmList[Index] == AlgorithmId) {\r
-        return TRUE;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case IKE_AUTH_TYPE :\r
-    for (Index = 0; Index < IKEV2_SUPPORT_AUTH_ALGORITHM_NUM; Index++) {\r
-      if (mIkev2AuthAlgorithmList[Index] == AlgorithmId) {\r
-        return TRUE;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case IKE_DH_TYPE :\r
-    for (Index = 0; Index < IKEV2_SUPPORT_DH_ALGORITHM_NUM; Index++) {\r
-      if (mIkev2DhGroupAlgorithmList[Index] == AlgorithmId) {\r
-        return TRUE;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case IKE_PRF_TYPE :\r
-    for (Index = 0; Index < IKEV2_SUPPORT_PRF_ALGORITHM_NUM; Index++) {\r
-      if (mIkev2PrfAlgorithmList[Index] == AlgorithmId) {\r
-        return TRUE;\r
-      }\r
-    }\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Get the preferred algorithm types from ProposalData.\r
-\r
-  @param[in]      ProposalData              Pointer to related IKEV2_PROPOSAL_DATA.\r
-  @param[in, out] PreferEncryptAlgorithm    Pointer to buffer which is used to store the\r
-                                            preferred encrypt algorithm.\r
-                                            Input value shall be initialized to zero that\r
-                                            indicates to be parsed from ProposalData.\r
-                                            Output of preferred encrypt algorithm.\r
-  @param[in, out] PreferIntegrityAlgorithm  Pointer to buffer which is used to store the\r
-                                            preferred integrity algorithm.\r
-                                            Input value shall be initialized to zero that\r
-                                            indicates to be parsed from ProposalData.\r
-                                            Output of preferred integrity algorithm.\r
-  @param[in, out] PreferPrfAlgorithm        Pointer to buffer which is used to store the\r
-                                            preferred PRF algorithm.\r
-                                            Input value shall be initialized to zero that\r
-                                            indicates to be parsed from ProposalData.\r
-                                            Output of preferred PRF algorithm. Only\r
-                                            for IKE SA.\r
-  @param[in, out] PreferDhGroup             Pointer to buffer which is used to store the\r
-                                            preferred DH group.\r
-                                            Input value shall be initialized to zero that\r
-                                            indicates to be parsed from ProposalData.\r
-                                            Output of preferred DH group. Only for\r
-                                            IKE SA.\r
-  @param[out]     PreferEncryptKeylength    Pointer to buffer which is used to store the\r
-                                            preferred encrypt key length in bytes.\r
-  @param[out]     IsSupportEsn              Pointer to buffer which is used to store the\r
-                                            value about the Extented Sequence Number is\r
-                                            support or not. Only for Child SA.\r
-  @param[in]      IsChildSa                 If it is ture, the ProposalData is for IKE\r
-                                            SA. Otherwise the proposalData is for Child SA.\r
-\r
-**/\r
-VOID\r
-Ikev2ParseProposalData (\r
-  IN     IKEV2_PROPOSAL_DATA  *ProposalData,\r
-  IN OUT UINT16               *PreferEncryptAlgorithm,\r
-  IN OUT UINT16               *PreferIntegrityAlgorithm,\r
-  IN OUT UINT16               *PreferPrfAlgorithm,\r
-  IN OUT UINT16               *PreferDhGroup,\r
-     OUT UINTN                *PreferEncryptKeylength,\r
-     OUT BOOLEAN              *IsSupportEsn,\r
-  IN     BOOLEAN              IsChildSa\r
-)\r
-{\r
-  IKEV2_TRANSFORM_DATA *TransformData;\r
-  UINT8                TransformIndex;\r
-\r
-  //\r
-  // Check input parameters.\r
-  //\r
-  if (ProposalData == NULL ||\r
-      PreferEncryptAlgorithm == NULL ||\r
-      PreferIntegrityAlgorithm == NULL ||\r
-      PreferEncryptKeylength == NULL\r
-      ) {\r
-    return;\r
-  }\r
-\r
-  if (IsChildSa) {\r
-    if (IsSupportEsn == NULL) {\r
-      return;\r
-    }\r
-  } else {\r
-    if (PreferPrfAlgorithm == NULL || PreferDhGroup == NULL) {\r
-      return;\r
-    }\r
-  }\r
-\r
-  TransformData = (IKEV2_TRANSFORM_DATA *)(ProposalData + 1);\r
-  for (TransformIndex = 0; TransformIndex < ProposalData->NumTransforms; TransformIndex++) {\r
-    switch (TransformData->TransformType) {\r
-    //\r
-    // For IKE SA there are four algorithm types. Encryption Algorithm, Pseudo-random Function,\r
-    // Integrity Algorithm, Diffie-Hellman Group. For Child SA, there are three algorithm types.\r
-    // Encryption Algorithm, Integrity Algorithm, Extended Sequence Number.\r
-    //\r
-    case IKEV2_TRANSFORM_TYPE_ENCR:\r
-      if (*PreferEncryptAlgorithm == 0 && Ikev2IsSupportAlg (TransformData->TransformId, IKE_ENCRYPT_TYPE)) {\r
-        //\r
-        // Check the attribute value. According to RFC, only Keylength is support.\r
-        //\r
-        if (TransformData->Attribute.AttrType == IKEV2_ATTRIBUTE_TYPE_KEYLEN) {\r
-          //\r
-          // If the Keylength is not support, continue to check the next one.\r
-          //\r
-          if (IpSecGetEncryptKeyLength ((UINT8)TransformData->TransformId) != (UINTN)(TransformData->Attribute.Attr.AttrValue >> 3)){\r
-            break;\r
-          } else {\r
-            *PreferEncryptKeylength = TransformData->Attribute.Attr.AttrValue;\r
-          }\r
-        }\r
-        *PreferEncryptAlgorithm = TransformData->TransformId;\r
-      }\r
-      break;\r
-\r
-    case IKEV2_TRANSFORM_TYPE_PRF :\r
-      if (!IsChildSa) {\r
-        if (*PreferPrfAlgorithm == 0 && Ikev2IsSupportAlg (TransformData->TransformId, IKE_PRF_TYPE)) {\r
-          *PreferPrfAlgorithm = TransformData->TransformId;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case IKEV2_TRANSFORM_TYPE_INTEG :\r
-      if (*PreferIntegrityAlgorithm == 0 && Ikev2IsSupportAlg (TransformData->TransformId, IKE_AUTH_TYPE)) {\r
-        *PreferIntegrityAlgorithm = TransformData->TransformId;\r
-      }\r
-      break;\r
-\r
-    case IKEV2_TRANSFORM_TYPE_DH :\r
-      if (!IsChildSa) {\r
-        if (*PreferDhGroup == 0 && Ikev2IsSupportAlg (TransformData->TransformId, IKE_DH_TYPE)) {\r
-          *PreferDhGroup = TransformData->TransformId;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case IKEV2_TRANSFORM_TYPE_ESN :\r
-      if (IsChildSa) {\r
-        if (TransformData->TransformId != 0) {\r
-          *IsSupportEsn = TRUE;\r
-        }\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-    TransformData = (IKEV2_TRANSFORM_DATA *)(TransformData + 1);\r
-  }\r
-}\r
-\r
-/**\r
-  Parse the received Initial Exchange Packet.\r
-\r
-  This function parse the SA Payload and Key Payload to find out the cryptographic\r
-  suite for the further IKE negotiation and fill it into the IKE SA Session's\r
-  CommonSession->SaParams.\r
-\r
-  @param[in, out]  IkeSaSession  Pointer to related IKEV2_SA_SESSION.\r
-  @param[in]       SaPayload     The received packet.\r
-  @param[in]       Type          The received packet IKE header flag.\r
-\r
-  @retval          TRUE          If the SA proposal in Packet is acceptable.\r
-  @retval          FALSE         If the SA proposal in Packet is not acceptable.\r
-\r
-**/\r
-BOOLEAN\r
-Ikev2SaParseSaPayload (\r
-  IN OUT IKEV2_SA_SESSION *IkeSaSession,\r
-  IN     IKE_PAYLOAD      *SaPayload,\r
-  IN     UINT8            Type\r
-  )\r
-{\r
-  IKEV2_PROPOSAL_DATA  *ProposalData;\r
-  UINT8                ProposalIndex;\r
-  UINT16               PreferEncryptAlgorithm;\r
-  UINT16               PreferIntegrityAlgorithm;\r
-  UINT16               PreferPrfAlgorithm;\r
-  UINT16               PreferDhGroup;\r
-  UINTN                PreferEncryptKeylength;\r
-  UINT16               EncryptAlgorithm;\r
-  UINT16               IntegrityAlgorithm;\r
-  UINT16               PrfAlgorithm;\r
-  UINT16               DhGroup;\r
-  UINTN                EncryptKeylength;\r
-  BOOLEAN              IsMatch;\r
-  UINTN                SaDataSize;\r
-\r
-  PreferPrfAlgorithm       = 0;\r
-  PreferIntegrityAlgorithm = 0;\r
-  PreferDhGroup            = 0;\r
-  PreferEncryptAlgorithm   = 0;\r
-  PreferEncryptKeylength   = 0;\r
-  PrfAlgorithm             = 0;\r
-  IntegrityAlgorithm       = 0;\r
-  DhGroup                  = 0;\r
-  EncryptAlgorithm         = 0;\r
-  EncryptKeylength         = 0;\r
-  IsMatch                  = FALSE;\r
-\r
-  if (Type == IKE_HEADER_FLAGS_INIT) {\r
-    ProposalData   = (IKEV2_PROPOSAL_DATA *)((IKEV2_SA_DATA *)SaPayload->PayloadBuf + 1);\r
-    for (ProposalIndex = 0; ProposalIndex < ((IKEV2_SA_DATA *)SaPayload->PayloadBuf)->NumProposals; ProposalIndex++) {\r
-      //\r
-      // Iterate each proposal to find the perfered one.\r
-      //\r
-      if (ProposalData->ProtocolId == IPSEC_PROTO_ISAKMP && ProposalData->NumTransforms >= 4) {\r
-        //\r
-        // Get the preferred algorithms.\r
-        //\r
-        Ikev2ParseProposalData (\r
-          ProposalData,\r
-          &PreferEncryptAlgorithm,\r
-          &PreferIntegrityAlgorithm,\r
-          &PreferPrfAlgorithm,\r
-          &PreferDhGroup,\r
-          &PreferEncryptKeylength,\r
-          NULL,\r
-          FALSE\r
-          );\r
-\r
-        if (PreferEncryptAlgorithm != 0 &&\r
-              PreferIntegrityAlgorithm != 0 &&\r
-              PreferPrfAlgorithm != 0 &&\r
-              PreferDhGroup != 0\r
-              ) {\r
-            //\r
-            // Find the matched one.\r
-            //\r
-            IkeSaSession->SessionCommon.SaParams = AllocateZeroPool (sizeof (IKEV2_SA_PARAMS));\r
-            if (IkeSaSession->SessionCommon.SaParams == NULL) {\r
-              return FALSE;\r
-            }\r
-\r
-            IkeSaSession->SessionCommon.SaParams->EncAlgId   = PreferEncryptAlgorithm;\r
-            IkeSaSession->SessionCommon.SaParams->EnckeyLen  = PreferEncryptKeylength;\r
-            IkeSaSession->SessionCommon.SaParams->DhGroup    = PreferDhGroup;\r
-            IkeSaSession->SessionCommon.SaParams->Prf        = PreferPrfAlgorithm;\r
-            IkeSaSession->SessionCommon.SaParams->IntegAlgId = PreferIntegrityAlgorithm;\r
-            IkeSaSession->SessionCommon.PreferDhGroup        = PreferDhGroup;\r
-\r
-            //\r
-            // Save the matched one in IKEV2_SA_DATA for furthure calculation.\r
-            //\r
-            SaDataSize           = sizeof (IKEV2_SA_DATA) +\r
-                                   sizeof (IKEV2_PROPOSAL_DATA) +\r
-                                   sizeof (IKEV2_TRANSFORM_DATA) * 4;\r
-            IkeSaSession->SaData = AllocateZeroPool (SaDataSize);\r
-            if (IkeSaSession->SaData == NULL) {\r
-              FreePool (IkeSaSession->SessionCommon.SaParams);\r
-              return FALSE;\r
-            }\r
-\r
-            IkeSaSession->SaData->NumProposals  = 1;\r
-\r
-            //\r
-            // BUGBUG: Suppose the matched proposal only has 4 transforms. If\r
-            // The matched Proposal has more than 4 transforms means it contains\r
-            // one than one transform with same type.\r
-            //\r
-            CopyMem (\r
-              (IKEV2_PROPOSAL_DATA *) (IkeSaSession->SaData + 1),\r
-               ProposalData,\r
-               SaDataSize - sizeof (IKEV2_SA_DATA)\r
-              );\r
-\r
-            ((IKEV2_PROPOSAL_DATA *) (IkeSaSession->SaData + 1))->ProposalIndex = 1;\r
-\r
-            return TRUE;\r
-          } else {\r
-            PreferEncryptAlgorithm   = 0;\r
-            PreferIntegrityAlgorithm = 0;\r
-            PreferPrfAlgorithm       = 0;\r
-            PreferDhGroup            = 0;\r
-            PreferEncryptKeylength   = 0;\r
-          }\r
-      }\r
-      //\r
-      // Point to next Proposal.\r
-      //\r
-      ProposalData = (IKEV2_PROPOSAL_DATA*)((UINT8*)(ProposalData + 1) +\r
-                     ProposalData->NumTransforms * sizeof (IKEV2_TRANSFORM_DATA));\r
-    }\r
-  } else if (Type == IKE_HEADER_FLAGS_RESPOND) {\r
-    //\r
-    // First check the SA proposal's ProtoctolID and Transform Numbers. Since it is\r
-    // the responded SA proposal, suppose it only has one proposal and the transform Numbers\r
-    // is 4.\r
-    //\r
-    ProposalData  = (IKEV2_PROPOSAL_DATA *)((IKEV2_SA_DATA *) SaPayload->PayloadBuf + 1);\r
-    if (ProposalData->ProtocolId != IPSEC_PROTO_ISAKMP || ProposalData->NumTransforms != 4) {\r
-      return FALSE;\r
-    }\r
-    //\r
-    // Get the preferred algorithms.\r
-    //\r
-    Ikev2ParseProposalData (\r
-      ProposalData,\r
-      &PreferEncryptAlgorithm,\r
-      &PreferIntegrityAlgorithm,\r
-      &PreferPrfAlgorithm,\r
-      &PreferDhGroup,\r
-      &PreferEncryptKeylength,\r
-      NULL,\r
-      FALSE\r
-      );\r
-    //\r
-    // Check if the Sa proposal data from received packet is in the IkeSaSession->SaData.\r
-    //\r
-    ProposalData = (IKEV2_PROPOSAL_DATA *) (IkeSaSession->SaData + 1);\r
-\r
-    for (ProposalIndex = 0; ProposalIndex < IkeSaSession->SaData->NumProposals && (!IsMatch); ProposalIndex++) {\r
-      Ikev2ParseProposalData (\r
-          ProposalData,\r
-          &EncryptAlgorithm,\r
-          &IntegrityAlgorithm,\r
-          &PrfAlgorithm,\r
-          &DhGroup,\r
-          &EncryptKeylength,\r
-          NULL,\r
-          FALSE\r
-          );\r
-      if (EncryptAlgorithm == PreferEncryptAlgorithm &&\r
-          EncryptKeylength == PreferEncryptKeylength &&\r
-          IntegrityAlgorithm == PreferIntegrityAlgorithm &&\r
-          PrfAlgorithm == PreferPrfAlgorithm &&\r
-          DhGroup      == PreferDhGroup\r
-          ) {\r
-        IsMatch = TRUE;\r
-      } else {\r
-        EncryptAlgorithm   = 0;\r
-        IntegrityAlgorithm = 0;\r
-        PrfAlgorithm       = 0;\r
-        DhGroup            = 0;\r
-        EncryptKeylength   = 0;\r
-      }\r
-\r
-      ProposalData = (IKEV2_PROPOSAL_DATA*)((UINT8*)(ProposalData + 1) +\r
-                     ProposalData->NumTransforms * sizeof (IKEV2_TRANSFORM_DATA));\r
-    }\r
-\r
-    if (IsMatch) {\r
-        IkeSaSession->SessionCommon.SaParams = AllocateZeroPool (sizeof (IKEV2_SA_PARAMS));\r
-        if (IkeSaSession->SessionCommon.SaParams == NULL) {\r
-          return FALSE;\r
-        }\r
-\r
-        IkeSaSession->SessionCommon.SaParams->EncAlgId   = PreferEncryptAlgorithm;\r
-        IkeSaSession->SessionCommon.SaParams->EnckeyLen  = PreferEncryptKeylength;\r
-        IkeSaSession->SessionCommon.SaParams->DhGroup    = PreferDhGroup;\r
-        IkeSaSession->SessionCommon.SaParams->Prf        = PreferPrfAlgorithm;\r
-        IkeSaSession->SessionCommon.SaParams->IntegAlgId = PreferIntegrityAlgorithm;\r
-        IkeSaSession->SessionCommon.PreferDhGroup        = PreferDhGroup;\r
-\r
-        return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Parse the received Authentication Exchange Packet.\r
-\r
-  This function parse the SA Payload and Key Payload to find out the cryptographic\r
-  suite for the ESP and fill it into the Child SA Session's CommonSession->SaParams.\r
-\r
-  @param[in, out]  ChildSaSession  Pointer to IKEV2_CHILD_SA_SESSION related to\r
-                                   this Authentication Exchange.\r
-  @param[in]       SaPayload       The received packet.\r
-  @param[in]       Type            The IKE header's flag of received packet .\r
-\r
-  @retval          TRUE            If the SA proposal in Packet is acceptable.\r
-  @retval          FALSE           If the SA proposal in Packet is not acceptable.\r
-\r
-**/\r
-BOOLEAN\r
-Ikev2ChildSaParseSaPayload (\r
-  IN OUT IKEV2_CHILD_SA_SESSION *ChildSaSession,\r
-  IN     IKE_PAYLOAD            *SaPayload,\r
-  IN     UINT8                  Type\r
-  )\r
-{\r
-  IKEV2_PROPOSAL_DATA  *ProposalData;\r
-  UINT8                ProposalIndex;\r
-  UINT16               PreferEncryptAlgorithm;\r
-  UINT16               PreferIntegrityAlgorithm;\r
-  UINTN                PreferEncryptKeylength;\r
-  BOOLEAN              PreferIsSupportEsn;\r
-  UINT16               EncryptAlgorithm;\r
-  UINT16               IntegrityAlgorithm;\r
-  UINTN                EncryptKeylength;\r
-  BOOLEAN              IsSupportEsn;\r
-  BOOLEAN              IsMatch;\r
-  UINTN                SaDataSize;\r
-\r
-\r
-  PreferIntegrityAlgorithm = 0;\r
-  PreferEncryptAlgorithm   = 0;\r
-  PreferEncryptKeylength   = 0;\r
-  IntegrityAlgorithm       = 0;\r
-  EncryptAlgorithm         = 0;\r
-  EncryptKeylength         = 0;\r
-  IsMatch                  = FALSE;\r
-  IsSupportEsn             = FALSE;\r
-  PreferIsSupportEsn       = FALSE;\r
-\r
-  if (Type == IKE_HEADER_FLAGS_INIT) {\r
-    ProposalData   = (IKEV2_PROPOSAL_DATA *)((IKEV2_SA_DATA *) SaPayload->PayloadBuf + 1);\r
-    for (ProposalIndex = 0; ProposalIndex < ((IKEV2_SA_DATA *) SaPayload->PayloadBuf)->NumProposals; ProposalIndex++) {\r
-      //\r
-      // Iterate each proposal to find the preferred one.\r
-      //\r
-      if (ProposalData->ProtocolId == IPSEC_PROTO_IPSEC_ESP && ProposalData->NumTransforms >= 3) {\r
-        //\r
-        // Get the preferred algorithm.\r
-        //\r
-        Ikev2ParseProposalData (\r
-          ProposalData,\r
-          &PreferEncryptAlgorithm,\r
-          &PreferIntegrityAlgorithm,\r
-          NULL,\r
-          NULL,\r
-          &PreferEncryptKeylength,\r
-          &IsSupportEsn,\r
-          TRUE\r
-          );\r
-        //\r
-        // Don't support the ESN now.\r
-        //\r
-        if (PreferEncryptAlgorithm != 0 &&\r
-            PreferIntegrityAlgorithm != 0 &&\r
-            !IsSupportEsn\r
-            ) {\r
-          //\r
-          // Find the matched one.\r
-          //\r
-          ChildSaSession->SessionCommon.SaParams = AllocateZeroPool (sizeof (IKEV2_SA_PARAMS));\r
-          if (ChildSaSession->SessionCommon.SaParams == NULL) {\r
-            return FALSE;\r
-          }\r
-\r
-          ChildSaSession->SessionCommon.SaParams->EncAlgId   = PreferEncryptAlgorithm;\r
-          ChildSaSession->SessionCommon.SaParams->EnckeyLen  = PreferEncryptKeylength;\r
-          ChildSaSession->SessionCommon.SaParams->IntegAlgId = PreferIntegrityAlgorithm;\r
-          CopyMem (&ChildSaSession->RemotePeerSpi, ProposalData->Spi, sizeof (ChildSaSession->RemotePeerSpi));\r
-\r
-          //\r
-          // Save the matched one in IKEV2_SA_DATA for furthure calculation.\r
-          //\r
-          SaDataSize           = sizeof (IKEV2_SA_DATA) +\r
-                                 sizeof (IKEV2_PROPOSAL_DATA) +\r
-                                 sizeof (IKEV2_TRANSFORM_DATA) * 4;\r
-\r
-          ChildSaSession->SaData = AllocateZeroPool (SaDataSize);\r
-          if (ChildSaSession->SaData == NULL) {\r
-            FreePool (ChildSaSession->SessionCommon.SaParams);\r
-            return FALSE;\r
-          }\r
-\r
-          ChildSaSession->SaData->NumProposals  = 1;\r
-\r
-          //\r
-          // BUGBUG: Suppose there are 4 transforms in the matched proposal. If\r
-          // the matched Proposal has more than 4 transforms that means there\r
-          // are more than one transform with same type.\r
-          //\r
-          CopyMem (\r
-            (IKEV2_PROPOSAL_DATA *) (ChildSaSession->SaData + 1),\r
-             ProposalData,\r
-             SaDataSize - sizeof (IKEV2_SA_DATA)\r
-            );\r
-\r
-          ((IKEV2_PROPOSAL_DATA *) (ChildSaSession->SaData + 1))->ProposalIndex = 1;\r
-\r
-          ((IKEV2_PROPOSAL_DATA *) (ChildSaSession->SaData + 1))->Spi = AllocateCopyPool (\r
-                                                                          sizeof (ChildSaSession->LocalPeerSpi),\r
-                                                                          &ChildSaSession->LocalPeerSpi\r
-                                                                          );\r
-          if (((IKEV2_PROPOSAL_DATA *) (ChildSaSession->SaData + 1))->Spi == NULL) {\r
-            FreePool (ChildSaSession->SessionCommon.SaParams);\r
-\r
-            FreePool (ChildSaSession->SaData );\r
-\r
-            return FALSE;\r
-          }\r
-\r
-          return TRUE;\r
-\r
-        } else {\r
-          PreferEncryptAlgorithm   = 0;\r
-          PreferIntegrityAlgorithm = 0;\r
-          IsSupportEsn             = TRUE;\r
-        }\r
-      }\r
-      //\r
-      // Point to next Proposal\r
-      //\r
-      ProposalData = (IKEV2_PROPOSAL_DATA *)((UINT8 *)(ProposalData + 1) +\r
-                     ProposalData->NumTransforms * sizeof (IKEV2_TRANSFORM_DATA));\r
-    }\r
-  } else if (Type == IKE_HEADER_FLAGS_RESPOND) {\r
-    //\r
-    // First check the SA proposal's ProtoctolID and Transform Numbers. Since it is\r
-    // the responded SA proposal, suppose it only has one proposal and the transform Numbers\r
-    // is 3.\r
-    //\r
-    ProposalData  = (IKEV2_PROPOSAL_DATA *)((IKEV2_SA_DATA *)SaPayload->PayloadBuf + 1);\r
-    if (ProposalData->ProtocolId != IPSEC_PROTO_IPSEC_ESP || ProposalData->NumTransforms != 3) {\r
-      return FALSE;\r
-    }\r
-    //\r
-    // Get the preferred algorithms.\r
-    //\r
-    Ikev2ParseProposalData (\r
-      ProposalData,\r
-      &PreferEncryptAlgorithm,\r
-      &PreferIntegrityAlgorithm,\r
-      NULL,\r
-      NULL,\r
-      &PreferEncryptKeylength,\r
-      &PreferIsSupportEsn,\r
-      TRUE\r
-      );\r
-\r
-    ProposalData = (IKEV2_PROPOSAL_DATA *) (ChildSaSession->SaData + 1);\r
-\r
-    for (ProposalIndex = 0; ProposalIndex < ChildSaSession->SaData->NumProposals && (!IsMatch); ProposalIndex++) {\r
-      Ikev2ParseProposalData (\r
-          ProposalData,\r
-          &EncryptAlgorithm,\r
-          &IntegrityAlgorithm,\r
-          NULL,\r
-          NULL,\r
-          &EncryptKeylength,\r
-          &IsSupportEsn,\r
-          TRUE\r
-          );\r
-      if (EncryptAlgorithm == PreferEncryptAlgorithm &&\r
-          EncryptKeylength == PreferEncryptKeylength &&\r
-          IntegrityAlgorithm == PreferIntegrityAlgorithm &&\r
-          IsSupportEsn == PreferIsSupportEsn\r
-          ) {\r
-        IsMatch = TRUE;\r
-      } else {\r
-        IntegrityAlgorithm = 0;\r
-        EncryptAlgorithm   = 0;\r
-        EncryptKeylength   = 0;\r
-        IsSupportEsn       = FALSE;\r
-      }\r
-      ProposalData = (IKEV2_PROPOSAL_DATA*)((UINT8*)(ProposalData + 1) +\r
-                     ProposalData->NumTransforms * sizeof (IKEV2_TRANSFORM_DATA));\r
-    }\r
-\r
-    ProposalData  = (IKEV2_PROPOSAL_DATA *)((IKEV2_SA_DATA *)SaPayload->PayloadBuf + 1);\r
-    if (IsMatch) {\r
-        ChildSaSession->SessionCommon.SaParams = AllocateZeroPool (sizeof (IKEV2_SA_PARAMS));\r
-        if (ChildSaSession->SessionCommon.SaParams == NULL) {\r
-          return FALSE;\r
-        }\r
-\r
-        ChildSaSession->SessionCommon.SaParams->EncAlgId   = PreferEncryptAlgorithm;\r
-        ChildSaSession->SessionCommon.SaParams->EnckeyLen  = PreferEncryptKeylength;\r
-        ChildSaSession->SessionCommon.SaParams->IntegAlgId = PreferIntegrityAlgorithm;\r
-        CopyMem (&ChildSaSession->RemotePeerSpi, ProposalData->Spi, sizeof (ChildSaSession->RemotePeerSpi));\r
-\r
-        return TRUE;\r
-    }\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Generate Key buffer from fragments.\r
-\r
-  If the digest length of specified HashAlgId is larger than or equal with the\r
-  required output key length, derive the key directly. Otherwise, Key Material\r
-  needs to be PRF-based concatenation according to 2.13 of RFC 4306:\r
-  prf+ (K,S) = T1 | T2 | T3 | T4 | ..., T1 = prf (K, S | 0x01),\r
-  T2 = prf (K, T1 | S | 0x02), T3 = prf (K, T2 | S | 0x03),T4 = prf (K, T3 | S | 0x04)\r
-  then derive the key from this key material.\r
-\r
-  @param[in]       HashAlgId        The Hash Algorithm ID used to generate key.\r
-  @param[in]       HashKey          Pointer to a key buffer which contains hash key.\r
-  @param[in]       HashKeyLength    The length of HashKey in bytes.\r
-  @param[in, out]  OutputKey        Pointer to buffer which is used to receive the\r
-                                    output key.\r
-  @param[in]       OutputKeyLength  The length of OutPutKey buffer.\r
-  @param[in]       Fragments        Pointer to the data to be used to generate key.\r
-  @param[in]       NumFragments     The numbers of the Fragement.\r
-\r
-  @retval EFI_SUCCESS            The operation complete successfully.\r
-  @retval EFI_INVALID_PARAMETER  If NumFragments is zero.\r
-                                 If the authentication algorithm given by HashAlgId\r
-                                 cannot be found.\r
-  @retval EFI_OUT_OF_RESOURCES   If the required resource can't be allocated.\r
-  @retval Others                 The operation is failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2SaGenerateKey (\r
-  IN     UINT8                 HashAlgId,\r
-  IN     UINT8                 *HashKey,\r
-  IN     UINTN                 HashKeyLength,\r
-  IN OUT UINT8                 *OutputKey,\r
-  IN     UINTN                 OutputKeyLength,\r
-  IN     PRF_DATA_FRAGMENT    *Fragments,\r
-  IN     UINTN                 NumFragments\r
-  )\r
-{\r
-  EFI_STATUS          Status;\r
-  PRF_DATA_FRAGMENT   LocalFragments[3];\r
-  UINT8               *Digest;\r
-  UINTN               DigestSize;\r
-  UINTN               Round;\r
-  UINTN               Index;\r
-  UINTN               AuthKeyLength;\r
-  UINTN               FragmentsSize;\r
-  UINT8               TailData;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  if (NumFragments == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  LocalFragments[0].Data = NULL;\r
-  LocalFragments[1].Data = NULL;\r
-  LocalFragments[2].Data = NULL;\r
-\r
-  AuthKeyLength = IpSecGetHmacDigestLength (HashAlgId);\r
-  if (AuthKeyLength == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  DigestSize    = AuthKeyLength;\r
-  Digest        = AllocateZeroPool (AuthKeyLength);\r
-\r
-  if (Digest == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // If the required output key length is less than the digest size,\r
-  // copy the digest into OutputKey.\r
-  //\r
-  if (OutputKeyLength <=  DigestSize) {\r
-    Status = IpSecCryptoIoHmac (\r
-               HashAlgId,\r
-               HashKey,\r
-               HashKeyLength,\r
-               (HASH_DATA_FRAGMENT *) Fragments,\r
-               NumFragments,\r
-               Digest,\r
-               DigestSize\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    CopyMem (OutputKey, Digest, OutputKeyLength);\r
-    goto Exit;\r
-  }\r
-\r
-  //\r
-  //Otherwise, Key Material need to be PRF-based concatenation according to 2.13\r
-  //of RFC 4306: prf+ (K,S) = T1 | T2 | T3 | T4 | ..., T1 = prf (K, S | 0x01),\r
-  //T2 = prf (K, T1 | S | 0x02), T3 = prf (K, T2 | S | 0x03),T4 = prf (K, T3 | S | 0x04)\r
-  //then derive the key from this key material.\r
-  //\r
-  FragmentsSize = 0;\r
-  for (Index = 0; Index < NumFragments; Index++) {\r
-    FragmentsSize = FragmentsSize + Fragments[Index].DataSize;\r
-  }\r
-\r
-  LocalFragments[1].Data     = AllocateZeroPool (FragmentsSize);\r
-  if (LocalFragments[1].Data == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
-\r
-  LocalFragments[1].DataSize = FragmentsSize;\r
-\r
-  //\r
-  // Copy all input fragments into LocalFragments[1];\r
-  //\r
-  FragmentsSize = 0;\r
-  for (Index = 0; Index < NumFragments; Index++) {\r
-    CopyMem (\r
-      LocalFragments[1].Data + FragmentsSize,\r
-      Fragments[Index].Data,\r
-      Fragments[Index].DataSize\r
-      );\r
-    FragmentsSize = FragmentsSize + Fragments[Index].DataSize;\r
-  }\r
-\r
-  //\r
-  // Prepare 0x01 as the first tail data.\r
-  //\r
-  TailData                   = 0x01;\r
-  LocalFragments[2].Data     = &TailData;\r
-  LocalFragments[2].DataSize = sizeof (TailData);\r
-  //\r
-  // Allocate buffer for the first fragment\r
-  //\r
-  LocalFragments[0].Data     = AllocateZeroPool (AuthKeyLength);\r
-  if (LocalFragments[0].Data == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
-\r
-  LocalFragments[0].DataSize = AuthKeyLength;\r
-\r
-  Round = (OutputKeyLength - 1) / AuthKeyLength + 1;\r
-  for (Index = 0; Index < Round; Index++) {\r
-    Status = IpSecCryptoIoHmac (\r
-               HashAlgId,\r
-               HashKey,\r
-               HashKeyLength,\r
-               (HASH_DATA_FRAGMENT *)(Index == 0 ? &LocalFragments[1] : LocalFragments),\r
-               Index == 0 ? 2 : 3,\r
-               Digest,\r
-               DigestSize\r
-               );\r
-    if (EFI_ERROR(Status)) {\r
-      goto Exit;\r
-    }\r
-    CopyMem (\r
-      LocalFragments[0].Data,\r
-      Digest,\r
-      DigestSize\r
-      );\r
-    if (OutputKeyLength > DigestSize * (Index + 1)) {\r
-      CopyMem (\r
-        OutputKey + Index * DigestSize,\r
-        Digest,\r
-        DigestSize\r
-        );\r
-      LocalFragments[0].DataSize = DigestSize;\r
-      TailData ++;\r
-    } else {\r
-      //\r
-      // The last round\r
-      //\r
-      CopyMem (\r
-        OutputKey + Index * DigestSize,\r
-        Digest,\r
-        OutputKeyLength - Index * DigestSize\r
-      );\r
-    }\r
-  }\r
-\r
-Exit:\r
-  //\r
-  // Only First and second Framgement Data need to be freed.\r
-  //\r
-  for (Index = 0 ; Index < 2; Index++) {\r
-    if (LocalFragments[Index].Data != NULL) {\r
-      FreePool (LocalFragments[Index].Data);\r
-    }\r
-  }\r
-  if (Digest != NULL) {\r
-    FreePool (Digest);\r
-  }\r
-  return Status;\r
-}\r
-\r