IkeCommon.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/** @file
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Common operation of the IKE
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg This program and the accompanying materials
d0538f66491267879b7418b21ad78e3dcc2dcc83cg are licensed and made available under the terms and conditions of the BSD License
d0538f66491267879b7418b21ad78e3dcc2dcc83cg which accompanies this distribution. The full text of the license may be found at
d0538f66491267879b7418b21ad78e3dcc2dcc83cg http://opensource.org/licenses/bsd-license.php.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "Ike.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "IkeCommon.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "IpSecConfigImpl.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "IpSecDebug.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg//
d0538f66491267879b7418b21ad78e3dcc2dcc83cg// Initial the SPI
d0538f66491267879b7418b21ad78e3dcc2dcc83cg//
d0538f66491267879b7418b21ad78e3dcc2dcc83cgUINT32 mNextSpi = IKE_SPI_BASE;
d0538f66491267879b7418b21ad78e3dcc2dcc83cgEFI_GUID mZeroGuid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Call Crypto Lib to generate a random value with eight-octet length.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @return the 64 byte vaule.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgUINT64
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeGenerateCookie (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg VOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg UINT64 Cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg EFI_STATUS Status;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)&Cookie, sizeof (UINT64));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (EFI_ERROR (Status)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return 0;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return Cookie;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Generate the random data for Nonce payload.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in] NonceSize Size of the data in bytes.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @return Buffer which contains the random data of the spcified size.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgUINT8 *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeGenerateNonce (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN UINTN NonceSize
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg UINT8 *Nonce;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg EFI_STATUS Status;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Nonce = AllocateZeroPool (NonceSize);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (Nonce == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Status = IpSecCryptoIoGenerateRandomBytes (Nonce, NonceSize);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (EFI_ERROR (Status)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg FreePool (Nonce);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return Nonce;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Convert the IKE Header from Network order to Host order.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in, out] Header The pointer of the IKE_HEADER.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgVOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeHdrNetToHost (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN OUT IKE_HEADER *Header
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->InitiatorCookie = NTOHLL (Header->InitiatorCookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->ResponderCookie = NTOHLL (Header->ResponderCookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->MessageId = NTOHL (Header->MessageId);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->Length = NTOHL (Header->Length);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Convert the IKE Header from Host order to Network order.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in, out] Header The pointer of the IKE_HEADER.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgVOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeHdrHostToNet (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN OUT IKE_HEADER *Header
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->InitiatorCookie = HTONLL (Header->InitiatorCookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->ResponderCookie = HTONLL (Header->ResponderCookie);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->MessageId = HTONL (Header->MessageId);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Header->Length = HTONL (Header->Length);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Allocate a buffer of IKE_PAYLOAD and set its Signature.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @return A buffer of IKE_PAYLOAD.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIKE_PAYLOAD *
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkePayloadAlloc (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg VOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IKE_PAYLOAD *IkePayload;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IkePayload = (IKE_PAYLOAD *) AllocateZeroPool (sizeof (IKE_PAYLOAD));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (IkePayload == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return NULL;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IkePayload->Signature = IKE_PAYLOAD_SIGNATURE;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return IkePayload;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Free a specified IKE_PAYLOAD buffer.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in] IkePayload Pointer of IKE_PAYLOAD to be freed.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgVOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkePayloadFree (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN IKE_PAYLOAD *IkePayload
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (IkePayload == NULL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg //
d0538f66491267879b7418b21ad78e3dcc2dcc83cg // If this IkePayload is not referred by others, free it.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg //
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (!IkePayload->IsPayloadBufExt && (IkePayload->PayloadBuf != NULL)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg FreePool (IkePayload->PayloadBuf);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg FreePool (IkePayload);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Generate an new SPI.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @return a SPI in 4 bytes.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgUINT32
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeGenerateSpi (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg VOID
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg //
d0538f66491267879b7418b21ad78e3dcc2dcc83cg // TODO: should generate SPI randomly to avoid security issue
d0538f66491267879b7418b21ad78e3dcc2dcc83cg //
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return mNextSpi++;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Generate a random data for IV
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in] IvBuffer The pointer of the IV buffer.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in] IvSize The IV size.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @retval EFI_SUCCESS Create a random data for IV.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @retval otherwise Failed.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg**/
d0538f66491267879b7418b21ad78e3dcc2dcc83cgEFI_STATUS
d0538f66491267879b7418b21ad78e3dcc2dcc83cgIkeGenerateIv (
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN UINT8 *IvBuffer,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IN UINTN IvSize
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
12db04d32e66c3b1803eed1182611245893e23ddmiao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg/**
d0538f66491267879b7418b21ad78e3dcc2dcc83cg Find SPD entry by a specified SPD selector.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg @param[in] SpdSel Point to SPD Selector to be searched for.
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
dc8c6b69817035ac35a9f4e5a835d114ce2b5e24ms @retval Point to SPD Entry if the SPD entry found.
dc8c6b69817035ac35a9f4e5a835d114ce2b5e24ms @retval NULL if not found.
dc8c6b69817035ac35a9f4e5a835d114ce2b5e24ms
fc6df3bdbec9a23827d64460d15c987a4497ef35miao chen - Sun Microsystems - Beijing China**/
fc6df3bdbec9a23827d64460d15c987a4497ef35miao chen - Sun Microsystems - Beijing ChinaIPSEC_SPD_ENTRY *
fc6df3bdbec9a23827d64460d15c987a4497ef35miao chen - Sun Microsystems - Beijing ChinaIkeSearchSpdEntry (
fc6df3bdbec9a23827d64460d15c987a4497ef35miao chen - Sun Microsystems - Beijing China IN EFI_IPSEC_SPD_SELECTOR *SpdSel
d0538f66491267879b7418b21ad78e3dcc2dcc83cg )
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg IPSEC_SPD_ENTRY *SpdEntry;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg LIST_ENTRY *SpdList;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg LIST_ENTRY *Entry;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg 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;
}
}