/** @file | |
Common operation of the IKE | |
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> | |
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; | |
EFI_GUID mZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; | |
/** | |
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); | |
} | |
/** | |
Find SPD entry by a specified SPD selector. | |
@param[in] SpdSel Point to SPD Selector to be searched for. | |
@retval Point to SPD Entry if the SPD entry found. | |
@retval NULL if not found. | |
**/ | |
IPSEC_SPD_ENTRY * | |
IkeSearchSpdEntry ( | |
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); | |
// | |
// Find the required SPD entry | |
// | |
if (CompareSpdSelector ( | |
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSel, | |
(EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector | |
)) { | |
return SpdEntry; | |
} | |
} | |
return NULL; | |
} | |
/** | |
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; | |
} | |
} | |