2010-12-31 11:43:54 +01:00
|
|
|
/** @file
|
|
|
|
Common operation of the IKE
|
|
|
|
|
2012-10-11 04:15:23 +02:00
|
|
|
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
2010-12-31 11:43:54 +01:00
|
|
|
|
|
|
|
This program and the accompanying materials
|
|
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include "Ike.h"
|
|
|
|
#include "IkeCommon.h"
|
|
|
|
#include "IpSecConfigImpl.h"
|
|
|
|
#include "IpSecDebug.h"
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initial the SPI
|
|
|
|
//
|
|
|
|
UINT32 mNextSpi = IKE_SPI_BASE;
|
2012-10-11 04:15:23 +02:00
|
|
|
EFI_GUID mZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
|
2010-12-31 11:43:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
Call Crypto Lib to generate a random value with eight-octet length.
|
|
|
|
|
|
|
|
@return the 64 byte vaule.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
IkeGenerateCookie (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Cookie;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)&Cookie, sizeof (UINT64));
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return Cookie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generate the random data for Nonce payload.
|
|
|
|
|
|
|
|
@param[in] NonceSize Size of the data in bytes.
|
|
|
|
|
|
|
|
@return Buffer which contains the random data of the spcified size.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8 *
|
|
|
|
IkeGenerateNonce (
|
|
|
|
IN UINTN NonceSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT8 *Nonce;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Nonce = AllocateZeroPool (NonceSize);
|
|
|
|
if (Nonce == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = IpSecCryptoIoGenerateRandomBytes (Nonce, NonceSize);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
FreePool (Nonce);
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
return Nonce;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert the IKE Header from Network order to Host order.
|
|
|
|
|
|
|
|
@param[in, out] Header The pointer of the IKE_HEADER.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
IkeHdrNetToHost (
|
|
|
|
IN OUT IKE_HEADER *Header
|
|
|
|
)
|
|
|
|
{
|
|
|
|
Header->InitiatorCookie = NTOHLL (Header->InitiatorCookie);
|
|
|
|
Header->ResponderCookie = NTOHLL (Header->ResponderCookie);
|
|
|
|
Header->MessageId = NTOHL (Header->MessageId);
|
|
|
|
Header->Length = NTOHL (Header->Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert the IKE Header from Host order to Network order.
|
|
|
|
|
|
|
|
@param[in, out] Header The pointer of the IKE_HEADER.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
IkeHdrHostToNet (
|
|
|
|
IN OUT IKE_HEADER *Header
|
|
|
|
)
|
|
|
|
{
|
|
|
|
Header->InitiatorCookie = HTONLL (Header->InitiatorCookie);
|
|
|
|
Header->ResponderCookie = HTONLL (Header->ResponderCookie);
|
|
|
|
Header->MessageId = HTONL (Header->MessageId);
|
|
|
|
Header->Length = HTONL (Header->Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Allocate a buffer of IKE_PAYLOAD and set its Signature.
|
|
|
|
|
|
|
|
@return A buffer of IKE_PAYLOAD.
|
|
|
|
|
|
|
|
**/
|
|
|
|
IKE_PAYLOAD *
|
|
|
|
IkePayloadAlloc (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
IKE_PAYLOAD *IkePayload;
|
|
|
|
|
|
|
|
IkePayload = (IKE_PAYLOAD *) AllocateZeroPool (sizeof (IKE_PAYLOAD));
|
|
|
|
if (IkePayload == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
IkePayload->Signature = IKE_PAYLOAD_SIGNATURE;
|
|
|
|
|
|
|
|
return IkePayload;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Free a specified IKE_PAYLOAD buffer.
|
|
|
|
|
|
|
|
@param[in] IkePayload Pointer of IKE_PAYLOAD to be freed.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
IkePayloadFree (
|
|
|
|
IN IKE_PAYLOAD *IkePayload
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (IkePayload == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// If this IkePayload is not referred by others, free it.
|
|
|
|
//
|
|
|
|
if (!IkePayload->IsPayloadBufExt && (IkePayload->PayloadBuf != NULL)) {
|
|
|
|
FreePool (IkePayload->PayloadBuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreePool (IkePayload);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generate an new SPI.
|
|
|
|
|
|
|
|
@return a SPI in 4 bytes.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT32
|
|
|
|
IkeGenerateSpi (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// TODO: should generate SPI randomly to avoid security issue
|
|
|
|
//
|
|
|
|
return mNextSpi++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generate a random data for IV
|
|
|
|
|
|
|
|
@param[in] IvBuffer The pointer of the IV buffer.
|
|
|
|
@param[in] IvSize The IV size.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Create a random data for IV.
|
|
|
|
@retval otherwise Failed.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
IkeGenerateIv (
|
|
|
|
IN UINT8 *IvBuffer,
|
|
|
|
IN UINTN IvSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-22 09:39:32 +01:00
|
|
|
/**
|
|
|
|
Find SPD entry by a specified SPD selector.
|
|
|
|
|
2010-12-31 11:43:54 +01:00
|
|
|
@param[in] SpdSel Point to SPD Selector to be searched for.
|
2014-01-22 09:39:32 +01:00
|
|
|
|
2010-12-31 11:43:54 +01:00
|
|
|
@retval Point to SPD Entry if the SPD entry found.
|
2014-01-22 09:39:32 +01:00
|
|
|
@retval NULL if not found.
|
|
|
|
|
|
|
|
**/
|
|
|
|
IPSEC_SPD_ENTRY *
|
2010-12-31 11:43:54 +01:00
|
|
|
IkeSearchSpdEntry (
|
2014-01-22 09:39:32 +01:00
|
|
|
IN EFI_IPSEC_SPD_SELECTOR *SpdSel
|
|
|
|
)
|
|
|
|
{
|
|
|
|
IPSEC_SPD_ENTRY *SpdEntry;
|
|
|
|
LIST_ENTRY *SpdList;
|
|
|
|
LIST_ENTRY *Entry;
|
|
|
|
|
|
|
|
SpdList = &mConfigData[IPsecConfigDataTypeSpd];
|
|
|
|
|
|
|
|
NET_LIST_FOR_EACH (Entry, SpdList) {
|
|
|
|
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
|
|
|
|
|
|
|
|
//
|
2010-12-31 11:43:54 +01:00
|
|
|
// Find the required SPD entry
|
2014-01-22 09:39:32 +01:00
|
|
|
//
|
|
|
|
if (CompareSpdSelector (
|
|
|
|
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
|
|
|
|
(EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
|
|
|
|
)) {
|
|
|
|
return SpdEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2010-12-31 11:43:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Get the IKE Version from the IKE_SA_SESSION.
|
|
|
|
|
|
|
|
@param[in] Session Pointer of the IKE_SA_SESSION.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8
|
|
|
|
IkeGetVersionFromSession (
|
|
|
|
IN UINT8 *Session
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (*(UINT32 *) Session == IKEV2_SA_SESSION_SIGNATURE) {
|
|
|
|
return ((IKEV2_SA_SESSION *) Session)->SessionCommon.IkeVer;
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Add IKEv1 support here.
|
|
|
|
//
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|