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