]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/Ikev2/Payload.c
NetworkPkg: Remove IpSec driver and application
[mirror_edk2.git] / NetworkPkg / IpSecDxe / Ikev2 / Payload.c
diff --git a/NetworkPkg/IpSecDxe/Ikev2/Payload.c b/NetworkPkg/IpSecDxe/Ikev2/Payload.c
deleted file mode 100644 (file)
index 56869e2..0000000
+++ /dev/null
@@ -1,3329 +0,0 @@
-/** @file\r
-  The implementation of Payloads Creation.\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 "IpSecConfigImpl.h"\r
-#include "IpSecCryptIo.h"\r
-\r
-//\r
-// The Constant String of "Key Pad for IKEv2" for Authentication Payload generation.\r
-//\r
-#define CONSTANT_KEY_SIZE     17\r
-GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mConstantKey[CONSTANT_KEY_SIZE] =\r
-{\r
-  'K', 'e', 'y', ' ', 'P', 'a', 'd', ' ', 'f', 'o', 'r', ' ', 'I', 'K', 'E', 'v', '2'\r
-};\r
-\r
-/**\r
-  Generate Ikev2 SA payload according to SessionSaData\r
-\r
-  @param[in] SessionSaData   The data used in SA payload.\r
-  @param[in] NextPayload     The payload type presented in NextPayload field of\r
-                             SA Payload header.\r
-  @param[in] Type            The SA type. It MUST be neither (1) for IKE_SA or\r
-                             (2) for CHILD_SA or (3) for INFO.\r
-\r
-  @retval a Pointer to SA IKE payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateSaPayload (\r
-  IN IKEV2_SA_DATA    *SessionSaData,\r
-  IN UINT8            NextPayload,\r
-  IN IKE_SESSION_TYPE Type\r
-  )\r
-{\r
-  IKE_PAYLOAD   *SaPayload;\r
-  IKEV2_SA_DATA *SaData;\r
-  UINTN         SaDataSize;\r
-\r
-  SaPayload = IkePayloadAlloc ();\r
-  if (SaPayload == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // TODO: Get the Proposal Number and Transform Number from IPsec Config,\r
-  // after the Ipsecconfig Application is support it.\r
-  //\r
-\r
-  if (Type == IkeSessionTypeIkeSa) {\r
-    SaDataSize = sizeof (IKEV2_SA_DATA) +\r
-                 SessionSaData->NumProposals * sizeof (IKEV2_PROPOSAL_DATA) +\r
-                 sizeof (IKEV2_TRANSFORM_DATA) * SessionSaData->NumProposals * 4;\r
-  } else {\r
-    SaDataSize = sizeof (IKEV2_SA_DATA) +\r
-                 SessionSaData->NumProposals * sizeof (IKEV2_PROPOSAL_DATA) +\r
-                 sizeof (IKEV2_TRANSFORM_DATA) * SessionSaData->NumProposals * 3;\r
-\r
-  }\r
-\r
-  SaData = AllocateZeroPool (SaDataSize);\r
-  if (SaData == NULL) {\r
-    IkePayloadFree (SaPayload);\r
-    return NULL;\r
-  }\r
-\r
-  CopyMem (SaData, SessionSaData, SaDataSize);\r
-  SaData->SaHeader.Header.NextPayload = NextPayload;\r
-  SaPayload->PayloadType              = IKEV2_PAYLOAD_TYPE_SA;\r
-  SaPayload->PayloadBuf               = (UINT8 *) SaData;\r
-\r
-  return SaPayload;\r
-}\r
-\r
-/**\r
-  Generate a Nonce payload containing the input parameter NonceBuf.\r
-\r
-  @param[in]  NonceBuf      The nonce buffer contains the whole Nonce payload block\r
-                            except the payload header.\r
-  @param[in]  NonceSize     The buffer size of the NonceBuf\r
-  @param[in]  NextPayload   The payload type presented in the NextPayload field\r
-                            of Nonce Payload header.\r
-\r
-  @retval Pointer to Nonce IKE paload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateNoncePayload (\r
-  IN UINT8            *NonceBuf,\r
-  IN UINTN            NonceSize,\r
-  IN UINT8            NextPayload\r
-  )\r
-{\r
-  IKE_PAYLOAD *NoncePayload;\r
-  IKEV2_NONCE *Nonce;\r
-  UINTN       Size;\r
-  UINT8       *NonceBlock;\r
-\r
-  //                           1                   2                   3\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !                                                               !\r
-  //    ~                            Nonce Data                         ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  Size        = sizeof (IKEV2_NONCE) + NonceSize;\r
-  NonceBlock  = NonceBuf;\r
-\r
-  Nonce       = AllocateZeroPool (Size);\r
-  if (Nonce == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  CopyMem (Nonce + 1, NonceBlock, Size - sizeof (IKEV2_NONCE));\r
-\r
-  Nonce->Header.NextPayload   = NextPayload;\r
-  Nonce->Header.PayloadLength = (UINT16) Size;\r
-  NoncePayload                = IkePayloadAlloc ();\r
-  if (NoncePayload == NULL) {\r
-    FreePool (Nonce);\r
-    return NULL;\r
-  }\r
-\r
-  NoncePayload->PayloadType = IKEV2_PAYLOAD_TYPE_NONCE;\r
-  NoncePayload->PayloadBuf  = (UINT8 *) Nonce;\r
-  NoncePayload->PayloadSize = Size;\r
-\r
-  return NoncePayload;\r
-}\r
-\r
-/**\r
-  Generate a Key Exchange payload according to the DH group type and save the\r
-  public Key into IkeSaSession IkeKey field.\r
-\r
-  @param[in, out] IkeSaSession    Pointer of the IKE_SA_SESSION.\r
-  @param[in]      NextPayload     The payload type presented in the NextPayload field of Key\r
-                                  Exchange Payload header.\r
-\r
-  @retval Pointer to Key IKE payload.\r
-\r
-**/\r
-IKE_PAYLOAD*\r
-Ikev2GenerateKePayload (\r
-  IN OUT IKEV2_SA_SESSION *IkeSaSession,\r
-  IN     UINT8            NextPayload\r
-  )\r
-{\r
-  IKE_PAYLOAD         *KePayload;\r
-  IKEV2_KEY_EXCHANGE  *Ke;\r
-  UINTN               KeSize;\r
-  IKEV2_SESSION_KEYS  *IkeKeys;\r
-\r
-  //\r
-  //                        1                   2                   3\r
-  //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !          DH Group #           !           RESERVED            !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !                                                               !\r
-  //   ~                       Key Exchange Data                       ~\r
-  //   !                                                               !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  IkeKeys = IkeSaSession->IkeKeys;\r
-\r
-  if (IkeSaSession->SessionCommon.IsInitiator) {\r
-    KeSize = sizeof (IKEV2_KEY_EXCHANGE) + IkeKeys->DhBuffer->GxSize;\r
-  } else {\r
-    KeSize = sizeof (IKEV2_KEY_EXCHANGE) + IkeKeys->DhBuffer->GxSize;\r
-  }\r
-\r
-  //\r
-  // Allocate buffer for Key Exchange\r
-  //\r
-  Ke = AllocateZeroPool (KeSize);\r
-  if (Ke == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  Ke->Header.NextPayload    = NextPayload;\r
-  Ke->Header.PayloadLength  = (UINT16) KeSize;\r
-  Ke->DhGroup               = IkeSaSession->SessionCommon.PreferDhGroup;\r
-\r
-  CopyMem (Ke + 1, IkeKeys->DhBuffer->GxBuffer, IkeKeys->DhBuffer->GxSize);\r
-\r
-  //\r
-  // Create IKE_PAYLOAD to point to Key Exchange payload\r
-  //\r
-  KePayload = IkePayloadAlloc ();\r
-  if (KePayload == NULL) {\r
-    FreePool (Ke);\r
-    return NULL;\r
-  }\r
-\r
-  KePayload->PayloadType = IKEV2_PAYLOAD_TYPE_KE;\r
-  KePayload->PayloadBuf  = (UINT8 *) Ke;\r
-  KePayload->PayloadSize = KeSize;\r
-  return KePayload;\r
-}\r
-\r
-/**\r
-  Generate a ID payload.\r
-\r
-  @param[in] CommonSession   Pointer to IKEV2_SESSION_COMMON related to ID payload.\r
-  @param[in] NextPayload     The payload type presented in the NextPayload field\r
-                             of ID Payload header.\r
-\r
-  @retval Pointer to ID IKE payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateIdPayload (\r
-  IN IKEV2_SESSION_COMMON *CommonSession,\r
-  IN UINT8                NextPayload\r
-  )\r
-{\r
-  IKE_PAYLOAD    *IdPayload;\r
-  IKEV2_ID       *Id;\r
-  UINTN          IdSize;\r
-  UINT8          IpVersion;\r
-  UINT8          AddrSize;\r
-\r
-  //\r
-  // ID payload\r
-  //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   ! Next Payload  !   RESERVED    !         Payload Length        !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !   ID Type     !             RESERVED                          !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !                                                               !\r
-  //   ~                   Identification Data                         ~\r
-  //   !                                                               !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  IpVersion = CommonSession->UdpService->IpVersion;\r
-  AddrSize  = (UINT8) ((IpVersion == IP_VERSION_4) ? sizeof(EFI_IPv4_ADDRESS) : sizeof(EFI_IPv6_ADDRESS));\r
-  IdSize    = sizeof (IKEV2_ID) + AddrSize;\r
-\r
-  Id = (IKEV2_ID *) AllocateZeroPool (IdSize);\r
-  if (Id == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  IdPayload = IkePayloadAlloc ();\r
-  if (IdPayload == NULL) {\r
-    FreePool (Id);\r
-    return NULL;\r
-  }\r
-\r
-  IdPayload->PayloadType  = (UINT8) ((CommonSession->IsInitiator) ? IKEV2_PAYLOAD_TYPE_ID_INIT : IKEV2_PAYLOAD_TYPE_ID_RSP);\r
-  IdPayload->PayloadBuf   = (UINT8 *) Id;\r
-  IdPayload->PayloadSize  = IdSize;\r
-\r
-  //\r
-  // Set generic header of identification payload\r
-  //\r
-  Id->Header.NextPayload    = NextPayload;\r
-  Id->Header.PayloadLength  = (UINT16) IdSize;\r
-  Id->IdType                = (UINT8) ((IpVersion == IP_VERSION_4) ? IKEV2_ID_TYPE_IPV4_ADDR : IKEV2_ID_TYPE_IPV6_ADDR);\r
-  CopyMem (Id + 1, &CommonSession->LocalPeerIp, AddrSize);\r
-\r
-  return IdPayload;\r
-}\r
-\r
-/**\r
-  Generate a ID payload.\r
-\r
-  @param[in] CommonSession   Pointer to IKEV2_SESSION_COMMON related to ID payload.\r
-  @param[in] NextPayload     The payload type presented in the NextPayload field\r
-                             of ID Payload header.\r
-  @param[in] InCert          Pointer to the Certificate which distinguished name\r
-                             will be added into the Id payload.\r
-  @param[in] CertSize        Size of the Certificate.\r
-\r
-  @retval Pointer to ID IKE payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateCertIdPayload (\r
-  IN IKEV2_SESSION_COMMON *CommonSession,\r
-  IN UINT8                NextPayload,\r
-  IN UINT8                *InCert,\r
-  IN UINTN                CertSize\r
-  )\r
-{\r
-  IKE_PAYLOAD    *IdPayload;\r
-  IKEV2_ID       *Id;\r
-  UINTN          IdSize;\r
-  UINTN          SubjectSize;\r
-  UINT8          *CertSubject;\r
-\r
-  //\r
-  // ID payload\r
-  //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   ! Next Payload  !   RESERVED    !         Payload Length        !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !   ID Type     !             RESERVED                          !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !                                                               !\r
-  //   ~                   Identification Data                         ~\r
-  //   !                                                               !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  SubjectSize = 0;\r
-  CertSubject = NULL;\r
-  IpSecCryptoIoGetSubjectFromCert (\r
-    InCert,\r
-    CertSize,\r
-    &CertSubject,\r
-    &SubjectSize\r
-    );\r
-  if (SubjectSize != 0) {\r
-    ASSERT (CertSubject != NULL);\r
-  }\r
-\r
-  IdSize = sizeof (IKEV2_ID) + SubjectSize;\r
-\r
-  Id = (IKEV2_ID *) AllocateZeroPool (IdSize);\r
-  if (Id == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  IdPayload = IkePayloadAlloc ();\r
-  if (IdPayload == NULL) {\r
-    FreePool (Id);\r
-    return NULL;\r
-  }\r
-\r
-  IdPayload->PayloadType  = (UINT8) ((CommonSession->IsInitiator) ? IKEV2_PAYLOAD_TYPE_ID_INIT : IKEV2_PAYLOAD_TYPE_ID_RSP);\r
-  IdPayload->PayloadBuf   = (UINT8 *) Id;\r
-  IdPayload->PayloadSize  = IdSize;\r
-\r
-  //\r
-  // Set generic header of identification payload\r
-  //\r
-  Id->Header.NextPayload    = NextPayload;\r
-  Id->Header.PayloadLength  = (UINT16) IdSize;\r
-  Id->IdType                = 9;\r
-  CopyMem (Id + 1, CertSubject, SubjectSize);\r
-\r
-  if (CertSubject != NULL) {\r
-    FreePool (CertSubject);\r
-  }\r
-  return IdPayload;\r
-}\r
-\r
-/**\r
-  Generate a Authentication Payload.\r
-\r
-  This function is used for both Authentication generation and verification. When the\r
-  IsVerify is TRUE, it create a Auth Data for verification. This function choose the\r
-  related IKE_SA_INIT Message for Auth data creation according to the IKE Session's type\r
-  and the value of IsVerify parameter.\r
-\r
-  @param[in]  IkeSaSession  Pointer to IKEV2_SA_SESSION related to.\r
-  @param[in]  IdPayload     Pointer to the ID payload to be used for Authentication\r
-                            payload generation.\r
-  @param[in]  NextPayload   The type filled into the Authentication Payload next\r
-                            payload field.\r
-  @param[in]  IsVerify      If it is TURE, the Authentication payload is used for\r
-                            verification.\r
-\r
-  @return pointer to IKE Authentication payload for Pre-shared key method.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2PskGenerateAuthPayload (\r
-  IN IKEV2_SA_SESSION *IkeSaSession,\r
-  IN IKE_PAYLOAD      *IdPayload,\r
-  IN UINT8            NextPayload,\r
-  IN BOOLEAN          IsVerify\r
-  )\r
-{\r
-  UINT8              *Digest;\r
-  UINTN              DigestSize;\r
-  PRF_DATA_FRAGMENT  Fragments[3];\r
-  UINT8              *KeyBuf;\r
-  UINTN              KeySize;\r
-  IKE_PAYLOAD        *AuthPayload;\r
-  IKEV2_AUTH         *PayloadBuf;\r
-  EFI_STATUS         Status;\r
-\r
-  //\r
-  // Auth = Prf(Prf(Secret,"Key Pad for IKEv2),IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))\r
-  //\r
-  //                           1                   2                   3\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Auth Method   !                RESERVED                       !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !                                                               !\r
-  //    ~                      Authentication Data                      ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  KeyBuf      = NULL;\r
-  AuthPayload = NULL;\r
-  Digest      = NULL;\r
-\r
-  DigestSize = IpSecGetHmacDigestLength ((UINT8)IkeSaSession->SessionCommon.SaParams->Prf);\r
-  Digest     = AllocateZeroPool (DigestSize);\r
-  if (Digest == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  if (IdPayload == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Calcualte Prf(Seceret, "Key Pad for IKEv2");\r
-  //\r
-  Fragments[0].Data     = (UINT8 *) mConstantKey;\r
-  Fragments[0].DataSize = CONSTANT_KEY_SIZE;\r
-\r
-  Status = IpSecCryptoIoHmac (\r
-             (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-             IkeSaSession->Pad->Data->AuthData,\r
-             IkeSaSession->Pad->Data->AuthDataSize,\r
-             (HASH_DATA_FRAGMENT *)Fragments,\r
-             1,\r
-             Digest,\r
-             DigestSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Store the AuthKey into KeyBuf\r
-  //\r
-  KeyBuf = AllocateZeroPool (DigestSize);\r
-  if (KeyBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  CopyMem (KeyBuf, Digest, DigestSize);\r
-  KeySize = DigestSize;\r
-\r
-  //\r
-  // Calculate Prf(SK_Pi/r, IDi/r)\r
-  //\r
-  Fragments[0].Data     = IdPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER);\r
-  Fragments[0].DataSize = IdPayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER);\r
-\r
-  if ((IkeSaSession->SessionCommon.IsInitiator && IsVerify) ||\r
-      (!IkeSaSession->SessionCommon.IsInitiator && !IsVerify)\r
-     ) {\r
-     Status = IpSecCryptoIoHmac (\r
-                (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-                IkeSaSession->IkeKeys->SkPrKey,\r
-                IkeSaSession->IkeKeys->SkPrKeySize,\r
-                (HASH_DATA_FRAGMENT *) Fragments,\r
-                1,\r
-                Digest,\r
-                DigestSize\r
-                );\r
-  } else {\r
-    Status = IpSecCryptoIoHmac (\r
-               (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-               IkeSaSession->IkeKeys->SkPiKey,\r
-               IkeSaSession->IkeKeys->SkPiKeySize,\r
-               (HASH_DATA_FRAGMENT *) Fragments,\r
-               1,\r
-               Digest,\r
-               DigestSize\r
-               );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Copy data to Fragments.\r
-  //\r
-  if ((IkeSaSession->SessionCommon.IsInitiator && IsVerify) ||\r
-      (!IkeSaSession->SessionCommon.IsInitiator && !IsVerify)\r
-     )  {\r
-    Fragments[0].Data     = IkeSaSession->RespPacket;\r
-    Fragments[0].DataSize = IkeSaSession->RespPacketSize;\r
-    Fragments[1].Data     = IkeSaSession->NiBlock;\r
-    Fragments[1].DataSize = IkeSaSession->NiBlkSize;\r
-  } else {\r
-    Fragments[0].Data     = IkeSaSession->InitPacket;\r
-    Fragments[0].DataSize = IkeSaSession->InitPacketSize;\r
-    Fragments[1].Data     = IkeSaSession->NrBlock;\r
-    Fragments[1].DataSize = IkeSaSession->NrBlkSize;\r
-  }\r
-\r
-  //\r
-  // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].\r
-  //\r
-  Fragments[2].Data     = AllocateZeroPool (DigestSize);\r
-  if (Fragments[2].Data == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  Fragments[2].DataSize = DigestSize;\r
-  CopyMem (Fragments[2].Data, Digest, DigestSize);\r
-\r
-  //\r
-  // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))\r
-  //\r
-  Status = IpSecCryptoIoHmac (\r
-             (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-             KeyBuf,\r
-             KeySize,\r
-             (HASH_DATA_FRAGMENT *) Fragments,\r
-             3,\r
-             Digest,\r
-             DigestSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Allocate buffer for Auth Payload\r
-  //\r
-  AuthPayload               = IkePayloadAlloc ();\r
-  if (AuthPayload == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  AuthPayload->PayloadSize  = sizeof (IKEV2_AUTH) + DigestSize;\r
-  PayloadBuf                = (IKEV2_AUTH *) AllocateZeroPool (AuthPayload->PayloadSize);\r
-  if (PayloadBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Fill in Auth payload.\r
-  //\r
-  PayloadBuf->Header.NextPayload   = NextPayload;\r
-  PayloadBuf->Header.PayloadLength = (UINT16) (AuthPayload->PayloadSize);\r
-  if (IkeSaSession->Pad->Data->AuthMethod == EfiIPsecAuthMethodPreSharedSecret) {\r
-    //\r
-    // Only support Shared Key Message Integrity\r
-    //\r
-    PayloadBuf->AuthMethod = IKEV2_AUTH_METHOD_SKMI;\r
-  } else {\r
-    //\r
-    // Not support other Auth method.\r
-    //\r
-    Status = EFI_UNSUPPORTED;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth\r
-  // payload block.\r
-  //\r
-  CopyMem (\r
-    PayloadBuf + 1,\r
-    Digest,\r
-    DigestSize\r
-    );\r
-\r
-  //\r
-  // Fill in IKE_PACKET\r
-  //\r
-  AuthPayload->PayloadBuf   = (UINT8 *) PayloadBuf;\r
-  AuthPayload->PayloadType  = IKEV2_PAYLOAD_TYPE_AUTH;\r
-\r
-EXIT:\r
-  if (KeyBuf != NULL) {\r
-    FreePool (KeyBuf);\r
-  }\r
-  if (Digest != NULL) {\r
-    FreePool (Digest);\r
-  }\r
-  if (Fragments[2].Data != NULL) {\r
-    //\r
-    // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)\r
-    //\r
-    FreePool (Fragments[2].Data);\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (AuthPayload != NULL) {\r
-      IkePayloadFree (AuthPayload);\r
-    }\r
-    return NULL;\r
-  } else {\r
-    return AuthPayload;\r
-  }\r
-}\r
-\r
-/**\r
-  Generate a Authentication Payload for Certificate Auth method.\r
-\r
-  This function has two functions. One is creating a local Authentication\r
-  Payload for sending and other is creating the remote Authentication data\r
-  for verification when the IsVerify is TURE.\r
-\r
-  @param[in]  IkeSaSession      Pointer to IKEV2_SA_SESSION related to.\r
-  @param[in]  IdPayload         Pointer to the ID payload to be used for Authentication\r
-                                payload generation.\r
-  @param[in]  NextPayload       The type filled into the Authentication Payload\r
-                                next payload field.\r
-  @param[in]  IsVerify          If it is TURE, the Authentication payload is used\r
-                                for verification.\r
-  @param[in]  UefiPrivateKey    Pointer to the UEFI private key. Ignore it when\r
-                                verify the authenticate payload.\r
-  @param[in]  UefiPrivateKeyLen The size of UefiPrivateKey in bytes. Ignore it\r
-                                when verify the authenticate payload.\r
-  @param[in]  UefiKeyPwd        Pointer to the password of UEFI private key.\r
-                                Ignore it when verify the authenticate payload.\r
-  @param[in]  UefiKeyPwdLen     The size of UefiKeyPwd in bytes.Ignore it when\r
-                                verify the authenticate payload.\r
-\r
-  @return pointer to IKE Authentication payload for Cerifitcation method.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2CertGenerateAuthPayload (\r
-  IN IKEV2_SA_SESSION *IkeSaSession,\r
-  IN IKE_PAYLOAD      *IdPayload,\r
-  IN UINT8            NextPayload,\r
-  IN BOOLEAN          IsVerify,\r
-  IN UINT8            *UefiPrivateKey,\r
-  IN UINTN            UefiPrivateKeyLen,\r
-  IN UINT8            *UefiKeyPwd,\r
-  IN UINTN            UefiKeyPwdLen\r
-  )\r
-{\r
-  UINT8              *Digest;\r
-  UINTN              DigestSize;\r
-  PRF_DATA_FRAGMENT  Fragments[3];\r
-  IKE_PAYLOAD        *AuthPayload;\r
-  IKEV2_AUTH         *PayloadBuf;\r
-  EFI_STATUS         Status;\r
-  UINT8              *Signature;\r
-  UINTN              SigSize;\r
-\r
-  //\r
-  // Auth = Prf(Scert,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))\r
-  //\r
-  //                           1                   2                   3\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Auth Method   !                RESERVED                       !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !                                                               !\r
-  //    ~                      Authentication Data                      ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  //\r
-  // Initial point\r
-  //\r
-  AuthPayload = NULL;\r
-  Digest      = NULL;\r
-  Signature   = NULL;\r
-  SigSize     = 0;\r
-\r
-  if (IdPayload == NULL) {\r
-    return NULL;\r
-  }\r
-  DigestSize = IpSecGetHmacDigestLength ((UINT8)IkeSaSession->SessionCommon.SaParams->Prf);\r
-  Digest     = AllocateZeroPool (DigestSize);\r
-  if (Digest == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Calculate Prf(SK_Pi/r, IDi/r)\r
-  //\r
-  Fragments[0].Data     = IdPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER);\r
-  Fragments[0].DataSize = IdPayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER);\r
-\r
-  IpSecDumpBuf ("RestofIDPayload", Fragments[0].Data, Fragments[0].DataSize);\r
-\r
-  if ((IkeSaSession->SessionCommon.IsInitiator && IsVerify) ||\r
-      (!IkeSaSession->SessionCommon.IsInitiator && !IsVerify)\r
-     ) {\r
-     Status = IpSecCryptoIoHmac(\r
-                (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-                IkeSaSession->IkeKeys->SkPrKey,\r
-                IkeSaSession->IkeKeys->SkPrKeySize,\r
-                (HASH_DATA_FRAGMENT *) Fragments,\r
-                1,\r
-                Digest,\r
-                DigestSize\r
-                );\r
-    IpSecDumpBuf ("MACedIDForR", Digest, DigestSize);\r
-  } else {\r
-    Status = IpSecCryptoIoHmac (\r
-               (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-               IkeSaSession->IkeKeys->SkPiKey,\r
-               IkeSaSession->IkeKeys->SkPiKeySize,\r
-               (HASH_DATA_FRAGMENT *) Fragments,\r
-               1,\r
-               Digest,\r
-               DigestSize\r
-               );\r
-    IpSecDumpBuf ("MACedIDForI", Digest, DigestSize);\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Copy data to Fragments.\r
-  //\r
-  if ((IkeSaSession->SessionCommon.IsInitiator && IsVerify) ||\r
-      (!IkeSaSession->SessionCommon.IsInitiator && !IsVerify)\r
-     )  {\r
-    Fragments[0].Data     = IkeSaSession->RespPacket;\r
-    Fragments[0].DataSize = IkeSaSession->RespPacketSize;\r
-    Fragments[1].Data     = IkeSaSession->NiBlock;\r
-    Fragments[1].DataSize = IkeSaSession->NiBlkSize;\r
-    IpSecDumpBuf ("RealMessage2", Fragments[0].Data, Fragments[0].DataSize);\r
-    IpSecDumpBuf ("NonceIDdata", Fragments[1].Data, Fragments[1].DataSize);\r
-  } else {\r
-    Fragments[0].Data     = IkeSaSession->InitPacket;\r
-    Fragments[0].DataSize = IkeSaSession->InitPacketSize;\r
-    Fragments[1].Data     = IkeSaSession->NrBlock;\r
-    Fragments[1].DataSize = IkeSaSession->NrBlkSize;\r
-    IpSecDumpBuf ("RealMessage1", Fragments[0].Data, Fragments[0].DataSize);\r
-    IpSecDumpBuf ("NonceRDdata", Fragments[1].Data, Fragments[1].DataSize);\r
-  }\r
-\r
-  //\r
-  // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].\r
-  //\r
-  Fragments[2].Data     = AllocateZeroPool (DigestSize);\r
-  if (Fragments[2].Data == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  Fragments[2].DataSize = DigestSize;\r
-  CopyMem (Fragments[2].Data, Digest, DigestSize);\r
-\r
-  //\r
-  // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))\r
-  //\r
-  Status = IpSecCryptoIoHash (\r
-             (UINT8)IkeSaSession->SessionCommon.SaParams->Prf,\r
-             (HASH_DATA_FRAGMENT *) Fragments,\r
-             3,\r
-             Digest,\r
-             DigestSize\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  IpSecDumpBuf ("HashSignedOctects", Digest, DigestSize);\r
-  //\r
-  // Sign the data by the private Key\r
-  //\r
-  if (!IsVerify) {\r
-    IpSecCryptoIoAuthDataWithCertificate (\r
-      Digest,\r
-      DigestSize,\r
-      UefiPrivateKey,\r
-      UefiPrivateKeyLen,\r
-      UefiKeyPwd,\r
-      UefiKeyPwdLen,\r
-      &Signature,\r
-      &SigSize\r
-      );\r
-\r
-    if (SigSize == 0 || Signature == NULL) {\r
-      goto EXIT;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Allocate buffer for Auth Payload\r
-  //\r
-  AuthPayload = IkePayloadAlloc ();\r
-  if (AuthPayload == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  if (!IsVerify) {\r
-    AuthPayload->PayloadSize  = sizeof (IKEV2_AUTH) + SigSize;\r
-  } else {\r
-    AuthPayload->PayloadSize  = sizeof (IKEV2_AUTH) + DigestSize;\r
-  }\r
-\r
-  PayloadBuf = (IKEV2_AUTH *) AllocateZeroPool (AuthPayload->PayloadSize);\r
-  if (PayloadBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Fill in Auth payload.\r
-  //\r
-  PayloadBuf->Header.NextPayload   = NextPayload;\r
-  PayloadBuf->Header.PayloadLength = (UINT16) (AuthPayload->PayloadSize);\r
-  if (IkeSaSession->Pad->Data->AuthMethod == EfiIPsecAuthMethodCertificates) {\r
-      PayloadBuf->AuthMethod = IKEV2_AUTH_METHOD_RSA;\r
-  } else {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth\r
-  // payload block.\r
-  //\r
-  if (!IsVerify) {\r
-    CopyMem (PayloadBuf + 1, Signature, SigSize);\r
-  } else {\r
-    CopyMem (PayloadBuf + 1, Digest, DigestSize);\r
-  }\r
-\r
-  //\r
-  // Fill in IKE_PACKET\r
-  //\r
-  AuthPayload->PayloadBuf   = (UINT8 *) PayloadBuf;\r
-  AuthPayload->PayloadType  = IKEV2_PAYLOAD_TYPE_AUTH;\r
-\r
-EXIT:\r
-  if (Digest != NULL) {\r
-    FreePool (Digest);\r
-  }\r
-  if (Signature != NULL) {\r
-    FreePool (Signature);\r
-  }\r
-  if (Fragments[2].Data != NULL) {\r
-    //\r
-    // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)\r
-    //\r
-    FreePool (Fragments[2].Data);\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (AuthPayload != NULL) {\r
-      IkePayloadFree (AuthPayload);\r
-    }\r
-    return NULL;\r
-  } else {\r
-    return AuthPayload;\r
-  }\r
-}\r
-\r
-/**\r
-  Generate TS payload.\r
-\r
-  This function generates TSi or TSr payload according to type of next payload.\r
-  If the next payload is Responder TS, gereate TSi Payload. Otherwise, generate\r
-  TSr payload.\r
-\r
-  @param[in] ChildSa        Pointer to IKEV2_CHILD_SA_SESSION related to this TS payload.\r
-  @param[in] NextPayload    The payload type presented in the NextPayload field\r
-                            of ID Payload header.\r
-  @param[in] IsTunnel       It indicates that if the Ts Payload is after the CP payload.\r
-                            If yes, it means the Tsi and Tsr payload should be with\r
-                            Max port range and address range and protocol is marked\r
-                            as zero.\r
-\r
-  @retval Pointer to Ts IKE payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateTsPayload (\r
-  IN IKEV2_CHILD_SA_SESSION *ChildSa,\r
-  IN UINT8                  NextPayload,\r
-  IN BOOLEAN                IsTunnel\r
-  )\r
-{\r
-  IKE_PAYLOAD        *TsPayload;\r
-  IKEV2_TS           *TsPayloadBuf;\r
-  TRAFFIC_SELECTOR   *TsSelector;\r
-  UINTN              SelectorSize;\r
-  UINTN              TsPayloadSize;\r
-  UINT8              IpVersion;\r
-  UINT8              AddrSize;\r
-\r
-  //\r
-  //                           1                   2                   3\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Number of TSs !                 RESERVED                      !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !                                                               !\r
-  //    ~                       <Traffic Selectors>                     ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  TsPayload    = IkePayloadAlloc();\r
-  if (TsPayload == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  IpVersion    = ChildSa->SessionCommon.UdpService->IpVersion;\r
-  //\r
-  // The Starting Address and Ending Address is variable length depends on\r
-  // is IPv4 or IPv6\r
-  //\r
-  AddrSize      = (UINT8)((IpVersion == IP_VERSION_4) ? sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS));\r
-  SelectorSize  = sizeof (TRAFFIC_SELECTOR) + 2 * AddrSize;\r
-  TsPayloadSize = sizeof (IKEV2_TS) + SelectorSize;\r
-  TsPayloadBuf = AllocateZeroPool (TsPayloadSize);\r
-  if (TsPayloadBuf == NULL) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  TsPayload->PayloadBuf = (UINT8 *) TsPayloadBuf;\r
-  TsSelector            = (TRAFFIC_SELECTOR*)(TsPayloadBuf + 1);\r
-\r
-  TsSelector->TSType = (UINT8)((IpVersion == IP_VERSION_4) ? IKEV2_TS_TYPE_IPV4_ADDR_RANGE : IKEV2_TS_TYPS_IPV6_ADDR_RANGE);\r
-\r
-  //\r
-  // For tunnel mode\r
-  //\r
-  if (IsTunnel) {\r
-    TsSelector->IpProtocolId = IKEV2_TS_ANY_PROTOCOL;\r
-    TsSelector->SelecorLen   = (UINT16) SelectorSize;\r
-    TsSelector->StartPort    = 0;\r
-    TsSelector->EndPort      = IKEV2_TS_ANY_PORT;\r
-    ZeroMem ((UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR), AddrSize);\r
-    SetMem  ((UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR) + AddrSize, AddrSize, 0xff);\r
-\r
-  } else {\r
-    //\r
-    // TODO: Support port range and address range\r
-    //\r
-    if (NextPayload == IKEV2_PAYLOAD_TYPE_TS_RSP){\r
-      //\r
-      // Create initiator Traffic Selector\r
-      //\r
-      TsSelector->SelecorLen   = (UINT16)SelectorSize;\r
-\r
-      //\r
-      // Currently only support the port range from 0~0xffff. Don't support other\r
-      // port range.\r
-      // TODO: support Port range\r
-      //\r
-      if (ChildSa->SessionCommon.IsInitiator) {\r
-        if (ChildSa->Spd->Selector->LocalPort != 0 &&\r
-            ChildSa->Spd->Selector->LocalPortRange == 0) {\r
-          //\r
-          // For not port range.\r
-          //\r
-          TsSelector->StartPort = ChildSa->Spd->Selector->LocalPort;\r
-          TsSelector->EndPort   = ChildSa->Spd->Selector->LocalPort;\r
-        } else if (ChildSa->Spd->Selector->LocalPort == 0){\r
-          //\r
-          // For port from 0~0xffff\r
-          //\r
-          TsSelector->StartPort = 0;\r
-          TsSelector->EndPort   = IKEV2_TS_ANY_PORT;\r
-        } else {\r
-          //\r
-          // Not support now.\r
-          //\r
-          goto ON_ERROR;\r
-        }\r
-      } else {\r
-        if (ChildSa->Spd->Selector->RemotePort != 0 &&\r
-            ChildSa->Spd->Selector->RemotePortRange == 0) {\r
-          //\r
-          // For not port range.\r
-          //\r
-          TsSelector->StartPort = ChildSa->Spd->Selector->RemotePort;\r
-          TsSelector->EndPort   = ChildSa->Spd->Selector->RemotePort;\r
-        } else if (ChildSa->Spd->Selector->RemotePort == 0) {\r
-          //\r
-          // For port from 0~0xffff\r
-          //\r
-          TsSelector->StartPort = 0;\r
-          TsSelector->EndPort   = IKEV2_TS_ANY_PORT;\r
-        } else {\r
-          //\r
-          // Not support now.\r
-          //\r
-          goto ON_ERROR;\r
-        }\r
-      }\r
-      //\r
-      // Copy Address.Currently the address range is not supported.\r
-      // The Starting address is same as Ending address\r
-      // TODO: Support Address Range.\r
-      //\r
-      CopyMem (\r
-        (UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR),\r
-        ChildSa->SessionCommon.IsInitiator ?\r
-        ChildSa->Spd->Selector->LocalAddress :\r
-        ChildSa->Spd->Selector->RemoteAddress,\r
-        AddrSize\r
-        );\r
-      CopyMem (\r
-        (UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR) + AddrSize,\r
-        ChildSa->SessionCommon.IsInitiator ?\r
-        ChildSa->Spd->Selector->LocalAddress :\r
-        ChildSa->Spd->Selector->RemoteAddress,\r
-        AddrSize\r
-        );\r
-      //\r
-      // If the Next Payload is not TS responder, this TS payload type is the TS responder.\r
-      //\r
-      TsPayload->PayloadType             = IKEV2_PAYLOAD_TYPE_TS_INIT;\r
-    }else{\r
-        //\r
-        // Create responder Traffic Selector\r
-        //\r
-        TsSelector->SelecorLen   = (UINT16)SelectorSize;\r
-\r
-        //\r
-        // Currently only support the port range from 0~0xffff. Don't support other\r
-        // port range.\r
-        // TODO: support Port range\r
-        //\r
-        if (!ChildSa->SessionCommon.IsInitiator) {\r
-          if (ChildSa->Spd->Selector->LocalPort != 0 &&\r
-              ChildSa->Spd->Selector->LocalPortRange == 0) {\r
-            //\r
-            // For not port range.\r
-            //\r
-            TsSelector->StartPort = ChildSa->Spd->Selector->LocalPort;\r
-            TsSelector->EndPort   = ChildSa->Spd->Selector->LocalPort;\r
-          } else if (ChildSa->Spd->Selector->LocalPort == 0){\r
-            //\r
-            // For port from 0~0xffff\r
-            //\r
-            TsSelector->StartPort = 0;\r
-            TsSelector->EndPort   = IKEV2_TS_ANY_PORT;\r
-          } else {\r
-            //\r
-            // Not support now.\r
-            //\r
-            goto ON_ERROR;\r
-          }\r
-        } else {\r
-          if (ChildSa->Spd->Selector->RemotePort != 0 &&\r
-              ChildSa->Spd->Selector->RemotePortRange == 0) {\r
-            //\r
-            // For not port range.\r
-            //\r
-            TsSelector->StartPort = ChildSa->Spd->Selector->RemotePort;\r
-            TsSelector->EndPort   = ChildSa->Spd->Selector->RemotePort;\r
-          } else if (ChildSa->Spd->Selector->RemotePort == 0){\r
-            //\r
-            // For port from 0~0xffff\r
-            //\r
-            TsSelector->StartPort = 0;\r
-            TsSelector->EndPort   = IKEV2_TS_ANY_PORT;\r
-          } else {\r
-            //\r
-            // Not support now.\r
-            //\r
-            goto ON_ERROR;\r
-          }\r
-        }\r
-        //\r
-        // Copy Address.Currently the address range is not supported.\r
-        // The Starting address is same as Ending address\r
-        // TODO: Support Address Range.\r
-        //\r
-        CopyMem (\r
-          (UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR),\r
-          ChildSa->SessionCommon.IsInitiator ?\r
-          ChildSa->Spd->Selector->RemoteAddress :\r
-          ChildSa->Spd->Selector->LocalAddress,\r
-          AddrSize\r
-          );\r
-        CopyMem (\r
-          (UINT8*)TsSelector + sizeof(TRAFFIC_SELECTOR) + AddrSize,\r
-          ChildSa->SessionCommon.IsInitiator ?\r
-          ChildSa->Spd->Selector->RemoteAddress :\r
-          ChildSa->Spd->Selector->LocalAddress,\r
-          AddrSize\r
-          );\r
-        //\r
-        // If the Next Payload is not TS responder, this TS payload type is the TS responder.\r
-        //\r
-        TsPayload->PayloadType          = IKEV2_PAYLOAD_TYPE_TS_RSP;\r
-      }\r
-    }\r
-\r
-    if (ChildSa->Spd->Selector->NextLayerProtocol != 0xffff) {\r
-      TsSelector->IpProtocolId = (UINT8)ChildSa->Spd->Selector->NextLayerProtocol;\r
-    } else {\r
-      TsSelector->IpProtocolId = IKEV2_TS_ANY_PROTOCOL;\r
-    }\r
-\r
-  TsPayloadBuf->Header.NextPayload    = NextPayload;\r
-  TsPayloadBuf->Header.PayloadLength  = (UINT16)TsPayloadSize;\r
-  TsPayloadBuf->TSNumbers             = 1;\r
-  TsPayload->PayloadSize              = TsPayloadSize;\r
-  goto ON_EXIT;\r
-\r
-ON_ERROR:\r
-  if (TsPayload != NULL) {\r
-    IkePayloadFree (TsPayload);\r
-    TsPayload = NULL;\r
-  }\r
-ON_EXIT:\r
-  return TsPayload;\r
-}\r
-\r
-/**\r
-  Generate the Notify payload.\r
-\r
-  Since the structure of Notify payload which defined in RFC 4306 is simple, so\r
-  there is no internal data structure for Notify payload. This function generate\r
-  Notify payload defined in RFC 4306, but all the fields in this payload are still\r
-  in host order and need call Ikev2EncodePayload() to convert those fields from\r
-  the host order to network order beforing sending it.\r
-\r
-  @param[in]  ProtocolId        The protocol type ID. For IKE_SA it MUST be one (1).\r
-                                For IPsec SAs it MUST be neither (2) for AH or (3)\r
-                                for ESP.\r
-  @param[in]  NextPayload       The next paylaod type in NextPayload field of\r
-                                the Notify payload.\r
-  @param[in]  SpiSize           Size of the SPI in SPI size field of the Notify Payload.\r
-  @param[in]  MessageType       The message type in NotifyMessageType field of the\r
-                                Notify Payload.\r
-  @param[in]  SpiBuf            Pointer to buffer contains the SPI value.\r
-  @param[in]  NotifyData        Pointer to buffer contains the notification data.\r
-  @param[in]  NotifyDataSize    The size of NotifyData in bytes.\r
-\r
-\r
-  @retval Pointer to IKE Notify Payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateNotifyPayload (\r
-  IN UINT8            ProtocolId,\r
-  IN UINT8            NextPayload,\r
-  IN UINT8            SpiSize,\r
-  IN UINT16           MessageType,\r
-  IN UINT8            *SpiBuf,\r
-  IN UINT8            *NotifyData,\r
-  IN UINTN            NotifyDataSize\r
-  )\r
-{\r
-  IKE_PAYLOAD         *NotifyPayload;\r
-  IKEV2_NOTIFY        *Notify;\r
-  UINT16              NotifyPayloadLen;\r
-  UINT8               *MessageData;\r
-\r
-  //                       1                   2                   3\r
-  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  !  Protocol ID  !   SPI Size    !      Notify Message Type      !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  !                                                               !\r
-  //  ~                Security Parameter Index (SPI)                 ~\r
-  //  !                                                               !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  !                                                               !\r
-  //  ~                       Notification Data                       ~\r
-  //  !                                                               !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  //\r
-  NotifyPayloadLen  = (UINT16) (sizeof (IKEV2_NOTIFY) + NotifyDataSize + SpiSize);\r
-  Notify            = (IKEV2_NOTIFY *) AllocateZeroPool (NotifyPayloadLen);\r
-  if (Notify == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Set Delete Payload's Generic Header\r
-  //\r
-  Notify->Header.NextPayload    = NextPayload;\r
-  Notify->Header.PayloadLength  = NotifyPayloadLen;\r
-  Notify->SpiSize               = SpiSize;\r
-  Notify->ProtocolId            = ProtocolId;\r
-  Notify->MessageType           = MessageType;\r
-\r
-  //\r
-  // Copy Spi , for Cookie Notify, there is no SPI.\r
-  //\r
-  if (SpiBuf != NULL && SpiSize != 0 ) {\r
-    CopyMem (Notify + 1, SpiBuf, SpiSize);\r
-  }\r
-\r
-  MessageData = ((UINT8 *) (Notify + 1)) + SpiSize;\r
-\r
-  //\r
-  // Copy Notification Data\r
-  //\r
-  if (NotifyDataSize != 0) {\r
-    CopyMem (MessageData, NotifyData, NotifyDataSize);\r
-  }\r
-\r
-  //\r
-  // Create Payload for and set type as IKEV2_PAYLOAD_TYPE_NOTIFY\r
-  //\r
-  NotifyPayload = IkePayloadAlloc ();\r
-  if (NotifyPayload == NULL) {\r
-    FreePool (Notify);\r
-    return NULL;\r
-  }\r
-\r
-  NotifyPayload->PayloadType  = IKEV2_PAYLOAD_TYPE_NOTIFY;\r
-  NotifyPayload->PayloadBuf   = (UINT8 *) Notify;\r
-  NotifyPayload->PayloadSize  = NotifyPayloadLen;\r
-  return NotifyPayload;\r
-}\r
-\r
-/**\r
-  Generate the Delete payload.\r
-\r
-  Since the structure of Delete payload which defined in RFC 4306 is simple,\r
-  there is no internal data structure for Delete payload. This function generate\r
-  Delete payload defined in RFC 4306, but all the fields in this payload are still\r
-  in host order and need call Ikev2EncodePayload() to convert those fields from\r
-  the host order to network order beforing sending it.\r
-\r
-  @param[in]  IkeSaSession      Pointer to IKE SA Session to be used of Delete payload generation.\r
-  @param[in]  NextPayload       The next paylaod type in NextPayload field of\r
-                                the Delete payload.\r
-  @param[in]  SpiSize           Size of the SPI in SPI size field of the Delete Payload.\r
-  @param[in]  SpiNum            Number of SPI in NumofSPIs field of the Delete Payload.\r
-  @param[in]  SpiBuf            Pointer to buffer contains the SPI value.\r
-\r
-  @retval a Pointer of IKE Delete Payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateDeletePayload (\r
-  IN IKEV2_SA_SESSION  *IkeSaSession,\r
-  IN UINT8             NextPayload,\r
-  IN UINT8             SpiSize,\r
-  IN UINT16            SpiNum,\r
-  IN UINT8             *SpiBuf\r
-\r
-  )\r
-{\r
-  IKE_PAYLOAD  *DelPayload;\r
-  IKEV2_DELETE *Del;\r
-  UINT16       SpiBufSize;\r
-  UINT16       DelPayloadLen;\r
-\r
-  //                         1                   2                   3\r
-  //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  ! Protocol ID   !   SPI Size    !           # of SPIs           !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //  !                                                               !\r
-  //  ~               Security Parameter Index(es) (SPI)              ~\r
-  //  !                                                               !\r
-  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  SpiBufSize    = (UINT16) (SpiSize * SpiNum);\r
-  if (SpiBufSize != 0 && SpiBuf == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  DelPayloadLen = (UINT16) (sizeof (IKEV2_DELETE) + SpiBufSize);\r
-\r
-  Del           = AllocateZeroPool (DelPayloadLen);\r
-  if (Del == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Set Delete Payload's Generic Header\r
-  //\r
-  Del->Header.NextPayload   = NextPayload;\r
-  Del->Header.PayloadLength = DelPayloadLen;\r
-  Del->NumSpis              = SpiNum;\r
-  Del->SpiSize              = SpiSize;\r
-\r
-  if (SpiSize == 4) {\r
-    //\r
-    // TODO: should consider the AH if needs to support.\r
-    //\r
-    Del->ProtocolId = IPSEC_PROTO_IPSEC_ESP;\r
-  } else {\r
-    Del->ProtocolId = IPSEC_PROTO_ISAKMP;\r
-  }\r
-\r
-  //\r
-  // Set Del Payload's Idntification Data\r
-  //\r
-  CopyMem (Del + 1, SpiBuf, SpiBufSize);\r
-  DelPayload = IkePayloadAlloc ();\r
-  if (DelPayload == NULL) {\r
-    FreePool (Del);\r
-    return NULL;\r
-  }\r
-\r
-  DelPayload->PayloadType = IKEV2_PAYLOAD_TYPE_DELETE;\r
-  DelPayload->PayloadBuf  = (UINT8 *) Del;\r
-  DelPayload->PayloadSize = DelPayloadLen;\r
-  return DelPayload;\r
-}\r
-\r
-/**\r
-  Generate the Configuration payload.\r
-\r
-  This function generate configuration payload defined in RFC 4306, but all the\r
-  fields in this payload are still in host order and need call Ikev2EncodePayload()\r
-  to convert those fields from the host order to network order beforing sending it.\r
-\r
-  @param[in]  IkeSaSession      Pointer to IKE SA Session to be used for Delete payload\r
-                                generation.\r
-  @param[in]  NextPayload       The next paylaod type in NextPayload field of\r
-                                the Delete payload.\r
-  @param[in]  CfgType           The attribute type in the Configuration attribute.\r
-\r
-  @retval Pointer to IKE CP Payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateCpPayload (\r
-  IN IKEV2_SA_SESSION  *IkeSaSession,\r
-  IN UINT8             NextPayload,\r
-  IN UINT8             CfgType\r
-  )\r
-{\r
-  IKE_PAYLOAD           *CpPayload;\r
-  IKEV2_CFG             *Cfg;\r
-  UINT16                PayloadLen;\r
-  IKEV2_CFG_ATTRIBUTES  *CfgAttributes;\r
-\r
-  //\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C! RESERVED    !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !   CFG Type    !                    RESERVED                   !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    !                                                               !\r
-  //    ~                   Configuration Attributes                    ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  PayloadLen = (UINT16) (sizeof (IKEV2_CFG) + sizeof (IKEV2_CFG_ATTRIBUTES));\r
-  Cfg        = (IKEV2_CFG *) AllocateZeroPool (PayloadLen);\r
-\r
-  if (Cfg == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  CfgAttributes = (IKEV2_CFG_ATTRIBUTES *)((UINT8 *)Cfg + sizeof (IKEV2_CFG));\r
-\r
-  //\r
-  // Only generate the configuration payload with an empty INTERNAL_IP4_ADDRESS\r
-  // or INTERNAL_IP6_ADDRESS.\r
-  //\r
-\r
-  Cfg->Header.NextPayload   = NextPayload;\r
-  Cfg->Header.PayloadLength = PayloadLen;\r
-  Cfg->CfgType              = IKEV2_CFG_TYPE_REQUEST;\r
-\r
-  CfgAttributes->AttritType  = CfgType;\r
-  CfgAttributes->ValueLength = 0;\r
-\r
-  CpPayload = IkePayloadAlloc ();\r
-  if (CpPayload == NULL) {\r
-    if (Cfg != NULL) {\r
-      FreePool (Cfg);\r
-    }\r
-    return NULL;\r
-  }\r
-\r
-  CpPayload->PayloadType = IKEV2_PAYLOAD_TYPE_CP;\r
-  CpPayload->PayloadBuf  = (UINT8 *) Cfg;\r
-  CpPayload->PayloadSize = PayloadLen;\r
-  return CpPayload;\r
-}\r
-\r
-/**\r
-  Parser the Notify Cookie payload.\r
-\r
-  This function parses the Notify Cookie payload.If the Notify ProtocolId is not\r
-  IPSEC_PROTO_ISAKMP or if the SpiSize is not zero or if the MessageType is not\r
-  the COOKIE, return EFI_INVALID_PARAMETER.\r
-\r
-  @param[in]      IkeNCookie    Pointer to the IKE_PAYLOAD which contians the\r
-                                Notify Cookie payload.\r
-                                the Notify payload.\r
-  @param[in, out] IkeSaSession  Pointer to the relevant IKE SA Session.\r
-\r
-  @retval EFI_SUCCESS           The Notify Cookie Payload is valid.\r
-  @retval EFI_INVALID_PARAMETER The Notify Cookie Payload is invalid.\r
-  @retval EFI_OUT_OF_RESOURCE   The required resource can't be allocated.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2ParserNotifyCookiePayload (\r
-  IN     IKE_PAYLOAD      *IkeNCookie,\r
-  IN OUT IKEV2_SA_SESSION *IkeSaSession\r
-  )\r
-{\r
-  IKEV2_NOTIFY      *NotifyPayload;\r
-  UINTN             NotifyDataSize;\r
-\r
-  NotifyPayload = (IKEV2_NOTIFY *)IkeNCookie->PayloadBuf;\r
-\r
-  if ((NotifyPayload->ProtocolId != IPSEC_PROTO_ISAKMP) ||\r
-      (NotifyPayload->SpiSize != 0) ||\r
-      (NotifyPayload->MessageType != IKEV2_NOTIFICATION_COOKIE)\r
-      ) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  NotifyDataSize        = NotifyPayload->Header.PayloadLength - sizeof (IKEV2_NOTIFY);\r
-  IkeSaSession->NCookie = AllocateZeroPool (NotifyDataSize);\r
-  if (IkeSaSession->NCookie == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  IkeSaSession->NCookieSize = NotifyDataSize;\r
-\r
-  CopyMem (\r
-    IkeSaSession->NCookie,\r
-    (UINT8 *)NotifyPayload + sizeof (IKEV2_NOTIFY),\r
-    NotifyDataSize\r
-    );\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Generate the Certificate payload or Certificate Request Payload.\r
-\r
-  Since the Certificate Payload structure is same with Certificate Request Payload,\r
-  the only difference is that one contains the Certificate Data, other contains\r
-  the acceptable certificateion CA. This function generate Certificate payload\r
-  or Certificate Request Payload defined in RFC 4306, but all the fields\r
-  in the payload are still in host order and need call Ikev2EncodePayload()\r
-  to convert those fields from the host order to network order beforing sending it.\r
-\r
-  @param[in]  IkeSaSession      Pointer to IKE SA Session to be used of Delete payload\r
-                                generation.\r
-  @param[in]  NextPayload       The next paylaod type in NextPayload field of\r
-                                the Delete payload.\r
-  @param[in]  Certificate       Pointer of buffer contains the certification data.\r
-  @param[in]  CertificateLen    The length of Certificate in byte.\r
-  @param[in]  EncodeType        Specified the Certificate Encodeing which is defined\r
-                                in RFC 4306.\r
-  @param[in]  IsRequest         To indicate create Certificate Payload or Certificate\r
-                                Request Payload. If it is TURE, create Certificate\r
-                                Request Payload. Otherwise, create Certificate Payload.\r
-\r
-  @retval  a Pointer to IKE Payload whose payload buffer containing the Certificate\r
-           payload or Certificated Request payload.\r
-\r
-**/\r
-IKE_PAYLOAD *\r
-Ikev2GenerateCertificatePayload (\r
-  IN IKEV2_SA_SESSION  *IkeSaSession,\r
-  IN UINT8             NextPayload,\r
-  IN UINT8             *Certificate,\r
-  IN UINTN             CertificateLen,\r
-  IN UINT8             EncodeType,\r
-  IN BOOLEAN           IsRequest\r
-  )\r
-{\r
-  IKE_PAYLOAD           *CertPayload;\r
-  IKEV2_CERT            *Cert;\r
-  UINT16                PayloadLen;\r
-  UINT8                 *PublicKey;\r
-  UINTN                 PublicKeyLen;\r
-  HASH_DATA_FRAGMENT    Fragment[1];\r
-  UINT8                 *HashData;\r
-  UINTN                 HashDataSize;\r
-  EFI_STATUS            Status;\r
-\r
-  //\r
-  //                         1                   2                   3\r
-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Next Payload  !C!  RESERVED   !         Payload Length        !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //    ! Cert Encoding !                                               !\r
-  //    +-+-+-+-+-+-+-+-+                                               !\r
-  //    ~                       Certificate Data/Authority              ~\r
-  //    !                                                               !\r
-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-\r
-  Status       = EFI_SUCCESS;\r
-  PublicKey    = NULL;\r
-  PublicKeyLen = 0;\r
-\r
-  if (!IsRequest) {\r
-    PayloadLen = (UINT16) (sizeof (IKEV2_CERT) + CertificateLen);\r
-  } else {\r
-    //\r
-    // SHA1 Hash length is 20.\r
-    //\r
-    PayloadLen = (UINT16) (sizeof (IKEV2_CERT) + 20);\r
-  }\r
-\r
-  Cert = AllocateZeroPool (PayloadLen);\r
-  if (Cert == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Generate Certificate Payload or Certificate Request Payload.\r
-  //\r
-  Cert->Header.NextPayload   = NextPayload;\r
-  Cert->Header.PayloadLength = PayloadLen;\r
-  Cert->CertEncoding         = EncodeType;\r
-  if (!IsRequest) {\r
-    CopyMem (\r
-      ((UINT8 *)Cert) + sizeof (IKEV2_CERT),\r
-      Certificate,\r
-      CertificateLen\r
-      );\r
-  } else {\r
-    Status = IpSecCryptoIoGetPublicKeyFromCert (\r
-               Certificate,\r
-               CertificateLen,\r
-               &PublicKey,\r
-               &PublicKeyLen\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_EXIT;\r
-    }\r
-\r
-    Fragment[0].Data     = PublicKey;\r
-    Fragment[0].DataSize = PublicKeyLen;\r
-    HashDataSize      = IpSecGetHmacDigestLength (IKE_AALG_SHA1HMAC);\r
-    HashData          = AllocateZeroPool (HashDataSize);\r
-    if (HashData == NULL) {\r
-      goto ON_EXIT;\r
-    }\r
-\r
-    Status = IpSecCryptoIoHash (\r
-               IKE_AALG_SHA1HMAC,\r
-               Fragment,\r
-               1,\r
-               HashData,\r
-               HashDataSize\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_EXIT;\r
-    }\r
-\r
-    CopyMem (\r
-      ((UINT8 *)Cert) + sizeof (IKEV2_CERT),\r
-      HashData,\r
-      HashDataSize\r
-      );\r
-  }\r
-\r
-  CertPayload = IkePayloadAlloc ();\r
-  if (CertPayload == NULL) {\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  if (!IsRequest) {\r
-    CertPayload->PayloadType = IKEV2_PAYLOAD_TYPE_CERT;\r
-  } else {\r
-    CertPayload->PayloadType = IKEV2_PAYLOAD_TYPE_CERTREQ;\r
-  }\r
-\r
-  CertPayload->PayloadBuf  = (UINT8 *) Cert;\r
-  CertPayload->PayloadSize = PayloadLen;\r
-  return CertPayload;\r
-\r
-ON_EXIT:\r
-  if (Cert != NULL) {\r
-    FreePool (Cert);\r
-  }\r
-  if (PublicKey != NULL) {\r
-    FreePool (PublicKey);\r
-  }\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Remove and free all IkePayloads in the specified IkePacket.\r
-\r
-  @param[in] IkePacket   The pointer of IKE_PACKET.\r
-\r
-**/\r
-VOID\r
-ClearAllPayloads (\r
-  IN IKE_PACKET     *IkePacket\r
-  )\r
-{\r
-  LIST_ENTRY      *PayloadEntry;\r
-  IKE_PAYLOAD     *IkePayload;\r
-  //\r
-  // remove all payloads from list and free each payload.\r
-  //\r
-  while (!IsListEmpty (&IkePacket->PayloadList)) {\r
-    PayloadEntry  = IkePacket->PayloadList.ForwardLink;\r
-    IkePayload    = IKE_PAYLOAD_BY_PACKET (PayloadEntry);\r
-    IKE_PACKET_REMOVE_PAYLOAD (IkePacket, IkePayload);\r
-    IkePayloadFree (IkePayload);\r
-  }\r
-}\r
-\r
-/**\r
-  Transfer the intrnal data structure IKEV2_SA_DATA to IKEV2_SA structure defined in RFC.\r
-\r
-  @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the SA Session.\r
-  @param[in] SaData        Pointer to IKEV2_SA_DATA to be transfered.\r
-\r
-  @retval  return the pointer of IKEV2_SA.\r
-\r
-**/\r
-IKEV2_SA*\r
-Ikev2EncodeSa (\r
-  IN IKEV2_SESSION_COMMON *SessionCommon,\r
-  IN IKEV2_SA_DATA        *SaData\r
-  )\r
-{\r
-  IKEV2_SA              *Sa;\r
-  UINTN                 SaSize;\r
-  IKEV2_PROPOSAL_DATA   *ProposalData;\r
-  IKEV2_TRANSFORM_DATA  *TransformData;\r
-  UINTN                 TotalTransforms;\r
-  UINTN                 SaAttrsSize;\r
-  UINTN                 TransformsSize;\r
-  UINTN                 TransformSize;\r
-  UINTN                 ProposalsSize;\r
-  UINTN                 ProposalSize;\r
-  UINTN                 ProposalIndex;\r
-  UINTN                 TransformIndex;\r
-  IKE_SA_ATTRIBUTE      *SaAttribute;\r
-  IKEV2_PROPOSAL        *Proposal;\r
-  IKEV2_TRANSFORM       *Transform;\r
-\r
-  //\r
-  // Transform IKE_SA_DATA structure to IKE_SA Payload.\r
-  // Header length is host order.\r
-  // The returned IKE_SA struct should be freed by caller.\r
-  //\r
-  TotalTransforms = 0;\r
-  //\r
-  // Calculate the Proposal numbers and Transform numbers.\r
-  //\r
-  for (ProposalIndex = 0; ProposalIndex < SaData->NumProposals; ProposalIndex++) {\r
-\r
-    ProposalData     = (IKEV2_PROPOSAL_DATA *) (SaData + 1) + ProposalIndex;\r
-    TotalTransforms += ProposalData->NumTransforms;\r
-\r
-  }\r
-  SaSize = sizeof (IKEV2_SA) +\r
-           SaData->NumProposals * sizeof (IKEV2_PROPOSAL) +\r
-           TotalTransforms * (sizeof (IKEV2_TRANSFORM) + MAX_SA_ATTRS_SIZE);\r
-  //\r
-  // Allocate buffer for IKE_SA.\r
-  //\r
-  Sa = AllocateZeroPool (SaSize);\r
-  if (Sa == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  CopyMem (Sa, SaData, sizeof (IKEV2_SA));\r
-  Sa->Header.PayloadLength  = (UINT16) sizeof (IKEV2_SA);\r
-  ProposalsSize             = 0;\r
-  Proposal                  = (IKEV2_PROPOSAL *) (Sa + 1);\r
-\r
-  //\r
-  // Set IKE_PROPOSAL\r
-  //\r
-  ProposalData  = (IKEV2_PROPOSAL_DATA *) (SaData + 1);\r
-  for (ProposalIndex = 0; ProposalIndex < SaData->NumProposals; ProposalIndex++) {\r
-    Proposal->ProposalIndex   = ProposalData->ProposalIndex;\r
-    Proposal->ProtocolId      = ProposalData->ProtocolId;\r
-    Proposal->NumTransforms   = ProposalData->NumTransforms;\r
-\r
-    if (ProposalData->Spi == 0) {\r
-      Proposal->SpiSize = 0;\r
-    } else {\r
-      Proposal->SpiSize           = 4;\r
-      *(UINT32 *) (Proposal + 1)  = HTONL (*((UINT32*)ProposalData->Spi));\r
-    }\r
-\r
-    TransformsSize  = 0;\r
-    Transform       = (IKEV2_TRANSFORM *) ((UINT8 *) (Proposal + 1) + Proposal->SpiSize);\r
-\r
-    //\r
-    // Set IKE_TRANSFORM\r
-    //\r
-    for (TransformIndex = 0; TransformIndex < ProposalData->NumTransforms; TransformIndex++) {\r
-      TransformData               = (IKEV2_TRANSFORM_DATA *) (ProposalData + 1) + TransformIndex;\r
-      Transform->TransformType    = TransformData->TransformType;\r
-      Transform->TransformId      = HTONS (TransformData->TransformId);\r
-      SaAttrsSize                 = 0;\r
-\r
-      //\r
-      // If the Encryption Algorithm is variable key length set the key length in attribute.\r
-      // Note that only a single attribute type (Key Length) is defined and it is fixed length.\r
-      //\r
-      if (Transform->TransformType == IKEV2_TRANSFORM_TYPE_ENCR && TransformData->Attribute.Attr.AttrValue != 0) {\r
-        SaAttribute                 = (IKE_SA_ATTRIBUTE *) (Transform + 1);\r
-        SaAttribute->AttrType       = HTONS (IKEV2_ATTRIBUTE_TYPE_KEYLEN | SA_ATTR_FORMAT_BIT);\r
-        SaAttribute->Attr.AttrValue = HTONS (TransformData->Attribute.Attr.AttrValue);\r
-        SaAttrsSize                 = sizeof (IKE_SA_ATTRIBUTE);\r
-      }\r
-\r
-      //\r
-      // If the Integrity Algorithm is variable key length set the key length in attribute.\r
-      //\r
-      if (Transform->TransformType == IKEV2_TRANSFORM_TYPE_INTEG && TransformData->Attribute.Attr.AttrValue != 0) {\r
-        SaAttribute                 = (IKE_SA_ATTRIBUTE *) (Transform + 1);\r
-        SaAttribute->AttrType       = HTONS (IKEV2_ATTRIBUTE_TYPE_KEYLEN | SA_ATTR_FORMAT_BIT);\r
-        SaAttribute->Attr.AttrValue = HTONS (TransformData->Attribute.Attr.AttrValue);\r
-        SaAttrsSize                 = sizeof (IKE_SA_ATTRIBUTE);\r
-      }\r
-\r
-      TransformSize                 = sizeof (IKEV2_TRANSFORM) + SaAttrsSize;\r
-      TransformsSize               += TransformSize;\r
-\r
-      Transform->Header.NextPayload   = IKE_TRANSFORM_NEXT_PAYLOAD_MORE;\r
-      Transform->Header.PayloadLength = HTONS ((UINT16)TransformSize);\r
-\r
-      if (TransformIndex == ((UINT32)ProposalData->NumTransforms - 1)) {\r
-        Transform->Header.NextPayload = IKE_TRANSFORM_NEXT_PAYLOAD_NONE;\r
-      }\r
-\r
-      Transform     = (IKEV2_TRANSFORM *)((UINT8 *) Transform + TransformSize);\r
-    }\r
-\r
-    //\r
-    // Set Proposal's Generic Header.\r
-    //\r
-    ProposalSize                   = sizeof (IKEV2_PROPOSAL) + Proposal->SpiSize + TransformsSize;\r
-    ProposalsSize                 += ProposalSize;\r
-    Proposal->Header.NextPayload   = IKE_PROPOSAL_NEXT_PAYLOAD_MORE;\r
-    Proposal->Header.PayloadLength = HTONS ((UINT16)ProposalSize);\r
-\r
-    if (ProposalIndex == (UINTN)(SaData->NumProposals - 1)) {\r
-      Proposal->Header.NextPayload = IKE_PROPOSAL_NEXT_PAYLOAD_NONE;\r
-    }\r
-\r
-    //\r
-    // Point to next Proposal Payload\r
-    //\r
-    Proposal     = (IKEV2_PROPOSAL *) ((UINT8 *) Proposal + ProposalSize);\r
-    ProposalData = (IKEV2_PROPOSAL_DATA *)(((UINT8 *)ProposalData) + sizeof (IKEV2_PROPOSAL_DATA) + (TransformIndex * sizeof (IKEV2_TRANSFORM_DATA)));\r
-  }\r
-  //\r
-  // Set SA's Generic Header.\r
-  //\r
-  Sa->Header.PayloadLength = (UINT16) (Sa->Header.PayloadLength + ProposalsSize);\r
-  return Sa;\r
-}\r
-\r
-/**\r
-  Decode SA payload.\r
-\r
-  This function converts the received SA payload to internal data structure.\r
-\r
-  @param[in]  SessionCommon       Pointer to IKE Common Session used to decode the SA\r
-                                  Payload.\r
-  @param[in]  Sa                  Pointer to SA Payload\r
-\r
-  @return a Pointer to internal data structure for SA payload.\r
-\r
-**/\r
-IKEV2_SA_DATA *\r
-Ikev2DecodeSa (\r
-  IN IKEV2_SESSION_COMMON *SessionCommon,\r
-  IN IKEV2_SA             *Sa\r
-  )\r
-{\r
-  IKEV2_SA_DATA         *SaData;\r
-  EFI_STATUS            Status;\r
-  IKEV2_PROPOSAL        *Proposal;\r
-  IKEV2_TRANSFORM       *Transform;\r
-  UINTN                 TotalProposals;\r
-  UINTN                 TotalTransforms;\r
-  UINTN                 ProposalNextPayloadSum;\r
-  UINTN                 ProposalIndex;\r
-  UINTN                 TransformIndex;\r
-  UINTN                 SaRemaining;\r
-  UINT16                ProposalSize;\r
-  UINTN                 ProposalRemaining;\r
-  UINT16                TransformSize;\r
-  UINTN                 SaAttrRemaining;\r
-  IKE_SA_ATTRIBUTE      *SaAttribute;\r
-  IKEV2_PROPOSAL_DATA   *ProposalData;\r
-  IKEV2_TRANSFORM_DATA  *TransformData;\r
-  UINT8                 *Spi;\r
-\r
-  //\r
-  // Transfrom from IKE_SA payload to IKE_SA_DATA structure.\r
-  // Header length NTOH is already done\r
-  // The returned IKE_SA_DATA should be freed by caller\r
-  //\r
-  SaData    = NULL;\r
-  Status    = EFI_SUCCESS;\r
-\r
-  //\r
-  // First round sanity check and size calculae\r
-  //\r
-  TotalProposals         = 0;\r
-  TotalTransforms        = 0;\r
-  ProposalNextPayloadSum = 0;\r
-  SaRemaining            = Sa->Header.PayloadLength - sizeof (IKEV2_SA);// Point to current position in SA\r
-  Proposal               = (IKEV2_PROPOSAL *)((IKEV2_SA *)(Sa)+1);\r
-\r
-  //\r
-  // Calculate the number of Proposal payload and the total numbers of\r
-  // Transforms payload (the transforms in all proposal payload).\r
-  //\r
-  while (SaRemaining > sizeof (IKEV2_PROPOSAL)) {\r
-    ProposalSize = NTOHS (Proposal->Header.PayloadLength);\r
-    if (SaRemaining < ProposalSize) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    if (Proposal->SpiSize != 0 && Proposal->SpiSize != 4) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    TotalProposals++;\r
-    TotalTransforms        += Proposal->NumTransforms;\r
-    SaRemaining            -= ProposalSize;\r
-    ProposalNextPayloadSum += Proposal->Header.NextPayload;\r
-    Proposal                = IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal, ProposalSize);\r
-  }\r
-\r
-  //\r
-  // Check the proposal number.\r
-  // The proposal Substructure, the NextPayLoad field indicates : 0 (last) or 2 (more)\r
-  // which Specifies whether this is the last Proposal Substructure in the SA.\r
-  // Here suming all Proposal NextPayLoad field to check the proposal number is correct\r
-  // or not.\r
-  //\r
-  if (TotalProposals == 0 ||\r
-      (TotalProposals - 1) * IKE_PROPOSAL_NEXT_PAYLOAD_MORE != ProposalNextPayloadSum\r
-      ) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto Exit;\r
-  }\r
-\r
-  //\r
-  // Second round sanity check and decode. Transform the SA payload into\r
-  // a IKE_SA_DATA structure.\r
-  //\r
-  SaData = (IKEV2_SA_DATA *) AllocateZeroPool (\r
-                               sizeof (IKEV2_SA_DATA) +\r
-                               TotalProposals * sizeof (IKEV2_PROPOSAL_DATA) +\r
-                               TotalTransforms * sizeof (IKEV2_TRANSFORM_DATA)\r
-                               );\r
-  if (SaData == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
-\r
-  CopyMem (SaData, Sa, sizeof (IKEV2_SA));\r
-  SaData->NumProposals        = TotalProposals;\r
-  ProposalData                = (IKEV2_PROPOSAL_DATA *) (SaData + 1);\r
-\r
-  //\r
-  // Proposal Payload\r
-  //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   ! Next Payload  !   RESERVED    !         Payload Length        !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !  Proposal #   !  Protocol-Id  !    SPI Size   !# of Transforms!\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //   !                        SPI (variable)                         !\r
-  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-  //\r
-  for (ProposalIndex = 0, Proposal = IKEV2_SA_FIRST_PROPOSAL (Sa);\r
-       ProposalIndex < TotalProposals;\r
-       ProposalIndex++\r
-       ) {\r
-\r
-    //\r
-    // TODO: check ProposalId\r
-    //\r
-    ProposalData->ProposalIndex   = Proposal->ProposalIndex;\r
-    ProposalData->ProtocolId      = Proposal->ProtocolId;\r
-    if (Proposal->SpiSize == 0) {\r
-      ProposalData->Spi = 0;\r
-    } else {\r
-      //\r
-      // SpiSize == 4\r
-      //\r
-      Spi = AllocateZeroPool (Proposal->SpiSize);\r
-      if (Spi == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Exit;\r
-      }\r
-\r
-      CopyMem (Spi, (UINT32 *) (Proposal + 1), Proposal->SpiSize);\r
-      *((UINT32*) Spi) = NTOHL (*((UINT32*) Spi));\r
-      ProposalData->Spi = Spi;\r
-    }\r
-\r
-    ProposalData->NumTransforms = Proposal->NumTransforms;\r
-    ProposalSize                = NTOHS (Proposal->Header.PayloadLength);\r
-    ProposalRemaining           = ProposalSize;\r
-    //\r
-    // Transform Payload\r
-    //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
-    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    //   ! Next Payload  !   RESERVED    !         Payload Length        !\r
-    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    //   !Transform Type !   RESERVED    !         Transform ID          !\r
-    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    //   !                                                               !\r
-    //   ~                        SA Attributes                          ~\r
-    //   !                                                               !\r
-    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    //\r
-    Transform = IKEV2_PROPOSAL_FIRST_TRANSFORM (Proposal);\r
-    for (TransformIndex = 0; TransformIndex < Proposal->NumTransforms; TransformIndex++) {\r
-\r
-      //\r
-      // Transfer the IKEV2_TRANSFORM structure into internal IKEV2_TRANSFORM_DATA struture.\r
-      //\r
-      TransformData                   = (IKEV2_TRANSFORM_DATA *) (ProposalData + 1) + TransformIndex;\r
-      TransformData->TransformId      = NTOHS (Transform->TransformId);\r
-      TransformData->TransformType    = Transform->TransformType;\r
-      TransformSize                   = NTOHS (Transform->Header.PayloadLength);\r
-      //\r
-      // Check the Proposal Data is correct.\r
-      //\r
-      if (ProposalRemaining < TransformSize) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Exit;\r
-      }\r
-\r
-      //\r
-      // Check if the Transform payload includes Attribution.\r
-      //\r
-      SaAttrRemaining = TransformSize - sizeof (IKEV2_TRANSFORM);\r
-\r
-      //\r
-      // According to RFC 4603, currently only the Key length attribute type is\r
-      // supported. For each Transform, there is only one attributeion.\r
-      //\r
-      if (SaAttrRemaining > 0) {\r
-        if (SaAttrRemaining != sizeof (IKE_SA_ATTRIBUTE)) {\r
-          Status = EFI_INVALID_PARAMETER;\r
-          goto Exit;\r
-        }\r
-        SaAttribute                             = (IKE_SA_ATTRIBUTE *) ((IKEV2_TRANSFORM *)(Transform) + 1);\r
-        TransformData->Attribute.AttrType       = (UINT16)((NTOHS (SaAttribute->AttrType))  & ~SA_ATTR_FORMAT_BIT);\r
-        TransformData->Attribute.Attr.AttrValue = NTOHS (SaAttribute->Attr.AttrValue);\r
-\r
-        //\r
-        // Currently, only supports the Key Length Attribution.\r
-        //\r
-        if (TransformData->Attribute.AttrType != IKEV2_ATTRIBUTE_TYPE_KEYLEN) {\r
-          Status = EFI_INVALID_PARAMETER;\r
-          goto Exit;\r
-        }\r
-      }\r
-\r
-      //\r
-      // Move to next Transform\r
-      //\r
-      Transform = IKEV2_NEXT_TRANSFORM_WITH_SIZE (Transform, TransformSize);\r
-    }\r
-    Proposal     = IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal, ProposalSize);\r
-    ProposalData = (IKEV2_PROPOSAL_DATA *) ((UINT8 *)(ProposalData + 1) +\r
-                                                ProposalData->NumTransforms *\r
-                                                sizeof (IKEV2_TRANSFORM_DATA));\r
-  }\r
-\r
-Exit:\r
-  if (EFI_ERROR (Status) && SaData != NULL) {\r
-    FreePool (SaData);\r
-    SaData = NULL;\r
-  }\r
-  return SaData;\r
-}\r
-\r
-/**\r
-  General interface of payload encoding.\r
-\r
-  This function encodes the internal data structure into payload which\r
-  is defined in RFC 4306. The IkePayload->PayloadBuf is used to store both the input\r
-  payload and converted payload. Only the SA payload use the interal structure\r
-  to store the attribute. Other payload use structure which is same with the RFC\r
-  defined, for this kind payloads just do host order to network order change of\r
-  some fields.\r
-\r
-  @param[in]      SessionCommon       Pointer to IKE Session Common used to encode the payload.\r
-  @param[in, out] IkePayload          Pointer to IKE payload to be encoded as input, and\r
-                                      store the encoded result as output.\r
-\r
-  @retval EFI_INVALID_PARAMETER  Meet error when encoding the SA payload.\r
-  @retval EFI_SUCCESS            Encoded successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2EncodePayload (\r
-  IN     UINT8               *SessionCommon,\r
-  IN OUT IKE_PAYLOAD         *IkePayload\r
-  )\r
-{\r
-  IKEV2_SA_DATA               *SaData;\r
-  IKEV2_SA                    *SaPayload;\r
-  IKEV2_COMMON_PAYLOAD_HEADER *PayloadHdr;\r
-  IKEV2_NOTIFY                *NotifyPayload;\r
-  IKEV2_DELETE                *DeletePayload;\r
-  IKEV2_KEY_EXCHANGE          *KeyPayload;\r
-  IKEV2_TS                    *TsPayload;\r
-  IKEV2_CFG_ATTRIBUTES        *CfgAttribute;\r
-  UINT8                       *TsBuffer;\r
-  UINT8                       Index;\r
-  TRAFFIC_SELECTOR            *TrafficSelector;\r
-\r
-  //\r
-  // Transform the Internal IKE structure to IKE payload.\r
-  // Only the SA payload use the interal structure to store the attribute.\r
-  // Other payload use structure which same with the RFC defined, so there is\r
-  // no need to tranform them to IKE payload.\r
-  //\r
-  switch (IkePayload->PayloadType) {\r
-  case IKEV2_PAYLOAD_TYPE_SA:\r
-    //\r
-    // Transform IKE_SA_DATA to IK_SA payload\r
-    //\r
-    SaData    = (IKEV2_SA_DATA *) IkePayload->PayloadBuf;\r
-    SaPayload = Ikev2EncodeSa ((IKEV2_SESSION_COMMON *) SessionCommon, SaData);\r
-\r
-    if (SaPayload == NULL) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-    if (!IkePayload->IsPayloadBufExt) {\r
-      FreePool (IkePayload->PayloadBuf);\r
-    }\r
-    IkePayload->PayloadBuf      = (UINT8 *) SaPayload;\r
-    IkePayload->IsPayloadBufExt = FALSE;\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_NOTIFY:\r
-    NotifyPayload               = (IKEV2_NOTIFY *) IkePayload->PayloadBuf;\r
-    NotifyPayload->MessageType  = HTONS (NotifyPayload->MessageType);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_DELETE:\r
-    DeletePayload           = (IKEV2_DELETE *) IkePayload->PayloadBuf;\r
-    DeletePayload->NumSpis  = HTONS (DeletePayload->NumSpis);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_KE:\r
-    KeyPayload              = (IKEV2_KEY_EXCHANGE *) IkePayload->PayloadBuf;\r
-    KeyPayload->DhGroup     = HTONS (KeyPayload->DhGroup);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_TS_INIT:\r
-  case IKEV2_PAYLOAD_TYPE_TS_RSP:\r
-    TsPayload = (IKEV2_TS *) IkePayload->PayloadBuf;\r
-    TsBuffer  = IkePayload->PayloadBuf + sizeof (IKEV2_TS);\r
-\r
-    for (Index = 0; Index < TsPayload->TSNumbers; Index++) {\r
-      TrafficSelector = (TRAFFIC_SELECTOR *) TsBuffer;\r
-      TsBuffer        = TsBuffer + TrafficSelector->SelecorLen;\r
-      //\r
-      // Host order to network order\r
-      //\r
-      TrafficSelector->SelecorLen = HTONS (TrafficSelector->SelecorLen);\r
-      TrafficSelector->StartPort  = HTONS (TrafficSelector->StartPort);\r
-      TrafficSelector->EndPort    = HTONS (TrafficSelector->EndPort);\r
-\r
-    }\r
-\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_CP:\r
-    CfgAttribute = (IKEV2_CFG_ATTRIBUTES *)(((IKEV2_CFG *) IkePayload->PayloadBuf) + 1);\r
-    CfgAttribute->AttritType  = HTONS (CfgAttribute->AttritType);\r
-    CfgAttribute->ValueLength = HTONS (CfgAttribute->ValueLength);\r
-\r
-  case IKEV2_PAYLOAD_TYPE_ID_INIT:\r
-  case IKEV2_PAYLOAD_TYPE_ID_RSP:\r
-  case IKEV2_PAYLOAD_TYPE_AUTH:\r
-  default:\r
-    break;\r
-  }\r
-\r
-  PayloadHdr  = (IKEV2_COMMON_PAYLOAD_HEADER *) IkePayload->PayloadBuf;\r
-  IkePayload->PayloadSize = PayloadHdr->PayloadLength;\r
-  PayloadHdr->PayloadLength = HTONS (PayloadHdr->PayloadLength);\r
-  IKEV2_DUMP_PAYLOAD (IkePayload);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  The general interface for decoding Payload.\r
-\r
-  This function converts the received Payload into internal structure.\r
-\r
-  @param[in]      SessionCommon     Pointer to IKE Session Common used for decoding.\r
-  @param[in, out] IkePayload        Pointer to IKE payload to be decoded as input, and\r
-                                    store the decoded result as output.\r
-\r
-  @retval EFI_INVALID_PARAMETER  Meet error when decoding the SA payload.\r
-  @retval EFI_SUCCESS            Decoded successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2DecodePayload (\r
-  IN     UINT8       *SessionCommon,\r
-  IN OUT IKE_PAYLOAD *IkePayload\r
-  )\r
-{\r
-  IKEV2_COMMON_PAYLOAD_HEADER *PayloadHdr;\r
-  UINT16                      PayloadSize;\r
-  UINT8                       PayloadType;\r
-  IKEV2_SA_DATA               *SaData;\r
-  EFI_STATUS                  Status;\r
-  IKEV2_NOTIFY                *NotifyPayload;\r
-  IKEV2_DELETE                *DeletePayload;\r
-  UINT16                      TsTotalSize;\r
-  TRAFFIC_SELECTOR            *TsSelector;\r
-  IKEV2_TS                    *TsPayload;\r
-  IKEV2_KEY_EXCHANGE          *KeyPayload;\r
-  IKEV2_CFG_ATTRIBUTES        *CfgAttribute;\r
-  UINT8                       Index;\r
-\r
-  //\r
-  // Transform the IKE payload to Internal IKE structure.\r
-  // Only the SA payload and Hash Payload use the interal\r
-  // structure to store the attribute. Other payloads use\r
-  // structure which is same with the definitions in RFC,\r
-  // so there is no need to tranform them to internal IKE\r
-  // structure.\r
-  //\r
-  Status      = EFI_SUCCESS;\r
-  PayloadSize = (UINT16) IkePayload->PayloadSize;\r
-  PayloadType = IkePayload->PayloadType;\r
-  PayloadHdr  = (IKEV2_COMMON_PAYLOAD_HEADER *) IkePayload->PayloadBuf;\r
-  //\r
-  // The PayloadSize is the size of whole payload.\r
-  // Replace HTONS operation to assignment statements, since the result is same.\r
-  //\r
-  PayloadHdr->PayloadLength = PayloadSize;\r
-\r
-  IKEV2_DUMP_PAYLOAD (IkePayload);\r
-  switch (PayloadType) {\r
-  case IKEV2_PAYLOAD_TYPE_SA:\r
-    if (PayloadSize < sizeof (IKEV2_SA)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    SaData = Ikev2DecodeSa ((IKEV2_SESSION_COMMON *) SessionCommon, (IKEV2_SA *) PayloadHdr);\r
-    if (SaData == NULL) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    if (!IkePayload->IsPayloadBufExt) {\r
-      FreePool (IkePayload->PayloadBuf);\r
-    }\r
-\r
-    IkePayload->PayloadBuf      = (UINT8 *) SaData;\r
-    IkePayload->IsPayloadBufExt = FALSE;\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_ID_INIT:\r
-  case IKEV2_PAYLOAD_TYPE_ID_RSP :\r
-    if (PayloadSize < sizeof (IKEV2_ID)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_NOTIFY:\r
-    if (PayloadSize < sizeof (IKEV2_NOTIFY)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    NotifyPayload               = (IKEV2_NOTIFY *) PayloadHdr;\r
-    NotifyPayload->MessageType  = NTOHS (NotifyPayload->MessageType);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_DELETE:\r
-    if (PayloadSize < sizeof (IKEV2_DELETE)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    DeletePayload           = (IKEV2_DELETE *) PayloadHdr;\r
-    DeletePayload->NumSpis  = NTOHS (DeletePayload->NumSpis);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_AUTH:\r
-    if (PayloadSize < sizeof (IKEV2_AUTH)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_KE:\r
-    KeyPayload              = (IKEV2_KEY_EXCHANGE *) IkePayload->PayloadBuf;\r
-    KeyPayload->DhGroup     = HTONS (KeyPayload->DhGroup);\r
-    break;\r
-\r
-  case IKEV2_PAYLOAD_TYPE_TS_INIT:\r
-  case IKEV2_PAYLOAD_TYPE_TS_RSP :\r
-    TsTotalSize = 0;\r
-    if (PayloadSize < sizeof (IKEV2_TS)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // Parse each traffic selector and transfer network-order to host-order\r
-    //\r
-    TsPayload   = (IKEV2_TS *) IkePayload->PayloadBuf;\r
-    TsSelector  = (TRAFFIC_SELECTOR *) (IkePayload->PayloadBuf + sizeof (IKEV2_TS));\r
-\r
-    for (Index = 0; Index < TsPayload->TSNumbers; Index++) {\r
-      TsSelector->SelecorLen  = NTOHS (TsSelector->SelecorLen);\r
-      TsSelector->StartPort   = NTOHS (TsSelector->StartPort);\r
-      TsSelector->EndPort     = NTOHS (TsSelector->EndPort);\r
-\r
-      TsTotalSize             = (UINT16) (TsTotalSize + TsSelector->SelecorLen);\r
-      TsSelector              = (TRAFFIC_SELECTOR *) ((UINT8 *) TsSelector + TsSelector->SelecorLen);\r
-    }\r
-    //\r
-    // Check if the total size of Traffic Selectors is correct.\r
-    //\r
-    if (TsTotalSize != PayloadSize - sizeof(IKEV2_TS)) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-  case IKEV2_PAYLOAD_TYPE_CP:\r
-    CfgAttribute = (IKEV2_CFG_ATTRIBUTES *)(((IKEV2_CFG *) IkePayload->PayloadBuf) + 1);\r
-    CfgAttribute->AttritType  = NTOHS (CfgAttribute->AttritType);\r
-    CfgAttribute->ValueLength = NTOHS (CfgAttribute->ValueLength);\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
- Exit:\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Decode the IKE packet.\r
-\r
-  This function first decrypts the IKE packet if needed , then separates the whole\r
-  IKE packet from the IkePacket->PayloadBuf into IkePacket payload list.\r
-\r
-  @param[in]      SessionCommon          Pointer to IKEV1_SESSION_COMMON containing\r
-                                         some parameter used by IKE packet decoding.\r
-  @param[in, out] IkePacket              The IKE Packet to be decoded on input, and\r
-                                         the decoded result on return.\r
-  @param[in]      IkeType                The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and\r
-                                         IKE_CHILD_TYPE are supported.\r
-\r
-  @retval         EFI_SUCCESS            The IKE packet is decoded successfully.\r
-  @retval         Otherwise              The IKE packet decoding is failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2DecodePacket (\r
-  IN     IKEV2_SESSION_COMMON  *SessionCommon,\r
-  IN OUT IKE_PACKET            *IkePacket,\r
-  IN     UINTN                 IkeType\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  IKEV2_COMMON_PAYLOAD_HEADER *PayloadHdr;\r
-  UINT8                       PayloadType;\r
-  UINTN                       RemainBytes;\r
-  UINT16                      PayloadSize;\r
-  IKE_PAYLOAD                 *IkePayload;\r
-  IKE_HEADER                  *IkeHeader;\r
-  IKEV2_SA_SESSION            *IkeSaSession;\r
-\r
-  IkeHeader = NULL;\r
-\r
-  //\r
-  // Check if the IkePacket need decrypt.\r
-  //\r
-  if (SessionCommon->State >= IkeStateAuth) {\r
-    Status = Ikev2DecryptPacket (SessionCommon, IkePacket, IkeType);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // If the IkePacket doesn't contain any payload return invalid parameter.\r
-  //\r
-  if (IkePacket->Header->NextPayload == IKEV2_PAYLOAD_TYPE_NONE) {\r
-    if ((SessionCommon->State >= IkeStateAuth) &&\r
-        (IkePacket->Header->ExchangeType == IKEV2_EXCHANGE_TYPE_INFO)\r
-        ) {\r
-      //\r
-      // If it is Liveness check, there will be no payload load in the encrypt payload.\r
-      //\r
-      Status = EFI_SUCCESS;\r
-    } else {\r
-      Status = EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  //\r
-  // If the PayloadTotalSize < Header length, return invalid parameter.\r
-  //\r
-  RemainBytes = IkePacket->PayloadTotalSize;\r
-  if (RemainBytes < sizeof (IKEV2_COMMON_PAYLOAD_HEADER)) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto Exit;\r
-  }\r
-\r
-  //\r
-  // If the packet is first or second message, store whole message in\r
-  // IkeSa->InitiPacket or IkeSa->RespPacket for following Auth Payload\r
-  // calculate.\r
-  //\r
-  if (IkePacket->Header->ExchangeType == IKEV2_EXCHANGE_TYPE_INIT) {\r
-    IkeHeader = AllocateZeroPool (sizeof (IKE_HEADER));\r
-    if (IkeHeader == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Exit;\r
-    }\r
-\r
-    CopyMem (IkeHeader, IkePacket->Header, sizeof (IKE_HEADER));\r
-\r
-    //\r
-    // Before store the whole packet, roll back the host order to network order,\r
-    // since the header order was changed in the IkePacketFromNetbuf.\r
-    //\r
-    IkeHdrNetToHost (IkeHeader);\r
-    IkeSaSession = IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    if (SessionCommon->IsInitiator) {\r
-      IkeSaSession->RespPacket     = AllocateZeroPool (IkePacket->Header->Length);\r
-      if (IkeSaSession->RespPacket == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Exit;\r
-      }\r
-      IkeSaSession->RespPacketSize = IkePacket->Header->Length;\r
-      CopyMem (IkeSaSession->RespPacket, IkeHeader, sizeof (IKE_HEADER));\r
-      CopyMem (\r
-        IkeSaSession->RespPacket + sizeof (IKE_HEADER),\r
-        IkePacket->PayloadsBuf,\r
-        IkePacket->Header->Length - sizeof (IKE_HEADER)\r
-        );\r
-    } else {\r
-      IkeSaSession->InitPacket     = AllocateZeroPool (IkePacket->Header->Length);\r
-      if (IkeSaSession->InitPacket == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Exit;\r
-      }\r
-      IkeSaSession->InitPacketSize = IkePacket->Header->Length;\r
-      CopyMem (IkeSaSession->InitPacket, IkeHeader, sizeof (IKE_HEADER));\r
-      CopyMem (\r
-        IkeSaSession->InitPacket + sizeof (IKE_HEADER),\r
-        IkePacket->PayloadsBuf,\r
-        IkePacket->Header->Length - sizeof (IKE_HEADER)\r
-        );\r
-    }\r
-  }\r
-\r
-  //\r
-  // Point to the first Payload\r
-  //\r
-  PayloadHdr  = (IKEV2_COMMON_PAYLOAD_HEADER *) IkePacket->PayloadsBuf;\r
-  PayloadType = IkePacket->Header->NextPayload;\r
-\r
-  //\r
-  // Parse each payload\r
-  //\r
-  while (RemainBytes >= sizeof (IKEV2_COMMON_PAYLOAD_HEADER)) {\r
-    PayloadSize = NTOHS (PayloadHdr->PayloadLength);\r
-\r
-    //\r
-    //Check the size of the payload is correct.\r
-    //\r
-    if (RemainBytes < PayloadSize) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    //\r
-    // At certain states, it should save some datas before decoding.\r
-    //\r
-    if (SessionCommon->BeforeDecodePayload != NULL) {\r
-      SessionCommon->BeforeDecodePayload (\r
-                       (UINT8 *) SessionCommon,\r
-                       (UINT8 *) PayloadHdr,\r
-                       PayloadSize,\r
-                       PayloadType\r
-                       );\r
-    }\r
-\r
-    //\r
-    // Initial IkePayload\r
-    //\r
-    IkePayload = IkePayloadAlloc ();\r
-    if (IkePayload == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Exit;\r
-    }\r
-\r
-    IkePayload->PayloadType     = PayloadType;\r
-    IkePayload->PayloadBuf      = (UINT8 *) PayloadHdr;\r
-    IkePayload->PayloadSize     = PayloadSize;\r
-    IkePayload->IsPayloadBufExt = TRUE;\r
-\r
-    Status = Ikev2DecodePayload ((UINT8 *) SessionCommon, IkePayload);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    IPSEC_DUMP_BUF ("After Decoding Payload", IkePayload->PayloadBuf, IkePayload->PayloadSize);\r
-    //\r
-    // Add each payload into packet\r
-    // Notice, the IkePacket->Hdr->Lenght still recode the whole IkePacket length\r
-    // which is before the decoding.\r
-    //\r
-    IKE_PACKET_APPEND_PAYLOAD (IkePacket, IkePayload);\r
-\r
-    RemainBytes -= PayloadSize;\r
-    PayloadType  = PayloadHdr->NextPayload;\r
-    if (PayloadType == IKEV2_PAYLOAD_TYPE_NONE) {\r
-      break;\r
-    }\r
-\r
-    PayloadHdr = (IKEV2_COMMON_PAYLOAD_HEADER *) ((UINT8 *) PayloadHdr + PayloadSize);\r
-  }\r
-\r
-  if (PayloadType != IKEV2_PAYLOAD_TYPE_NONE) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto Exit;\r
-  }\r
-\r
-Exit:\r
-  if (EFI_ERROR (Status)) {\r
-    ClearAllPayloads (IkePacket);\r
-  }\r
-\r
-  if (IkeHeader != NULL) {\r
-    FreePool (IkeHeader);\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Encode the IKE packet.\r
-\r
-  This function puts all Payloads into one payload then encrypt it if needed.\r
-\r
-  @param[in]      SessionCommon      Pointer to IKEV2_SESSION_COMMON containing\r
-                                     some parameter used during IKE packet encoding.\r
-  @param[in, out] IkePacket          Pointer to IKE_PACKET to be encoded as input,\r
-                                     and the encoded result as output.\r
-  @param[in]      IkeType            The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and\r
-                                     IKE_CHILD_TYPE are supportted.\r
-\r
-  @retval         EFI_SUCCESS        Encode IKE packet successfully.\r
-  @retval         Otherwise          Encode IKE packet failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2EncodePacket (\r
-  IN     IKEV2_SESSION_COMMON *SessionCommon,\r
-  IN OUT IKE_PACKET           *IkePacket,\r
-  IN     UINTN                IkeType\r
-  )\r
-{\r
-  IKE_PAYLOAD       *IkePayload;\r
-  UINTN             PayloadTotalSize;\r
-  LIST_ENTRY        *Entry;\r
-  EFI_STATUS        Status;\r
-  IKEV2_SA_SESSION  *IkeSaSession;\r
-\r
-  PayloadTotalSize = 0;\r
-  //\r
-  // Encode each payload\r
-  //\r
-  for (Entry = IkePacket->PayloadList.ForwardLink; Entry != &(IkePacket->PayloadList);) {\r
-    IkePayload  = IKE_PAYLOAD_BY_PACKET (Entry);\r
-    Entry       = Entry->ForwardLink;\r
-    Status      = Ikev2EncodePayload ((UINT8 *) SessionCommon, IkePayload);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    if (SessionCommon->AfterEncodePayload != NULL) {\r
-      //\r
-      // For certain states, save some payload for further calculation\r
-      //\r
-      SessionCommon->AfterEncodePayload (\r
-                      (UINT8 *) SessionCommon,\r
-                      IkePayload->PayloadBuf,\r
-                      IkePayload->PayloadSize,\r
-                      IkePayload->PayloadType\r
-                      );\r
-    }\r
-\r
-    PayloadTotalSize += IkePayload->PayloadSize;\r
-  }\r
-  IkePacket->PayloadTotalSize = PayloadTotalSize;\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (SessionCommon->State >= IkeStateAuth) {\r
-    //\r
-    // Encrypt all payload and transfer IKE packet header from Host order to Network order.\r
-    //\r
-    Status = Ikev2EncryptPacket (SessionCommon, IkePacket);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  } else {\r
-    //\r
-    // Fill in the lenght into IkePacket header and transfer Host order to Network order.\r
-    //\r
-    IkePacket->Header->Length = (UINT32) (sizeof (IKE_HEADER) + IkePacket->PayloadTotalSize);\r
-    IkeHdrHostToNet (IkePacket->Header);\r
-  }\r
-\r
-  //\r
-  // If the packet is first message, store whole message in IkeSa->InitiPacket\r
-  // for following Auth Payload calculation.\r
-  //\r
-  if (IkePacket->Header->ExchangeType == IKEV2_EXCHANGE_TYPE_INIT) {\r
-    IkeSaSession =  IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    if (SessionCommon->IsInitiator) {\r
-      IkeSaSession->InitPacketSize = IkePacket->PayloadTotalSize + sizeof (IKE_HEADER);\r
-      IkeSaSession->InitPacket     = AllocateZeroPool (IkeSaSession->InitPacketSize);\r
-      if (IkeSaSession->InitPacket == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      CopyMem (IkeSaSession->InitPacket, IkePacket->Header, sizeof (IKE_HEADER));\r
-      PayloadTotalSize = 0;\r
-      for (Entry = IkePacket->PayloadList.ForwardLink; Entry != &(IkePacket->PayloadList);) {\r
-        IkePayload  = IKE_PAYLOAD_BY_PACKET (Entry);\r
-        Entry       = Entry->ForwardLink;\r
-        CopyMem (\r
-          IkeSaSession->InitPacket + sizeof (IKE_HEADER) + PayloadTotalSize,\r
-          IkePayload->PayloadBuf,\r
-          IkePayload->PayloadSize\r
-          );\r
-        PayloadTotalSize = PayloadTotalSize + IkePayload->PayloadSize;\r
-      }\r
-    } else {\r
-      IkeSaSession->RespPacketSize = IkePacket->PayloadTotalSize + sizeof(IKE_HEADER);\r
-      IkeSaSession->RespPacket     = AllocateZeroPool (IkeSaSession->RespPacketSize);\r
-      if (IkeSaSession->RespPacket == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      CopyMem (IkeSaSession->RespPacket, IkePacket->Header, sizeof (IKE_HEADER));\r
-      PayloadTotalSize = 0;\r
-      for (Entry = IkePacket->PayloadList.ForwardLink; Entry != &(IkePacket->PayloadList);) {\r
-        IkePayload  = IKE_PAYLOAD_BY_PACKET (Entry);\r
-        Entry       = Entry->ForwardLink;\r
-\r
-        CopyMem (\r
-          IkeSaSession->RespPacket + sizeof (IKE_HEADER) + PayloadTotalSize,\r
-          IkePayload->PayloadBuf,\r
-          IkePayload->PayloadSize\r
-          );\r
-        PayloadTotalSize = PayloadTotalSize + IkePayload->PayloadSize;\r
-      }\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Decrypt IKE packet.\r
-\r
-  This function decrypts the Encrypted IKE packet and put the result into IkePacket->PayloadBuf.\r
-\r
-  @param[in]      SessionCommon       Pointer to IKEV2_SESSION_COMMON containing\r
-                                      some parameter used during decrypting.\r
-  @param[in, out] IkePacket           Pointer to IKE_PACKET to be decrypted as input,\r
-                                      and the decrypted result as output.\r
-  @param[in, out] IkeType             The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and\r
-                                      IKE_CHILD_TYPE are supportted.\r
-\r
-  @retval EFI_INVALID_PARAMETER      If the IKE packet length is zero or the\r
-                                     IKE packet length is not aligned with Algorithm Block Size\r
-  @retval EFI_SUCCESS                Decrypt IKE packet successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2DecryptPacket (\r
-  IN     IKEV2_SESSION_COMMON *SessionCommon,\r
-  IN OUT IKE_PACKET           *IkePacket,\r
-  IN OUT UINTN                IkeType\r
-  )\r
-{\r
-  UINT8                  CryptBlockSize;      // Encrypt Block Size\r
-  UINTN                  DecryptedSize;       // Encrypted IKE Payload Size\r
-  UINT8                  *DecryptedBuf;       // Encrypted IKE Payload buffer\r
-  UINTN                  IntegritySize;\r
-  UINT8                  *IntegrityBuffer;\r
-  UINTN                  IvSize;              // Iv Size\r
-  UINT8                  CheckSumSize;        // Integrity Check Sum Size depends on intergrity Auth\r
-  UINT8                  *CheckSumData;       // Check Sum data\r
-  IKEV2_SA_SESSION       *IkeSaSession;\r
-  IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
-  EFI_STATUS             Status;\r
-  UINT8                  PadLen;\r
-  HASH_DATA_FRAGMENT     Fragments[1];\r
-\r
-  IvSize         = 0;\r
-  IkeSaSession   = NULL;\r
-  CryptBlockSize = 0;\r
-  CheckSumSize   = 0;\r
-\r
-  //\r
-  // Check if the first payload is the Encrypted payload\r
-  //\r
-  if (IkePacket->Header->NextPayload != IKEV2_PAYLOAD_TYPE_ENCRYPT) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-  CheckSumData    = NULL;\r
-  DecryptedBuf    = NULL;\r
-  IntegrityBuffer = NULL;\r
-\r
-  //\r
-  // Get the Block Size\r
-  //\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-\r
-    CryptBlockSize = (UINT8) IpSecGetEncryptBlockSize ((UINT8) SessionCommon->SaParams->EncAlgId);\r
-\r
-    CheckSumSize   = (UINT8) IpSecGetIcvLength ((UINT8) SessionCommon->SaParams->IntegAlgId);\r
-    IkeSaSession   = IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-\r
-  } else if (SessionCommon->IkeSessionType == IkeSessionTypeChildSa) {\r
-\r
-    ChildSaSession = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    IkeSaSession   = ChildSaSession->IkeSaSession;\r
-    CryptBlockSize = (UINT8) IpSecGetEncryptBlockSize ((UINT8) IkeSaSession->SessionCommon.SaParams->EncAlgId);\r
-    CheckSumSize   = (UINT8) IpSecGetIcvLength ((UINT8) IkeSaSession->SessionCommon.SaParams->IntegAlgId);\r
-  } else {\r
-    //\r
-    // The type of SA Session would either be IkeSa or ChildSa.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CheckSumData = AllocateZeroPool (CheckSumSize);\r
-  if (CheckSumData == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Fill in the Integrity buffer\r
-  //\r
-  IntegritySize   = IkePacket->PayloadTotalSize + sizeof (IKE_HEADER);\r
-  IntegrityBuffer = AllocateZeroPool (IntegritySize);\r
-  if (IntegrityBuffer == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  CopyMem (IntegrityBuffer, IkePacket->Header, sizeof(IKE_HEADER));\r
-  CopyMem (IntegrityBuffer + sizeof (IKE_HEADER), IkePacket->PayloadsBuf, IkePacket->PayloadTotalSize);\r
-\r
-  //\r
-  // Change Host order to Network order, since the header order was changed\r
-  // in the IkePacketFromNetbuf.\r
-  //\r
-  IkeHdrHostToNet ((IKE_HEADER *)IntegrityBuffer);\r
-\r
-  //\r
-  // Calculate the Integrity CheckSum Data\r
-  //\r
-  Fragments[0].Data     = IntegrityBuffer;\r
-  Fragments[0].DataSize = IntegritySize - CheckSumSize;\r
-\r
-  if (SessionCommon->IsInitiator) {\r
-    Status = IpSecCryptoIoHmac (\r
-               (UINT8)IkeSaSession->SessionCommon.SaParams->IntegAlgId,\r
-               IkeSaSession->IkeKeys->SkArKey,\r
-               IkeSaSession->IkeKeys->SkArKeySize,\r
-               (HASH_DATA_FRAGMENT *) Fragments,\r
-               1,\r
-               CheckSumData,\r
-               CheckSumSize\r
-               );\r
-  } else {\r
-    Status = IpSecCryptoIoHmac (\r
-               (UINT8)IkeSaSession->SessionCommon.SaParams->IntegAlgId,\r
-               IkeSaSession->IkeKeys->SkAiKey,\r
-               IkeSaSession->IkeKeys->SkAiKeySize,\r
-               (HASH_DATA_FRAGMENT *) Fragments,\r
-               1,\r
-               CheckSumData,\r
-               CheckSumSize\r
-               );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_EXIT;\r
-  }\r
-  //\r
-  // Compare the Integrity CheckSum Data with the one in IkePacket\r
-  //\r
-  if (CompareMem (\r
-        IkePacket->PayloadsBuf + IkePacket->PayloadTotalSize - CheckSumSize,\r
-        CheckSumData,\r
-        CheckSumSize\r
-        ) != 0) {\r
-    DEBUG ((DEBUG_ERROR, "Error auth verify payload\n"));\r
-    Status = EFI_ACCESS_DENIED;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  IvSize = CryptBlockSize;\r
-\r
-  //\r
-  // Decrypt the payload with the key.\r
-  //\r
-  DecryptedSize = IkePacket->PayloadTotalSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER) - IvSize - CheckSumSize;\r
-  DecryptedBuf  = AllocateZeroPool (DecryptedSize);\r
-  if (DecryptedBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  CopyMem (\r
-    DecryptedBuf,\r
-    IkePacket->PayloadsBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER) + IvSize,\r
-    DecryptedSize\r
-    );\r
-\r
-  if (SessionCommon->IsInitiator) {\r
-   Status = IpSecCryptoIoDecrypt (\r
-              (UINT8) SessionCommon->SaParams->EncAlgId,\r
-              IkeSaSession->IkeKeys->SkErKey,\r
-              IkeSaSession->IkeKeys->SkErKeySize << 3,\r
-              IkePacket->PayloadsBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),\r
-              DecryptedBuf,\r
-              DecryptedSize,\r
-              DecryptedBuf\r
-              );\r
-  } else {\r
-    Status = IpSecCryptoIoDecrypt (\r
-               (UINT8) SessionCommon->SaParams->EncAlgId,\r
-               IkeSaSession->IkeKeys->SkEiKey,\r
-               IkeSaSession->IkeKeys->SkEiKeySize << 3,\r
-               IkePacket->PayloadsBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),\r
-               DecryptedBuf,\r
-               DecryptedSize,\r
-               DecryptedBuf\r
-               );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "Error decrypt buffer with %r\n", Status));\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Get the Padding length\r
-  //\r
-  //\r
-  PadLen = (UINT8) (*(DecryptedBuf + DecryptedSize - sizeof (IKEV2_PAD_LEN)));\r
-\r
-  //\r
-  // Save the next payload of encrypted payload into IkePacket->Hdr->NextPayload\r
-  //\r
-  IkePacket->Header->NextPayload = ((IKEV2_ENCRYPTED *) IkePacket->PayloadsBuf)->Header.NextPayload;\r
-\r
-  //\r
-  // Free old IkePacket->PayloadBuf and point it to decrypted paylaod buffer.\r
-  //\r
-  FreePool (IkePacket->PayloadsBuf);\r
-  IkePacket->PayloadsBuf      = DecryptedBuf;\r
-  IkePacket->PayloadTotalSize = DecryptedSize - PadLen;\r
-\r
-  IPSEC_DUMP_BUF ("Decrypted Buffer", DecryptedBuf, DecryptedSize);\r
-\r
-\r
-ON_EXIT:\r
-  if (CheckSumData != NULL) {\r
-    FreePool (CheckSumData);\r
-  }\r
-\r
-  if (EFI_ERROR (Status) && DecryptedBuf != NULL) {\r
-    FreePool (DecryptedBuf);\r
-  }\r
-\r
-  if (IntegrityBuffer != NULL) {\r
-    FreePool (IntegrityBuffer);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Encrypt IKE packet.\r
-\r
-  This function encrypt IKE packet before sending it. The Encrypted IKE packet\r
-  is put in to IKEV2 Encrypted Payload.\r
-\r
-  @param[in]        SessionCommon     Pointer to IKEV2_SESSION_COMMON related to the IKE packet.\r
-  @param[in, out]   IkePacket         Pointer to IKE packet to be encrypted.\r
-\r
-  @retval      EFI_SUCCESS       Operation is successful.\r
-  @retval      Others            Operation is failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2EncryptPacket (\r
-  IN IKEV2_SESSION_COMMON *SessionCommon,\r
-  IN OUT IKE_PACKET       *IkePacket\r
-  )\r
-{\r
-  UINT8                  CryptBlockSize;      // Encrypt Block Size\r
-  UINT8                  CryptBlockSizeMask;  // Block Mask\r
-  UINTN                  EncryptedSize;       // Encrypted IKE Payload Size\r
-  UINT8                  *EncryptedBuf;       // Encrypted IKE Payload buffer\r
-  UINT8                  *EncryptPayloadBuf;  // Contain whole Encrypted Payload\r
-  UINTN                  EncryptPayloadSize;  // Total size of the Encrypted payload\r
-  UINT8                  *IntegrityBuf;       // Buffer to be intergity\r
-  UINT8                  *IvBuffer;           // Initialization Vector\r
-  UINT8                  IvSize;              // Iv Size\r
-  UINT8                  CheckSumSize;        // Integrity Check Sum Size depends on intergrity Auth\r
-  UINT8                  *CheckSumData;       // Check Sum data\r
-  UINTN                  Index;\r
-  IKE_PAYLOAD            *EncryptPayload;\r
-  IKEV2_SA_SESSION       *IkeSaSession;\r
-  IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
-  EFI_STATUS             Status;\r
-  LIST_ENTRY             *Entry;\r
-  IKE_PAYLOAD            *IkePayload;\r
-  HASH_DATA_FRAGMENT     Fragments[1];\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // Initial all buffers to NULL.\r
-  //\r
-  EncryptedBuf      = NULL;\r
-  EncryptPayloadBuf = NULL;\r
-  IvBuffer          = NULL;\r
-  CheckSumData      = NULL;\r
-  IkeSaSession      = NULL;\r
-  CryptBlockSize    = 0;\r
-  CheckSumSize      = 0;\r
-  IntegrityBuf      = NULL;\r
-  //\r
-  // Get the Block Size\r
-  //\r
-  if (SessionCommon->IkeSessionType == IkeSessionTypeIkeSa) {\r
-\r
-    CryptBlockSize = (UINT8) IpSecGetEncryptBlockSize ((UINT8) SessionCommon->SaParams->EncAlgId);\r
-    CheckSumSize   = (UINT8) IpSecGetIcvLength ((UINT8) SessionCommon->SaParams->IntegAlgId);\r
-    IkeSaSession   = IKEV2_SA_SESSION_FROM_COMMON (SessionCommon);\r
-\r
-  } else if (SessionCommon->IkeSessionType == IkeSessionTypeChildSa) {\r
-\r
-    ChildSaSession = IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon);\r
-    IkeSaSession   = ChildSaSession->IkeSaSession;\r
-    CryptBlockSize = (UINT8) IpSecGetEncryptBlockSize ((UINT8) IkeSaSession->SessionCommon.SaParams->EncAlgId);\r
-    CheckSumSize   = (UINT8) IpSecGetIcvLength ((UINT8) IkeSaSession->SessionCommon.SaParams->IntegAlgId);\r
-  }\r
-\r
-  //\r
-  // Calcualte the EncryptPayloadSize and the PAD length\r
-  //\r
-  CryptBlockSizeMask  = (UINT8) (CryptBlockSize - 1);\r
-  EncryptedSize       = (IkePacket->PayloadTotalSize + sizeof (IKEV2_PAD_LEN) + CryptBlockSizeMask) & ~CryptBlockSizeMask;\r
-  EncryptedBuf        = (UINT8 *) AllocateZeroPool (EncryptedSize);\r
-  if (EncryptedBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Copy all payload into EncryptedIkePayload\r
-  //\r
-  Index = 0;\r
-  NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
-    IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
-\r
-    CopyMem (EncryptedBuf + Index, IkePayload->PayloadBuf, IkePayload->PayloadSize);\r
-    Index += IkePayload->PayloadSize;\r
-\r
-  };\r
-\r
-  //\r
-  // Fill in the Pading Length\r
-  //\r
-  *(EncryptedBuf + EncryptedSize - 1) = (UINT8)(EncryptedSize - IkePacket->PayloadTotalSize - 1);\r
-\r
-  //\r
-  // The IV size is equal with block size\r
-  //\r
-  IvSize    = CryptBlockSize;\r
-  IvBuffer  = (UINT8 *) AllocateZeroPool (IvSize);\r
-  if (IvBuffer == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Generate IV\r
-  //\r
-  IkeGenerateIv (IvBuffer, IvSize);\r
-\r
-  //\r
-  // Encrypt payload buf\r
-  //\r
-  if (SessionCommon->IsInitiator) {\r
-    Status = IpSecCryptoIoEncrypt (\r
-               (UINT8) IkeSaSession->SessionCommon.SaParams->EncAlgId,\r
-               IkeSaSession->IkeKeys->SkEiKey,\r
-               IkeSaSession->IkeKeys->SkEiKeySize << 3,\r
-               IvBuffer,\r
-               EncryptedBuf,\r
-               EncryptedSize,\r
-               EncryptedBuf\r
-               );\r
-  } else {\r
-    Status = IpSecCryptoIoEncrypt (\r
-               (UINT8) IkeSaSession->SessionCommon.SaParams->EncAlgId,\r
-               IkeSaSession->IkeKeys->SkErKey,\r
-               IkeSaSession->IkeKeys->SkErKeySize << 3,\r
-               IvBuffer,\r
-               EncryptedBuf,\r
-               EncryptedSize,\r
-               EncryptedBuf\r
-               );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Allocate the buffer for the whole IKE payload (Encrypted Payload).\r
-  //\r
-  EncryptPayloadSize = sizeof(IKEV2_ENCRYPTED) + IvSize + EncryptedSize + CheckSumSize;\r
-  EncryptPayloadBuf  = AllocateZeroPool (EncryptPayloadSize);\r
-  if (EncryptPayloadBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Fill in Header of  Encrypted Payload\r
-  //\r
-  ((IKEV2_ENCRYPTED *) EncryptPayloadBuf)->Header.NextPayload   = IkePacket->Header->NextPayload;\r
-  ((IKEV2_ENCRYPTED *) EncryptPayloadBuf)->Header.PayloadLength = HTONS ((UINT16)EncryptPayloadSize);\r
-\r
-  //\r
-  // Fill in Iv\r
-  //\r
-  CopyMem (EncryptPayloadBuf + sizeof (IKEV2_ENCRYPTED), IvBuffer, IvSize);\r
-\r
-  //\r
-  // Fill in encrypted data\r
-  //\r
-  CopyMem (EncryptPayloadBuf + sizeof (IKEV2_ENCRYPTED) + IvSize, EncryptedBuf, EncryptedSize);\r
-\r
-  //\r
-  // Fill in the IKE Packet header\r
-  //\r
-  IkePacket->PayloadTotalSize    = EncryptPayloadSize;\r
-  IkePacket->Header->Length      = (UINT32) (sizeof (IKE_HEADER) + IkePacket->PayloadTotalSize);\r
-  IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ENCRYPT;\r
-\r
-  IntegrityBuf                   = AllocateZeroPool (IkePacket->Header->Length);\r
-  if (IntegrityBuf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-  IkeHdrHostToNet (IkePacket->Header);\r
-\r
-  CopyMem (IntegrityBuf, IkePacket->Header, sizeof (IKE_HEADER));\r
-  CopyMem (IntegrityBuf + sizeof (IKE_HEADER), EncryptPayloadBuf, EncryptPayloadSize);\r
-\r
-  //\r
-  // Calcualte Integrity CheckSum\r
-  //\r
-  Fragments[0].Data     = IntegrityBuf;\r
-  Fragments[0].DataSize = EncryptPayloadSize + sizeof (IKE_HEADER) - CheckSumSize;\r
-\r
-  CheckSumData = AllocateZeroPool (CheckSumSize);\r
-  if (CheckSumData == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-  if (SessionCommon->IsInitiator) {\r
-\r
-    IpSecCryptoIoHmac (\r
-      (UINT8)IkeSaSession->SessionCommon.SaParams->IntegAlgId,\r
-      IkeSaSession->IkeKeys->SkAiKey,\r
-      IkeSaSession->IkeKeys->SkAiKeySize,\r
-      (HASH_DATA_FRAGMENT *) Fragments,\r
-      1,\r
-      CheckSumData,\r
-      CheckSumSize\r
-      );\r
-  } else {\r
-\r
-    IpSecCryptoIoHmac (\r
-      (UINT8)IkeSaSession->SessionCommon.SaParams->IntegAlgId,\r
-      IkeSaSession->IkeKeys->SkArKey,\r
-      IkeSaSession->IkeKeys->SkArKeySize,\r
-      (HASH_DATA_FRAGMENT *) Fragments,\r
-      1,\r
-      CheckSumData,\r
-      CheckSumSize\r
-      );\r
-  }\r
-\r
-  //\r
-  // Copy CheckSum into Encrypted Payload\r
-  //\r
-  CopyMem (EncryptPayloadBuf + EncryptPayloadSize - CheckSumSize, CheckSumData, CheckSumSize);\r
-\r
-  IPSEC_DUMP_BUF ("Encrypted payload buffer", EncryptPayloadBuf, EncryptPayloadSize);\r
-  IPSEC_DUMP_BUF ("Integrith CheckSum Data", CheckSumData, CheckSumSize);\r
-\r
-  //\r
-  // Clean all payload under IkePacket->PayloadList.\r
-  //\r
-  ClearAllPayloads (IkePacket);\r
-\r
-  //\r
-  // Create Encrypted Payload and add into IkePacket->PayloadList\r
-  //\r
-  EncryptPayload = IkePayloadAlloc ();\r
-  if (EncryptPayload == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Fill the encrypted payload into the IKE_PAYLOAD structure.\r
-  //\r
-  EncryptPayload->PayloadBuf  = EncryptPayloadBuf;\r
-  EncryptPayload->PayloadSize = EncryptPayloadSize;\r
-  EncryptPayload->PayloadType = IKEV2_PAYLOAD_TYPE_ENCRYPT;\r
-\r
-  IKE_PACKET_APPEND_PAYLOAD (IkePacket, EncryptPayload);\r
-\r
-ON_EXIT:\r
-  if (EncryptedBuf != NULL) {\r
-    FreePool (EncryptedBuf);\r
-  }\r
-\r
-  if (EFI_ERROR (Status) && EncryptPayloadBuf != NULL) {\r
-    FreePool (EncryptPayloadBuf);\r
-  }\r
-\r
-  if (IvBuffer != NULL) {\r
-    FreePool (IvBuffer);\r
-  }\r
-\r
-  if (CheckSumData != NULL) {\r
-    FreePool (CheckSumData);\r
-  }\r
-\r
-  if (IntegrityBuf != NULL) {\r
-    FreePool (IntegrityBuf);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-\r
-  The notification function. It will be called when the related UDP_TX_TOKEN's event\r
-  is signaled.\r
-\r
-  This function frees the Net Buffer pointed to the input Packet.\r
-\r
-  @param[in]  Packet           Pointer to Net buffer containing the sending IKE packet.\r
-  @param[in]  EndPoint         Pointer to UDP_END_POINT containing the remote and local\r
-                               address information.\r
-  @param[in]  IoStatus         The Status of the related UDP_TX_TOKEN.\r
-  @param[in]  Context          Pointer to data passed from the caller.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Ikev2OnPacketSent (\r
-  IN NET_BUF                   *Packet,\r
-  IN UDP_END_POINT             *EndPoint,\r
-  IN EFI_STATUS                IoStatus,\r
-  IN VOID                      *Context\r
-  )\r
-{\r
- IKE_PACKET             *IkePacket;\r
- IKEV2_SA_SESSION       *IkeSaSession;\r
- IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
- UINT8                  Value;\r
- IPSEC_PRIVATE_DATA     *Private;\r
- EFI_STATUS             Status;\r
-\r
- IkePacket  = (IKE_PACKET *) Context;\r
- Private    = NULL;\r
-\r
- if (EFI_ERROR (IoStatus)) {\r
-    DEBUG ((DEBUG_ERROR, "Error send the last packet in IkeSessionTypeIkeSa with %r\n", IoStatus));\r
-  }\r
-\r
-  NetbufFree (Packet);\r
-\r
-  if (IkePacket->IsDeleteInfo) {\r
-    //\r
-    // For each RemotePeerIP, there are only one IKESA.\r
-    //\r
-    IkeSaSession = Ikev2SaSessionLookup (\r
-                     &IkePacket->Private->Ikev2EstablishedList,\r
-                     &IkePacket->RemotePeerIp\r
-                     );\r
-    if (IkeSaSession == NULL) {\r
-      IkePacketFree (IkePacket);\r
-      return;\r
-    }\r
-\r
-    Private = IkePacket->Private;\r
-    if (IkePacket->Spi != 0 ) {\r
-      //\r
-      // At that time, the established Child SA still in eht ChildSaEstablishSessionList.\r
-      // And meanwhile, if the Child SA is in the the ChildSa in Delete list,\r
-      // remove it from delete list and delete it direclty.\r
-      //\r
-      ChildSaSession = Ikev2ChildSaSessionLookupBySpi (\r
-                         &IkeSaSession->ChildSaEstablishSessionList,\r
-                         IkePacket->Spi\r
-                         );\r
-      if (ChildSaSession != NULL) {\r
-        Ikev2ChildSaSessionRemove (\r
-          &IkeSaSession->DeleteSaList,\r
-          ChildSaSession->LocalPeerSpi,\r
-          IKEV2_DELET_CHILDSA_LIST\r
-          );\r
-\r
-        //\r
-        // Delete the Child SA.\r
-        //\r
-        Ikev2ChildSaSilentDelete (\r
-          IkeSaSession,\r
-          IkePacket->Spi\r
-          );\r
-      }\r
-\r
-    } else {\r
-      //\r
-      // Delete the IKE SA\r
-      //\r
-      DEBUG (\r
-        (DEBUG_INFO,\r
-        "\n------ deleted Packet (cookie_i, cookie_r):(0x%lx, 0x%lx)------\n",\r
-        IkeSaSession->InitiatorCookie,\r
-        IkeSaSession->ResponderCookie)\r
-        );\r
-\r
-      RemoveEntryList (&IkeSaSession->BySessionTable);\r
-      Ikev2SaSessionFree (IkeSaSession);\r
-    }\r
-  }\r
-  IkePacketFree (IkePacket);\r
-\r
-  //\r
-  // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec status\r
-  // should be changed.\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 DisabledFlag in Private data.\r
-        //\r
-        Private->IpSec.DisabledFlag = TRUE;\r
-        Private->IsIPsecDisabling   = FALSE;\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Send out IKEV2 packet.\r
-\r
-  @param[in]  IkeUdpService     Pointer to IKE_UDP_SERVICE used to send the IKE packet.\r
-  @param[in]  SessionCommon     Pointer to IKEV1_SESSION_COMMON related to the IKE packet.\r
-  @param[in]  IkePacket         Pointer to IKE_PACKET to be sent out.\r
-  @param[in]  IkeType           The type of IKE to point what's kind of the IKE\r
-                                packet is to be sent out. IKE_SA_TYPE, IKE_INFO_TYPE\r
-                                and IKE_CHILD_TYPE are supportted.\r
-\r
-  @retval     EFI_SUCCESS       The operation complete successfully.\r
-  @retval     Otherwise         The operation is failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ikev2SendIkePacket (\r
-  IN IKE_UDP_SERVICE     *IkeUdpService,\r
-  IN UINT8               *SessionCommon,\r
-  IN IKE_PACKET          *IkePacket,\r
-  IN UINTN               IkeType\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  NET_BUF               *IkePacketNetbuf;\r
-  UDP_END_POINT         EndPoint;\r
-  IKEV2_SESSION_COMMON  *Common;\r
-\r
-  Common = (IKEV2_SESSION_COMMON *) SessionCommon;\r
-\r
-  //\r
-  // Set the resend interval\r
-  //\r
-  if (Common->TimeoutInterval == 0) {\r
-    Common->TimeoutInterval = IKE_DEFAULT_TIMEOUT_INTERVAL;\r
-  }\r
-\r
-  //\r
-  // Retransfer the packet if it is initial packet.\r
-  //\r
-  if (IkePacket->Header->Flags == IKE_HEADER_FLAGS_INIT) {\r
-    //\r
-    // Set timer for next retry, this will cancel previous timer\r
-    //\r
-    Status = gBS->SetTimer (\r
-                    Common->TimeoutEvent,\r
-                    TimerRelative,\r
-                    MultU64x32 (Common->TimeoutInterval, 10000) // ms->100ns\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  IKE_PACKET_REF (IkePacket);\r
-  //\r
-  // If the last sent packet is same with this round packet, the packet is resent packet.\r
-  //\r
-  if (IkePacket != Common->LastSentPacket && Common->LastSentPacket != NULL) {\r
-    IkePacketFree (Common->LastSentPacket);\r
-  }\r
-\r
-  Common->LastSentPacket = IkePacket;\r
-\r
-  //\r
-  // Transform IkePacke to NetBuf\r
-  //\r
-  IkePacketNetbuf = IkeNetbufFromPacket ((UINT8 *) SessionCommon, IkePacket, IkeType);\r
-  if (IkePacketNetbuf == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  ZeroMem (&EndPoint, sizeof (UDP_END_POINT));\r
-  EndPoint.RemotePort = IKE_DEFAULT_PORT;\r
-  CopyMem (&IkePacket->RemotePeerIp, &Common->RemotePeerIp, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&EndPoint.RemoteAddr, &Common->RemotePeerIp, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&EndPoint.LocalAddr, &Common->LocalPeerIp, sizeof (EFI_IP_ADDRESS));\r
-\r
-  IPSEC_DUMP_PACKET (IkePacket, EfiIPsecOutBound, IkeUdpService->IpVersion);\r
-\r
-  if (IkeUdpService->IpVersion == IP_VERSION_4) {\r
-    EndPoint.RemoteAddr.Addr[0] = HTONL (EndPoint.RemoteAddr.Addr[0]);\r
-    EndPoint.LocalAddr.Addr[0]  = HTONL (EndPoint.LocalAddr.Addr[0]);\r
-  }\r
-\r
-  //\r
-  // Call UDPIO to send out the IKE packet.\r
-  //\r
-  Status = UdpIoSendDatagram (\r
-             IkeUdpService->Output,\r
-             IkePacketNetbuf,\r
-             &EndPoint,\r
-             NULL,\r
-             Ikev2OnPacketSent,\r
-             (VOID*)IkePacket\r
-             );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "Error send packet with %r\n", Status));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r