| /** @file
|
| Common operation of the IKE
|
|
|
| Copyright (c) 2010, 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;
|
| }
|
| }
|
|
|