]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IkeCommon.c
Add IPsec/Ikev2 support.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeCommon.c
diff --git a/NetworkPkg/IpSecDxe/IkeCommon.c b/NetworkPkg/IpSecDxe/IkeCommon.c
new file mode 100644 (file)
index 0000000..7f56365
--- /dev/null
@@ -0,0 +1,255 @@
+/** @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