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